Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions docs/string-functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -293,3 +293,39 @@ Converts base 64 encoded bytes to a string, using a UTF-8 Unicode codepage.
__Examples__

- `$base64decode("bXl1c2VyOm15cGFzcw==")` => `"myuser:mypass"`

## `$encodeUrlComponent()`
__Signature:__ `$encodeUrlComponent(str)`

Encodes a Uniform Resource Locator (URL) component by replacing each instance of certain characters by one, two, three, or four escape sequences representing the UTF-8 encoding of the character.

__Examples__

- `$encodeUrlComponent("?x=test")` => `"%3Fx%3Dtest"`

## `$encodeUrl()`
__Signature:__ `$encodeUrl(str)`

Encodes a Uniform Resource Locator (URL) by replacing each instance of certain characters by one, two, three, or four escape sequences representing the UTF-8 encoding of the character.

__Examples__

- `$encodeUrl("https://mozilla.org/?x=шеллы")` => `"https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B"`

## `$decodeUrlComponent()`
__Signature:__ `$decodeUrlComponent(str)`

Decodes a Uniform Resource Locator (URL) component previously created by encodeUrlComponent.

__Examples__

- `$decodeUrlComponent("%3Fx%3Dtest")` => `"?x=test"`

## `$decodeUrl()`
__Signature:__ `$decodeUrl(str)`

Decodes a Uniform Resource Locator (URL) previously created by encodeUrl.

__Examples__

