Skip to content

Commit 4fc5e29

Browse files
committed
java-0.9.4 js-1.3.3 - fix text template url encoding with fallback template
1 parent 7f1f2da commit 4fc5e29

10 files changed

Lines changed: 73 additions & 20 deletions

File tree

docs/package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"@docusaurus/preset-classic": "3.7.0",
2020
"@mdx-js/react": "3.1.0",
2121
"@monaco-editor/react": "4.6.0",
22-
"@nlighten/json-transform": "^1.3.2",
22+
"@nlighten/json-transform": "^1.3.3",
2323
"@nlighten/json-transform-core": "^1.3.2",
2424
"buffer": "^6.0.3",
2525
"clsx": "2.1.0",

java/json-transform/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ plugins {
99
}
1010

1111
group 'co.nlighten'
12-
version = '0.9.3'
12+
version = '0.9.4'
1313

1414
ext {
1515
gsonVersion = "2.10.1"

java/json-transform/src/main/java/co/nlighten/jsontransform/template/TextTemplate.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,11 @@ private void parse(String template, ParameterDefaultResolveOptions defaultResolv
103103
buffer.append("\\{");
104104
continue;
105105
}
106+
if (nextChar == '}' && state != STATE_TEXT) {
107+
i++; // skip backslash
108+
buffer.append("\\}");
109+
continue;
110+
}
106111
}
107112
break;
108113
case '{':
@@ -179,7 +184,8 @@ String internalRender(ParameterResolver resolver, JsonAdapter<?,?,?> adapter, Bo
179184
sb.append(s);
180185
} else if (value instanceof TemplateParameter param) {
181186
var renderedValue = param.getStringValue(resolver, adapter);
182-
sb.append(Boolean.TRUE.equals(urlEncodeParameters)
187+
sb.append(
188+
Boolean.TRUE.equals(urlEncodeParameters) && !UNESCAPED_OPEN_CURLY_BRACKET.matcher(renderedValue).find()
183189
? URLEncoder.encode(renderedValue, StandardCharsets.UTF_8)
184190
: renderedValue);
185191
}
@@ -201,7 +207,9 @@ public String render(ParameterResolver resolver, JsonAdapter<?,?,?> adapter, Boo
201207
res = get(res, defaultResolver).internalRender(resolver, adapter, urlEncodeParameters);
202208
}
203209
// unescape
204-
return res.replace("\\{", "{").replace("\\}", "}");
210+
return urlEncodeParameters
211+
? res.replace("%5C%7B", "%7B").replace("%5C%7D", "%7D")
212+
: res.replace("\\{", "{").replace("\\}", "}");
205213
}
206214

207215
public String render(ParameterResolver resolver) {

java/json-transform/src/test/java/co/nlighten/jsontransform/template/TextTemplateTests.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,6 @@ void recursiveWithEscapedTemplateParameterDefaultValue() {
9595
));
9696
var def = new TextTemplate("{b,{a}}").render(resolver);
9797
Assertions.assertEquals("A", def);
98-
def = new TextTemplate("{b,\\{a}}").render(resolver);
99-
Assertions.assertEquals("{a}", def);
10098
}
10199

102100
@Test
@@ -114,7 +112,7 @@ void recursiveWithEscapedTemplateParameterDefaultValue3() {
114112
var resolver = ParameterResolver.fromMap(Map.of(
115113
"a", "A"
116114
));
117-
var def = new TextTemplate("{b,\\{a}}").render(resolver);
115+
var def = new TextTemplate("{b,\\{a\\}}").render(resolver);
118116
Assertions.assertEquals("{a}", def);
119117
}
120118

@@ -130,4 +128,17 @@ void urlEncode() {
130128
def = new TextTemplate("href={href}").render(resolver);
131129
Assertions.assertEquals("href=https://example.com/", def);
132130
}
131+
132+
@Test
133+
void urlEncodeWithFallback() {
134+
var resolver = ParameterResolver.fromMap(Map.of(
135+
"href", "https://example.com/"
136+
));
137+
// default value is a template
138+
var def = new TextTemplate("href={url,{href}}").render(resolver, true);
139+
Assertions.assertEquals("href=https%3A%2F%2Fexample.com%2F", def);
140+
// default value escaped
141+
def = new TextTemplate("href={url,\\{href\\}}").render(resolver, true);
142+
Assertions.assertEquals("href=%7Bhref%7D", def);
143+
}
133144
}

