@swagger-api/apidom-json-pointer 1.0.0-beta.1 → 1.0.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,16 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [1.0.0-beta.3](https://github.com/swagger-api/apidom/compare/v1.0.0-beta.2...v1.0.0-beta.3) (2024-11-25)
7
+
8
+ **Note:** Version bump only for package @swagger-api/apidom-json-pointer
9
+
10
+ # [1.0.0-beta.2](https://github.com/swagger-api/apidom/compare/v1.0.0-beta.1...v1.0.0-beta.2) (2024-11-22)
11
+
12
+ ### Bug Fixes
13
+
14
+ - **json-pointer:** fix non existing package entry point ([#4549](https://github.com/swagger-api/apidom/issues/4549)) ([764a1c5](https://github.com/swagger-api/apidom/commit/764a1c5bdf7c5300b878b5eadccab00faef84d1a)), closes [#4539](https://github.com/swagger-api/apidom/issues/4539)
15
+
6
16
  # [1.0.0-beta.1](https://github.com/swagger-api/apidom/compare/v1.0.0-beta.0...v1.0.0-beta.1) (2024-11-22)
7
17
 
8
18
  **Note:** Version bump only for package @swagger-api/apidom-json-pointer
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@swagger-api/apidom-json-pointer",
3
- "version": "1.0.0-beta.1",
3
+ "version": "1.0.0-beta.3",
4
4
  "description": "Evaluate JSON Pointer expressions against ApiDOM.",
5
5
  "publishConfig": {
6
6
  "access": "public",
@@ -38,21 +38,21 @@
38
38
  "license": "Apache-2.0",
39
39
  "dependencies": {
40
40
  "@babel/runtime-corejs3": "^7.20.7",
41
- "@swagger-api/apidom-core": "^1.0.0-beta.1",
42
- "@swagger-api/apidom-error": "^1.0.0-beta.1",
41
+ "@swagger-api/apidom-core": "^1.0.0-beta.3",
42
+ "@swagger-api/apidom-error": "^1.0.0-beta.3",
43
43
  "@types/ramda": "~0.30.0",
44
44
  "ramda": "~0.30.0",
45
45
  "ramda-adjunct": "^5.0.0"
46
46
  },
47
47
  "files": [
48
- "cjs/",
48
+ "src/**/*.mjs",
49
+ "src/**/*.cjs",
49
50
  "dist/",
50
- "es/",
51
51
  "types/apidom-json-pointer.d.ts",
52
52
  "LICENSES",
53
53
  "NOTICE",
54
54
  "README.md",
55
55
  "CHANGELOG.md"
56
56
  ],
57
- "gitHead": "605eed17c44883c182280c2297c9f6e46d639eec"
57
+ "gitHead": "a0cf66f3e4520986db154bd2b97001715a8a3287"
58
58
  }
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault").default;
4
+ exports.__esModule = true;
5
+ exports.default = void 0;
6
+ var _escape = _interopRequireDefault(require("./escape.cjs"));
7
+ var _CompilationJsonPointerError = _interopRequireDefault(require("./errors/CompilationJsonPointerError.cjs"));
8
+ /**
9
+ * @public
10
+ */
11
+ const compile = tokens => {
12
+ try {
13
+ if (tokens.length === 0) {
14
+ return '';
15
+ }
16
+ return `/${tokens.map(_escape.default).join('/')}`;
17
+ } catch (error) {
18
+ throw new _CompilationJsonPointerError.default('JSON Pointer compilation of tokens encountered an error.', {
19
+ tokens,
20
+ cause: error
21
+ });
22
+ }
23
+ };
24
+ var _default = exports.default = compile;
@@ -0,0 +1,19 @@
1
+ import escape from "./escape.mjs";
2
+ import CompilationJsonPointerError from "./errors/CompilationJsonPointerError.mjs";
3
+ /**
4
+ * @public
5
+ */
6
+ const compile = tokens => {
7
+ try {
8
+ if (tokens.length === 0) {
9
+ return '';
10
+ }
11
+ return `/${tokens.map(escape).join('/')}`;
12
+ } catch (error) {
13
+ throw new CompilationJsonPointerError('JSON Pointer compilation of tokens encountered an error.', {
14
+ tokens,
15
+ cause: error
16
+ });
17
+ }
18
+ };
19
+ export default compile;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault").default;
4
+ exports.__esModule = true;
5
+ exports.default = void 0;
6
+ var _JsonPointerError = _interopRequireDefault(require("./JsonPointerError.cjs"));
7
+ /**
8
+ * @public
9
+ */
10
+
11
+ /**
12
+ * @public
13
+ */
14
+ class CompilationJsonPointerError extends _JsonPointerError.default {
15
+ tokens;
16
+ constructor(message, structuredOptions) {
17
+ super(message, structuredOptions);
18
+ if (typeof structuredOptions !== 'undefined') {
19
+ this.tokens = [...structuredOptions.tokens];
20
+ }
21
+ }
22
+ }
23
+ var _default = exports.default = CompilationJsonPointerError;
@@ -0,0 +1,17 @@
1
+ import JsonPointerError from "./JsonPointerError.mjs";
2
+ /**
3
+ * @public
4
+ */
5
+ /**
6
+ * @public
7
+ */
8
+ class CompilationJsonPointerError extends JsonPointerError {
9
+ tokens;
10
+ constructor(message, structuredOptions) {
11
+ super(message, structuredOptions);
12
+ if (typeof structuredOptions !== 'undefined') {
13
+ this.tokens = [...structuredOptions.tokens];
14
+ }
15
+ }
16
+ }
17
+ export default CompilationJsonPointerError;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault").default;
4
+ exports.__esModule = true;
5
+ exports.default = void 0;
6
+ var _JsonPointerError = _interopRequireDefault(require("./JsonPointerError.cjs"));
7
+ /**
8
+ * @public
9
+ */
10
+
11
+ /**
12
+ * @public
13
+ */
14
+ class EvaluationJsonPointerError extends _JsonPointerError.default {
15
+ pointer;
16
+ tokens;
17
+ failedToken;
18
+ failedTokenPosition;
19
+ element;
20
+ constructor(message, structuredOptions) {
21
+ super(message, structuredOptions);
22
+ if (typeof structuredOptions !== 'undefined') {
23
+ this.pointer = structuredOptions.pointer;
24
+ if (Array.isArray(structuredOptions.tokens)) {
25
+ this.tokens = [...structuredOptions.tokens];
26
+ }
27
+ this.failedToken = structuredOptions.failedToken;
28
+ this.failedTokenPosition = structuredOptions.failedTokenPosition;
29
+ this.element = structuredOptions.element;
30
+ }
31
+ }
32
+ }
33
+ var _default = exports.default = EvaluationJsonPointerError;
@@ -0,0 +1,27 @@
1
+ import JsonPointerError from "./JsonPointerError.mjs";
2
+ /**
3
+ * @public
4
+ */
5
+ /**
6
+ * @public
7
+ */
8
+ class EvaluationJsonPointerError extends JsonPointerError {
9
+ pointer;
10
+ tokens;
11
+ failedToken;
12
+ failedTokenPosition;
13
+ element;
14
+ constructor(message, structuredOptions) {
15
+ super(message, structuredOptions);
16
+ if (typeof structuredOptions !== 'undefined') {
17
+ this.pointer = structuredOptions.pointer;
18
+ if (Array.isArray(structuredOptions.tokens)) {
19
+ this.tokens = [...structuredOptions.tokens];
20
+ }
21
+ this.failedToken = structuredOptions.failedToken;
22
+ this.failedTokenPosition = structuredOptions.failedTokenPosition;
23
+ this.element = structuredOptions.element;
24
+ }
25
+ }
26
+ }
27
+ export default EvaluationJsonPointerError;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault").default;
4
+ exports.__esModule = true;
5
+ exports.default = void 0;
6
+ var _JsonPointerError = _interopRequireDefault(require("./JsonPointerError.cjs"));
7
+ /**
8
+ * @public
9
+ */
10
+
11
+ /**
12
+ * @public
13
+ */
14
+ class InvalidJsonPointerError extends _JsonPointerError.default {
15
+ pointer;
16
+ constructor(message, structuredOptions) {
17
+ super(message, structuredOptions);
18
+ if (typeof structuredOptions !== 'undefined') {
19
+ this.pointer = structuredOptions.pointer;
20
+ }
21
+ }
22
+ }
23
+ var _default = exports.default = InvalidJsonPointerError;
@@ -0,0 +1,17 @@
1
+ import JsonPointerError from "./JsonPointerError.mjs";
2
+ /**
3
+ * @public
4
+ */
5
+ /**
6
+ * @public
7
+ */
8
+ class InvalidJsonPointerError extends JsonPointerError {
9
+ pointer;
10
+ constructor(message, structuredOptions) {
11
+ super(message, structuredOptions);
12
+ if (typeof structuredOptions !== 'undefined') {
13
+ this.pointer = structuredOptions.pointer;
14
+ }
15
+ }
16
+ }
17
+ export default InvalidJsonPointerError;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.default = void 0;
5
+ var _apidomError = require("@swagger-api/apidom-error");
6
+ /**
7
+ * @public
8
+ */
9
+ class JsonPointerError extends _apidomError.ApiDOMStructuredError {}
10
+ var _default = exports.default = JsonPointerError;
@@ -0,0 +1,7 @@
1
+ import { ApiDOMStructuredError } from '@swagger-api/apidom-error';
2
+
3
+ /**
4
+ * @public
5
+ */
6
+ class JsonPointerError extends ApiDOMStructuredError {}
7
+ export default JsonPointerError;
package/src/escape.cjs ADDED
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.default = void 0;
5
+ var _ramda = require("ramda");
6
+ /**
7
+ * @public
8
+ */
9
+ const escape = (0, _ramda.pipe)((0, _ramda.replace)(/~/g, '~0'), (0, _ramda.replace)(/\//g, '~1'), encodeURIComponent);
10
+ var _default = exports.default = escape;
package/src/escape.mjs ADDED
@@ -0,0 +1,7 @@
1
+ import { pipe, replace } from 'ramda';
2
+
3
+ /**
4
+ * @public
5
+ */
6
+ const escape = pipe(replace(/~/g, '~0'), replace(/\//g, '~1'), encodeURIComponent);
7
+ export default escape;
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault").default;
4
+ exports.__esModule = true;
5
+ exports.default = void 0;
6
+ var _ramdaAdjunct = require("ramda-adjunct");
7
+ var _apidomCore = require("@swagger-api/apidom-core");
8
+ var _parse = _interopRequireDefault(require("./parse.cjs"));
9
+ var _EvaluationJsonPointerError = _interopRequireDefault(require("./errors/EvaluationJsonPointerError.cjs"));
10
+ /**
11
+ * Evaluates JSON Pointer against ApiDOM fragment.
12
+ * @public
13
+ */
14
+ const evaluate = (pointer, element) => {
15
+ let tokens;
16
+ try {
17
+ tokens = (0, _parse.default)(pointer);
18
+ } catch (error) {
19
+ throw new _EvaluationJsonPointerError.default(`JSON Pointer evaluation failed while parsing the pointer "${pointer}".`, {
20
+ pointer,
21
+ element: (0, _apidomCore.cloneDeep)(element),
22
+ cause: error
23
+ });
24
+ }
25
+ return tokens.reduce((acc, token, tokenPosition) => {
26
+ if ((0, _apidomCore.isObjectElement)(acc)) {
27
+ // @ts-ignore
28
+ if (!acc.hasKey(token)) {
29
+ throw new _EvaluationJsonPointerError.default(`JSON Pointer evaluation failed while evaluating token "${token}" against an ObjectElement`, {
30
+ pointer,
31
+ tokens,
32
+ failedToken: token,
33
+ failedTokenPosition: tokenPosition,
34
+ element: (0, _apidomCore.cloneDeep)(acc)
35
+ });
36
+ }
37
+ // @ts-ignore
38
+ return acc.get(token);
39
+ }
40
+ if ((0, _apidomCore.isArrayElement)(acc)) {
41
+ if (!(token in acc.content) || !(0, _ramdaAdjunct.isInteger)(Number(token))) {
42
+ throw new _EvaluationJsonPointerError.default(`JSON Pointer evaluation failed while evaluating token "${token}" against an ArrayElement`, {
43
+ pointer,
44
+ tokens,
45
+ failedToken: token,
46
+ failedTokenPosition: tokenPosition,
47
+ element: (0, _apidomCore.cloneDeep)(acc)
48
+ });
49
+ }
50
+ // @ts-ignore
51
+ return acc.get(Number(token));
52
+ }
53
+ throw new _EvaluationJsonPointerError.default(`JSON Pointer evaluation failed while evaluating token "${token}" against an unexpected Element`, {
54
+ pointer,
55
+ tokens,
56
+ failedToken: token,
57
+ failedTokenPosition: tokenPosition,
58
+ element: (0, _apidomCore.cloneDeep)(acc)
59
+ });
60
+ }, element);
61
+ };
62
+ var _default = exports.default = evaluate;
@@ -0,0 +1,57 @@
1
+ import { isInteger } from 'ramda-adjunct';
2
+ import { isObjectElement, isArrayElement, cloneDeep } from '@swagger-api/apidom-core';
3
+ import parse from "./parse.mjs";
4
+ import EvaluationJsonPointerError from "./errors/EvaluationJsonPointerError.mjs";
5
+ /**
6
+ * Evaluates JSON Pointer against ApiDOM fragment.
7
+ * @public
8
+ */
9
+ const evaluate = (pointer, element) => {
10
+ let tokens;
11
+ try {
12
+ tokens = parse(pointer);
13
+ } catch (error) {
14
+ throw new EvaluationJsonPointerError(`JSON Pointer evaluation failed while parsing the pointer "${pointer}".`, {
15
+ pointer,
16
+ element: cloneDeep(element),
17
+ cause: error
18
+ });
19
+ }
20
+ return tokens.reduce((acc, token, tokenPosition) => {
21
+ if (isObjectElement(acc)) {
22
+ // @ts-ignore
23
+ if (!acc.hasKey(token)) {
24
+ throw new EvaluationJsonPointerError(`JSON Pointer evaluation failed while evaluating token "${token}" against an ObjectElement`, {
25
+ pointer,
26
+ tokens,
27
+ failedToken: token,
28
+ failedTokenPosition: tokenPosition,
29
+ element: cloneDeep(acc)
30
+ });
31
+ }
32
+ // @ts-ignore
33
+ return acc.get(token);
34
+ }
35
+ if (isArrayElement(acc)) {
36
+ if (!(token in acc.content) || !isInteger(Number(token))) {
37
+ throw new EvaluationJsonPointerError(`JSON Pointer evaluation failed while evaluating token "${token}" against an ArrayElement`, {
38
+ pointer,
39
+ tokens,
40
+ failedToken: token,
41
+ failedTokenPosition: tokenPosition,
42
+ element: cloneDeep(acc)
43
+ });
44
+ }
45
+ // @ts-ignore
46
+ return acc.get(Number(token));
47
+ }
48
+ throw new EvaluationJsonPointerError(`JSON Pointer evaluation failed while evaluating token "${token}" against an unexpected Element`, {
49
+ pointer,
50
+ tokens,
51
+ failedToken: token,
52
+ failedTokenPosition: tokenPosition,
53
+ element: cloneDeep(acc)
54
+ });
55
+ }, element);
56
+ };
57
+ export default evaluate;
package/src/index.cjs ADDED
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+
3
+ var _interopRequireWildcard = require("@babel/runtime-corejs3/helpers/interopRequireWildcard").default;
4
+ var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault").default;
5
+ exports.__esModule = true;
6
+ exports.uriToPointer = exports.unescape = exports.parse = exports.evaluate = exports.escape = exports.compile = exports.JsonPointerError = exports.InvalidJsonPointerError = exports.EvaluationJsonPointerError = exports.CompilationJsonPointerError = void 0;
7
+ var _JsonPointerError = _interopRequireDefault(require("./errors/JsonPointerError.cjs"));
8
+ exports.JsonPointerError = _JsonPointerError.default;
9
+ var _InvalidJsonPointerError = _interopRequireDefault(require("./errors/InvalidJsonPointerError.cjs"));
10
+ exports.InvalidJsonPointerError = _InvalidJsonPointerError.default;
11
+ var _CompilationJsonPointerError = _interopRequireDefault(require("./errors/CompilationJsonPointerError.cjs"));
12
+ exports.CompilationJsonPointerError = _CompilationJsonPointerError.default;
13
+ var _EvaluationJsonPointerError = _interopRequireDefault(require("./errors/EvaluationJsonPointerError.cjs"));
14
+ exports.EvaluationJsonPointerError = _EvaluationJsonPointerError.default;
15
+ var _escape = _interopRequireDefault(require("./escape.cjs"));
16
+ exports.escape = _escape.default;
17
+ var _unescape = _interopRequireDefault(require("./unescape.cjs"));
18
+ exports.unescape = _unescape.default;
19
+ var _parse = _interopRequireWildcard(require("./parse.cjs"));
20
+ exports.parse = _parse.default;
21
+ exports.uriToPointer = _parse.uriToPointer;
22
+ var _compile = _interopRequireDefault(require("./compile.cjs"));
23
+ exports.compile = _compile.default;
24
+ var _evaluate = _interopRequireDefault(require("./evaluate.cjs"));
25
+ exports.evaluate = _evaluate.default;
package/src/index.mjs ADDED
@@ -0,0 +1,9 @@
1
+ export { default as JsonPointerError } from "./errors/JsonPointerError.mjs";
2
+ export { default as InvalidJsonPointerError } from "./errors/InvalidJsonPointerError.mjs";
3
+ export { default as CompilationJsonPointerError } from "./errors/CompilationJsonPointerError.mjs";
4
+ export { default as EvaluationJsonPointerError } from "./errors/EvaluationJsonPointerError.mjs";
5
+ export { default as escape } from "./escape.mjs";
6
+ export { default as unescape } from "./unescape.mjs";
7
+ export { default as parse, uriToPointer } from "./parse.mjs";
8
+ export { default as compile } from "./compile.mjs";
9
+ export { default as evaluate } from "./evaluate.mjs";
package/src/parse.cjs ADDED
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault").default;
4
+ exports.__esModule = true;
5
+ exports.uriToPointer = exports.default = void 0;
6
+ var _ramda = require("ramda");
7
+ var _ramdaAdjunct = require("ramda-adjunct");
8
+ var _unescape = _interopRequireDefault(require("./unescape.cjs"));
9
+ var _InvalidJsonPointerError = _interopRequireDefault(require("./errors/InvalidJsonPointerError.cjs"));
10
+ /**
11
+ * @public
12
+ */
13
+ const parse = pointer => {
14
+ if ((0, _ramdaAdjunct.isEmptyString)(pointer)) {
15
+ return [];
16
+ }
17
+ if (!(0, _ramda.startsWith)('/', pointer)) {
18
+ throw new _InvalidJsonPointerError.default(`Invalid JSON Pointer "${pointer}". JSON Pointers must begin with "/"`, {
19
+ pointer
20
+ });
21
+ }
22
+ try {
23
+ const tokens = (0, _ramda.pipe)((0, _ramda.split)('/'), (0, _ramda.map)(_unescape.default))(pointer);
24
+ return (0, _ramda.tail)(tokens);
25
+ } catch (error) {
26
+ throw new _InvalidJsonPointerError.default(`JSON Pointer parsing of "${pointer}" encountered an error.`, {
27
+ pointer,
28
+ cause: error
29
+ });
30
+ }
31
+ };
32
+
33
+ /**
34
+ * Returns the hash (URL fragment), of the given path.
35
+ * If there is no hash, then the root hash ("#") is returned.
36
+ */
37
+ const getHash = uri => {
38
+ const hashIndex = uri.indexOf('#');
39
+ if (hashIndex !== -1) {
40
+ return uri.substring(hashIndex);
41
+ }
42
+ return '#';
43
+ };
44
+
45
+ /**
46
+ * @public
47
+ */
48
+ const uriToPointer = uri => {
49
+ const hash = getHash(uri);
50
+ return (0, _ramdaAdjunct.trimCharsStart)('#', hash);
51
+ };
52
+ exports.uriToPointer = uriToPointer;
53
+ var _default = exports.default = parse;
package/src/parse.mjs ADDED
@@ -0,0 +1,47 @@
1
+ import { map, pipe, split, startsWith, tail } from 'ramda';
2
+ import { isEmptyString, trimCharsStart } from 'ramda-adjunct';
3
+ import unescape from "./unescape.mjs";
4
+ import InvalidJsonPointerError from "./errors/InvalidJsonPointerError.mjs";
5
+ /**
6
+ * @public
7
+ */
8
+ const parse = pointer => {
9
+ if (isEmptyString(pointer)) {
10
+ return [];
11
+ }
12
+ if (!startsWith('/', pointer)) {
13
+ throw new InvalidJsonPointerError(`Invalid JSON Pointer "${pointer}". JSON Pointers must begin with "/"`, {
14
+ pointer
15
+ });
16
+ }
17
+ try {
18
+ const tokens = pipe(split('/'), map(unescape))(pointer);
19
+ return tail(tokens);
20
+ } catch (error) {
21
+ throw new InvalidJsonPointerError(`JSON Pointer parsing of "${pointer}" encountered an error.`, {
22
+ pointer,
23
+ cause: error
24
+ });
25
+ }
26
+ };
27
+
28
+ /**
29
+ * Returns the hash (URL fragment), of the given path.
30
+ * If there is no hash, then the root hash ("#") is returned.
31
+ */
32
+ const getHash = uri => {
33
+ const hashIndex = uri.indexOf('#');
34
+ if (hashIndex !== -1) {
35
+ return uri.substring(hashIndex);
36
+ }
37
+ return '#';
38
+ };
39
+
40
+ /**
41
+ * @public
42
+ */
43
+ export const uriToPointer = uri => {
44
+ const hash = getHash(uri);
45
+ return trimCharsStart('#', hash);
46
+ };
47
+ export default parse;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.default = void 0;
5
+ var _ramda = require("ramda");
6
+ /**
7
+ * decodeURIComponent can throw URIError in certain cases like 'c%d'.
8
+ * safeDecodeURIComponent is a safe variant of decodeURIComponent that never trows.
9
+ *
10
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Malformed_URI|More info about URIError}
11
+ */
12
+ const safeDecodeURIComponent = encodedURIComponent => {
13
+ try {
14
+ return decodeURIComponent(encodedURIComponent);
15
+ } catch {
16
+ return encodedURIComponent;
17
+ }
18
+ };
19
+
20
+ /**
21
+ * @public
22
+ */
23
+ const unescape = (0, _ramda.pipe)((0, _ramda.replace)(/~1/g, '/'), (0, _ramda.replace)(/~0/g, '~'), safeDecodeURIComponent);
24
+ var _default = exports.default = unescape;
@@ -0,0 +1,21 @@
1
+ import { pipe, replace } from 'ramda';
2
+
3
+ /**
4
+ * decodeURIComponent can throw URIError in certain cases like 'c%d'.
5
+ * safeDecodeURIComponent is a safe variant of decodeURIComponent that never trows.
6
+ *
7
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Malformed_URI|More info about URIError}
8
+ */
9
+ const safeDecodeURIComponent = encodedURIComponent => {
10
+ try {
11
+ return decodeURIComponent(encodedURIComponent);
12
+ } catch {
13
+ return encodedURIComponent;
14
+ }
15
+ };
16
+
17
+ /**
18
+ * @public
19
+ */
20
+ const unescape = pipe(replace(/~1/g, '/'), replace(/~0/g, '~'), safeDecodeURIComponent);
21
+ export default unescape;