- `$decodeUrl("https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B")` => `"https://mozilla.org/?x=шеллы"`
106 changes: 105 additions & 1 deletion src/functions.js
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,110 @@ const functions = (() => {
return atob(str);
}

/**
* Encode a string into a component for a url
* @param {String} str - String to encode
* @returns {string} Encoded string
*/
function encodeUrlComponent(str) {
// undefined inputs always return undefined
if (typeof str === 'undefined') {
return undefined;
}

// Catch URIErrors when URI sequence is malformed
var returnVal;
try {
returnVal = encodeURIComponent(str);
} catch (e) {
throw {
code: "D3140",
stack: (new Error()).stack,
value: str,
functionName: "encodeUrlComponent"
};
}
return returnVal;
}

/**
* Encode a string into a url
* @param {String} str - String to encode
* @returns {string} Encoded string
*/
function encodeUrl(str) {
// undefined inputs always return undefined
if (typeof str === 'undefined') {
return undefined;
}

// Catch URIErrors when URI sequence is malformed
var returnVal;
try {
returnVal = encodeURI(str);
} catch (e) {
throw {
code: "D3140",
stack: (new Error()).stack,
value: str,
functionName: "encodeUrl"
};
}
return returnVal;
}

/**
* Decode a string from a component for a url
* @param {String} str - String to decode
* @returns {string} Decoded string
*/
function decodeUrlComponent(str) {
// undefined inputs always return undefined
if (typeof str === 'undefined') {
return undefined;
}

// Catch URIErrors when URI sequence is malformed
var returnVal;
try {
returnVal = decodeURIComponent(str);
} catch (e) {
throw {
code: "D3140",
stack: (new Error()).stack,
value: str,
functionName: "decodeUrlComponent"
};
}
return returnVal;
}

/**
* Decode a string from a url
* @param {String} str - String to decode
* @returns {string} Decoded string
*/
function decodeUrl(str) {
// undefined inputs always return undefined
if (typeof str === 'undefined') {
return undefined;
}

// Catch URIErrors when URI sequence is malformed
var returnVal;
try {
returnVal = decodeURI(str);
} catch (e) {
throw {
code: "D3140",
stack: (new Error()).stack,
value: str,
functionName: "decodeUrl"
};
}
return returnVal;
}

/**
* Split a string into an array of substrings
* @param {String} str - string
Expand Down Expand Up @@ -1844,7 +1948,7 @@ const functions = (() => {
boolean, not,
map, zip, filter, single, foldLeft, sift,
keys, lookup, append, exists, spread, merge, reverse, each, error, sort, shuffle,
base64encode, base64decode
base64encode, base64decode, encodeUrlComponent, encodeUrl, decodeUrlComponent, decodeUrl
};
})();

Expand Down
7 changes: 6 additions & 1 deletion src/jsonata.js
Original file line number Diff line number Diff line change
Expand Up @@ -1705,6 +1705,10 @@ var jsonata = (function() {
staticFrame.bind('shuffle', defineFunction(fn.shuffle, '<a:a>'));
staticFrame.bind('base64encode', defineFunction(fn.base64encode, '<s-:s>'));
staticFrame.bind('base64decode', defineFunction(fn.base64decode, '<s-:s>'));
staticFrame.bind('encodeUrlComponent', defineFunction(fn.encodeUrlComponent, '<s-:s>'));
staticFrame.bind('encodeUrl', defineFunction(fn.encodeUrl, '<s-:s>'));
staticFrame.bind('decodeUrlComponent', defineFunction(fn.decodeUrlComponent, '<s-:s>'));
staticFrame.bind('decodeUrl', defineFunction(fn.decodeUrl, '<s-:s>'));
staticFrame.bind('eval', defineFunction(functionEval, '<sx?:x>'));
staticFrame.bind('toMillis', defineFunction(datetime.toMillis, '<s-s?:n>'));
staticFrame.bind('fromMillis', defineFunction(datetime.fromMillis, '<n-s?s?:s>'));
Expand Down Expand Up @@ -1814,7 +1818,8 @@ var jsonata = (function() {
"D3136": "The date/time picture string is missing specifiers required to parse the timestamp",
"D3137": "{{{message}}}",
"D3138": "The $single() function expected exactly 1 matching result. Instead it matched more.",
"D3139": "The $single() function expected exactly 1 matching result. Instead it matched 0."
"D3139": "The $single() function expected exactly 1 matching result. Instead it matched 0.",
"D3140": "Malformed URL passed to ${{{functionName}}}(): {{value}}"
};

/**
Expand Down
6 changes: 6 additions & 0 deletions test/test-suite/groups/function-decodeUrl/case000.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"expr": "$decodeUrl(\"https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B\")",
"dataset": "dataset5",
"bindings": {},
"result": "https://mozilla.org/?x=шеллы"
}
6 changes: 6 additions & 0 deletions test/test-suite/groups/function-decodeUrl/case001.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"expr": "$decodeUrl(blah)",
"dataset": "dataset5",
"bindings": {},
"undefinedResult": true
}
9 changes: 9 additions & 0 deletions test/test-suite/groups/function-decodeUrl/case002.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"expr": "$decodeUrl('%E0%A4%A')",
"dataset": "dataset5",
"bindings": {},
"error": {
"code": "D3140",
"message": "Malformed URL passed to $decodeUrl(): \"%E0%A4%A\""
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"expr": "$decodeUrlComponent(\"%3Fx%3Dtest\")",
"dataset": "dataset5",
"bindings": {},
"result": "?x=test"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"expr": "$decodeUrlComponent(blah)",
"dataset": "dataset5",
"bindings": {},
"undefinedResult": true
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"expr": "$decodeUrlComponent('%E0%A4%A')",
"dataset": "dataset5",
"bindings": {},
"error": {
"code": "D3140",
"message": "Malformed URL passed to $decodeUrlComponent(): \"%E0%A4%A\""
}
}
6 changes: 6 additions & 0 deletions test/test-suite/groups/function-encodeUrl/case000.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"expr": "$encodeUrl(\"https://mozilla.org/?x=шеллы\")",
"dataset": "dataset5",
"bindings": {},
"result": "https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B"
}
6 changes: 6 additions & 0 deletions test/test-suite/groups/function-encodeUrl/case001.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"expr": "$encodeUrl(blah)",
"dataset": "dataset5",
"bindings": {},
"undefinedResult": true
}
9 changes: 9 additions & 0 deletions test/test-suite/groups/function-encodeUrl/case002.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"expr": "$encodeUrl('\uD800')",
"dataset": "dataset5",
"bindings": {},
"error": {
"code": "D3140",
"message": "Malformed URL passed to $encodeUrl(): \"\uD800\""
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"expr": "$encodeUrlComponent(\"?x=test\")",
"dataset": "dataset5",
"bindings": {},
"result": "%3Fx%3Dtest"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"expr": "$encodeUrlComponent(blah)",
"dataset": "dataset5",
"bindings": {},
"undefinedResult": true
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"expr": "$encodeUrlComponent('\uD800')",
"dataset": "dataset5",
"bindings": {},
"error": {
"code": "D3140",
"message": "Malformed URL passed to $encodeUrlComponent(): \"\uD800\""
}
}