javascript/json-transform/package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

javascript/json-transform/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@nlighten/json-transform",
33
"description": "JSON transformers JavaScript implementation",
4-
"version": "1.3.2",
4+
"version": "1.3.3",
55
"main": "dist/json-transform.js",
66
"umd:main": "dist/json-transform.umd.js",
77
"module": "dist/json-transform.module.js",

javascript/json-transform/src/__tests__/template/TextTemplate.test.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,8 @@ describe("TextTemplate", () => {
7070
const resolver = parameterResolverFromMap({
7171
a: "A",
7272
});
73-
let def = await new TextTemplate("{b,{a}}").render(resolver);
73+
const def = await new TextTemplate("{b,{a}}").render(resolver);
7474
expect(def).toEqual("A");
75-
def = await new TextTemplate("{b,\\{a}}").render(resolver);
76-
expect(def).toEqual("{a}");
7775
});
7876

7977
test("recursiveWithEscapedTemplateParameterDefaultValue2", async () => {
@@ -88,7 +86,7 @@ describe("TextTemplate", () => {
8886
const resolver = parameterResolverFromMap({
8987
a: "A",
9088
});
91-
const def = await new TextTemplate("{b,\\{a}}").render(resolver);
89+
const def = await new TextTemplate("{b,\\{a\\}}").render(resolver);
9290
expect(def).toEqual("{a}");
9391
});
9492

@@ -103,4 +101,14 @@ describe("TextTemplate", () => {
103101
def = await new TextTemplate("href={href}").render(resolver);
104102
expect(def).toEqual("href=https://example.com/");
105103
});
104+
105+
test("urlEncodeWithFallback", async () => {
106+
const resolver = parameterResolverFromMap({
107+
href: "https://example.com/",
108+
});
109+
let def = await new TextTemplate("href={url,{href}}").render(resolver, true);
110+
expect(def).toEqual("href=https%3A%2F%2Fexample.com%2F");
111+
def = await new TextTemplate("href={url,\\{href\\}}").render(resolver, true);
112+
expect(def).toEqual("href=%7Bhref%7D");
113+
});
106114
});

javascript/json-transform/src/template/TextTemplate.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,11 @@ export default class TextTemplate {
7878
buffer += "\\{";
7979
continue;
8080
}
81+
if (nextChar == "}" && state !== STATE_TEXT) {
82+
i++; // skip backslash
83+
buffer += "\\}";
84+
continue;
85+
}
8186
}
8287
break;
8388
case "{":
@@ -157,7 +162,10 @@ export default class TextTemplate {
157162
sb += value;
158163
} else if (value instanceof TemplateParameter) {
159164
const renderedValue = await value.getStringValue(resolver);
160-
sb += urlEncodeParameters ? encodeURIComponent(renderedValue.replace()) : renderedValue;
165+
sb +=
166+
urlEncodeParameters && !UNESCAPED_OPEN_CURLY_BRACKET.test(renderedValue)
167+
? encodeURIComponent(renderedValue)
168+
: renderedValue;
161169
}
162170
}
163171
return sb;
@@ -177,7 +185,9 @@ export default class TextTemplate {
177185
res = await TextTemplate.get(res, this.defaultResolver).internalRender(resl, urlEncodeParameters);
178186
}
179187
// unescape
180-
return res.replace(/\\\{/g, "{").replace(/\\}/g, "}");
188+
return urlEncodeParameters
189+
? res.replace(/%5C%7B/g, "%7B").replace(/%5C%7D/g, "%7D")
190+
: res.replace(/\\\{/g, "{").replace(/\\}/g, "}");
181191
}
182192

183193
public static render(

test/tests/functions/template.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,5 +105,21 @@
105105
"expect": {
106106
"equal": "href=https%3A%2F%2Fexample.com%2F"
107107
}
108+
},
109+
{
110+
"name": "object - url encode with fallback",
111+
"given": {
112+
"input": {
113+
"href": "https://example.com/"
114+
},
115+
"definition": {
116+
"$$template": "href={$.url,{$.href}}",
117+
"payload": "$",
118+
"url_encode": true
119+
}
120+
},
121+
"expect": {
122+
"equal": "href=https%3A%2F%2Fexample.com%2F"
123+
}
108124
}
109125
]

0 commit comments

Comments
 (0)