@scalar/json-magic 0.12.2 → 0.12.4

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.
Files changed (72) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/bundle/bundle.js +476 -250
  3. package/dist/bundle/index.js +1 -6
  4. package/dist/bundle/plugins/browser.js +4 -9
  5. package/dist/bundle/plugins/fetch-urls/index.js +76 -49
  6. package/dist/bundle/plugins/node.js +5 -11
  7. package/dist/bundle/plugins/parse-json/index.js +30 -23
  8. package/dist/bundle/plugins/parse-yaml/index.js +31 -24
  9. package/dist/bundle/plugins/read-files/index.js +50 -29
  10. package/dist/bundle/value-generator.js +118 -49
  11. package/dist/dereference/dereference.js +66 -36
  12. package/dist/dereference/index.js +1 -5
  13. package/dist/diff/apply.js +69 -36
  14. package/dist/diff/diff.js +68 -32
  15. package/dist/diff/index.js +4 -9
  16. package/dist/diff/merge.js +122 -60
  17. package/dist/diff/trie.js +100 -77
  18. package/dist/diff/utils.js +96 -41
  19. package/dist/helpers/convert-to-local-ref.js +30 -23
  20. package/dist/helpers/escape-json-pointer.js +7 -6
  21. package/dist/helpers/get-schemas.js +59 -32
  22. package/dist/helpers/get-segments-from-path.js +13 -9
  23. package/dist/helpers/get-value-by-path.js +38 -22
  24. package/dist/helpers/is-file-path.js +19 -9
  25. package/dist/helpers/is-http-url.js +20 -11
  26. package/dist/helpers/is-json-object.js +29 -15
  27. package/dist/helpers/is-yaml.js +17 -6
  28. package/dist/helpers/json-path-utils.js +30 -15
  29. package/dist/helpers/normalize.js +27 -26
  30. package/dist/helpers/resolve-reference-path.js +28 -16
  31. package/dist/helpers/set-value-at-path.js +72 -26
  32. package/dist/helpers/to-relative-path.js +40 -28
  33. package/dist/helpers/unescape-json-pointer.js +8 -6
  34. package/dist/magic-proxy/index.js +1 -6
  35. package/dist/magic-proxy/proxy.js +245 -186
  36. package/dist/types.js +1 -1
  37. package/package.json +5 -7
  38. package/dist/bundle/bundle.js.map +0 -7
  39. package/dist/bundle/index.js.map +0 -7
  40. package/dist/bundle/plugins/browser.js.map +0 -7
  41. package/dist/bundle/plugins/fetch-urls/index.js.map +0 -7
  42. package/dist/bundle/plugins/node.js.map +0 -7
  43. package/dist/bundle/plugins/parse-json/index.js.map +0 -7
  44. package/dist/bundle/plugins/parse-yaml/index.js.map +0 -7
  45. package/dist/bundle/plugins/read-files/index.js.map +0 -7
  46. package/dist/bundle/value-generator.js.map +0 -7
  47. package/dist/dereference/dereference.js.map +0 -7
  48. package/dist/dereference/index.js.map +0 -7
  49. package/dist/diff/apply.js.map +0 -7
  50. package/dist/diff/diff.js.map +0 -7
  51. package/dist/diff/index.js.map +0 -7
  52. package/dist/diff/merge.js.map +0 -7
  53. package/dist/diff/trie.js.map +0 -7
  54. package/dist/diff/utils.js.map +0 -7
  55. package/dist/helpers/convert-to-local-ref.js.map +0 -7
  56. package/dist/helpers/escape-json-pointer.js.map +0 -7
  57. package/dist/helpers/get-schemas.js.map +0 -7
  58. package/dist/helpers/get-segments-from-path.js.map +0 -7
  59. package/dist/helpers/get-value-by-path.js.map +0 -7
  60. package/dist/helpers/is-file-path.js.map +0 -7
  61. package/dist/helpers/is-http-url.js.map +0 -7
  62. package/dist/helpers/is-json-object.js.map +0 -7
  63. package/dist/helpers/is-yaml.js.map +0 -7
  64. package/dist/helpers/json-path-utils.js.map +0 -7
  65. package/dist/helpers/normalize.js.map +0 -7
  66. package/dist/helpers/resolve-reference-path.js.map +0 -7
  67. package/dist/helpers/set-value-at-path.js.map +0 -7
  68. package/dist/helpers/to-relative-path.js.map +0 -7
  69. package/dist/helpers/unescape-json-pointer.js.map +0 -7
  70. package/dist/magic-proxy/index.js.map +0 -7
  71. package/dist/magic-proxy/proxy.js.map +0 -7
  72. package/dist/types.js.map +0 -7
@@ -1,17 +1,29 @@
1
- import path from "pathe";
2
- import { isHttpUrl } from "../helpers/is-http-url.js";
3
- const resolveReferencePath = (base, relativePath) => {
4
- if (isHttpUrl(relativePath)) {
5
- return relativePath;
6
- }
7
- if (isHttpUrl(base)) {
8
- const baseUrl = new URL(base);
9
- baseUrl.pathname = path.posix.resolve("/", path.dirname(baseUrl.pathname), relativePath);
10
- return baseUrl.toString();
11
- }
12
- return path.resolve(path.dirname(base), relativePath);
1
+ import path from 'pathe';
2
+ import { isHttpUrl } from '../helpers/is-http-url.js';
3
+ /**
4
+ * Resolves a reference path by combining a base path with a relative path.
5
+ * Handles both remote URLs and local file paths.
6
+ *
7
+ * @param base - The base path (can be a URL or local file path)
8
+ * @param relativePath - The relative path to resolve against the base
9
+ * @returns The resolved absolute path
10
+ * @example
11
+ * // Resolve remote URL
12
+ * resolveReferencePath('https://example.com/api/schema.json', 'user.json')
13
+ * // Returns: 'https://example.com/api/user.json'
14
+ *
15
+ * // Resolve local path
16
+ * resolveReferencePath('/path/to/schema.json', 'user.json')
17
+ * // Returns: '/path/to/user.json'
18
+ */
19
+ export const resolveReferencePath = (base, relativePath) => {
20
+ if (isHttpUrl(relativePath)) {
21
+ return relativePath;
22
+ }
23
+ if (isHttpUrl(base)) {
24
+ const baseUrl = new URL(base);
25
+ baseUrl.pathname = path.posix.resolve('/', path.dirname(baseUrl.pathname), relativePath);
26
+ return baseUrl.toString();
27
+ }
28
+ return path.resolve(path.dirname(base), relativePath);
13
29
  };
14
- export {
15
- resolveReferencePath
16
- };
17
- //# sourceMappingURL=resolve-reference-path.js.map
@@ -1,28 +1,74 @@
1
- import { preventPollution } from "@scalar/helpers/object/prevent-pollution";
2
- import { getSegmentsFromPath } from "../helpers/get-segments-from-path.js";
3
- function setValueAtPath(obj, path, value) {
4
- if (path === "") {
5
- throw new Error("Cannot set value at root ('') pointer");
6
- }
7
- const parts = getSegmentsFromPath(path);
8
- parts.forEach((part) => preventPollution(part));
9
- let current = obj;
10
- for (let i = 0; i < parts.length; i++) {
11
- const key = parts[i];
12
- const isLast = i === parts.length - 1;
13
- const nextKey = parts[i + 1];
14
- const shouldBeArray = /^\d+$/.test(nextKey ?? "");
15
- if (isLast) {
16
- current[key] = value;
17
- } else {
18
- if (!(key in current) || typeof current[key] !== "object") {
19
- current[key] = shouldBeArray ? [] : {};
20
- }
21
- current = current[key];
1
+ import { preventPollution } from '@scalar/helpers/object/prevent-pollution';
2
+ import { getSegmentsFromPath } from '../helpers/get-segments-from-path.js';
3
+ /**
4
+ * Sets a value at a specified path in an object, creating intermediate objects/arrays as needed.
5
+ * This function traverses the object structure and creates any missing intermediate objects
6
+ * or arrays based on the path segments. If the next segment is a numeric string, it creates
7
+ * an array instead of an object.
8
+ *
9
+ * ⚠️ Warning: Be careful with object keys that look like numbers (e.g. "123") as this function
10
+ * will interpret them as array indices and create arrays instead of objects. If you need to
11
+ * use numeric-looking keys, consider prefixing them with a non-numeric character.
12
+ *
13
+ * @param obj - The target object to set the value in
14
+ * @param path - The JSON pointer path where the value should be set
15
+ * @param value - The value to set at the specified path
16
+ * @throws {Error} If attempting to set a value at the root path ('')
17
+ *
18
+ * @example
19
+ * const obj = {}
20
+ * setValueAtPath(obj, '/foo/bar/0', 'value')
21
+ * // Result:
22
+ * // {
23
+ * // foo: {
24
+ * // bar: ['value']
25
+ * // }
26
+ * // }
27
+ *
28
+ * @example
29
+ * const obj = { existing: { path: 'old' } }
30
+ * setValueAtPath(obj, '/existing/path', 'new')
31
+ * // Result:
32
+ * // {
33
+ * // existing: {
34
+ * // path: 'new'
35
+ * // }
36
+ * // }
37
+ *
38
+ * @example
39
+ * // ⚠️ Warning: This will create an array instead of an object with key "123"
40
+ * setValueAtPath(obj, '/foo/123/bar', 'value')
41
+ * // Result:
42
+ * // {
43
+ * // foo: [
44
+ * // undefined,
45
+ * // undefined,
46
+ * // undefined,
47
+ * // { bar: 'value' }
48
+ * // ]
49
+ * // }
50
+ */
51
+ export function setValueAtPath(obj, path, value) {
52
+ if (path === '') {
53
+ throw new Error("Cannot set value at root ('') pointer");
54
+ }
55
+ const parts = getSegmentsFromPath(path);
56
+ // Prevent prototype pollution
57
+ parts.forEach((part) => preventPollution(part));
58
+ let current = obj;
59
+ for (let i = 0; i < parts.length; i++) {
60
+ const key = parts[i];
61
+ const isLast = i === parts.length - 1;
62
+ const nextKey = parts[i + 1];
63
+ const shouldBeArray = /^\d+$/.test(nextKey ?? '');
64
+ if (isLast) {
65
+ current[key] = value;
66
+ }
67
+ else {
68
+ if (!(key in current) || typeof current[key] !== 'object') {
69
+ current[key] = shouldBeArray ? [] : {};
70
+ }
71
+ current = current[key];
72
+ }
22
73
  }
23
- }
24
74
  }
25
- export {
26
- setValueAtPath
27
- };
28
- //# sourceMappingURL=set-value-at-path.js.map
@@ -1,30 +1,42 @@
1
- import path from "pathe";
2
- import { isHttpUrl } from "../helpers/is-http-url.js";
3
- const toRelativePath = (input, base) => {
4
- if (isHttpUrl(input) && isHttpUrl(base)) {
5
- const inputUrl = new URL(input);
6
- const baseUrl = new URL(base);
7
- if (inputUrl.origin !== baseUrl.origin) {
8
- return input;
1
+ import path from 'pathe';
2
+ import { isHttpUrl } from '../helpers/is-http-url.js';
3
+ /**
4
+ * Converts an input path or URL to a relative path based on the provided base.
5
+ * Handles both remote URLs and local file system paths.
6
+ * - If both input and base are remote URLs and share the same origin, computes the relative pathname.
7
+ * - If base is a remote URL but input is local, returns a remote URL with a relative pathname.
8
+ * - If input is a remote URL but base is local, returns input as is.
9
+ * - Otherwise, computes the relative path between two local paths.
10
+ */
11
+ export const toRelativePath = (input, base) => {
12
+ // Both input and base are remote URLs
13
+ if (isHttpUrl(input) && isHttpUrl(base)) {
14
+ const inputUrl = new URL(input);
15
+ const baseUrl = new URL(base);
16
+ // If origins aren't the same, return input as is
17
+ if (inputUrl.origin !== baseUrl.origin) {
18
+ return input;
19
+ }
20
+ // Get the directory of the base URL pathname (not the file itself)
21
+ const baseDir = path.dirname(path.posix.resolve('/', baseUrl.pathname));
22
+ const inputPath = path.posix.resolve('/', inputUrl.pathname);
23
+ // Return the relative path from baseDir to inputPath
24
+ return path.posix.relative(baseDir, inputPath);
9
25
  }
10
- const baseDir2 = path.dirname(path.posix.resolve("/", baseUrl.pathname));
11
- const inputPath2 = path.posix.resolve("/", inputUrl.pathname);
12
- return path.posix.relative(baseDir2, inputPath2);
13
- }
14
- if (isHttpUrl(base)) {
15
- const baseUrl = new URL(base);
16
- const baseDir2 = path.dirname(path.posix.resolve("/", baseUrl.pathname));
17
- baseUrl.pathname = path.posix.relative(baseDir2, path.posix.resolve("/", input));
18
- return baseUrl.toString();
19
- }
20
- if (isHttpUrl(input)) {
21
- return input;
22
- }
23
- const baseDir = path.dirname(path.resolve(base));
24
- const inputPath = path.resolve(input);
25
- return path.relative(baseDir, inputPath);
26
- };
27
- export {
28
- toRelativePath
26
+ // Base is a remote URL, input is a local path
27
+ if (isHttpUrl(base)) {
28
+ const baseUrl = new URL(base);
29
+ const baseDir = path.dirname(path.posix.resolve('/', baseUrl.pathname));
30
+ // Set the pathname of the base URL to the relative path and return the URL as a string
31
+ baseUrl.pathname = path.posix.relative(baseDir, path.posix.resolve('/', input));
32
+ return baseUrl.toString();
33
+ }
34
+ // Input is a remote URL, base is a local path; just return input
35
+ if (isHttpUrl(input)) {
36
+ return input;
37
+ }
38
+ // Both input and base are local paths; return the relative path
39
+ const baseDir = path.dirname(path.resolve(base));
40
+ const inputPath = path.resolve(input);
41
+ return path.relative(baseDir, inputPath);
29
42
  };
30
- //# sourceMappingURL=to-relative-path.js.map
@@ -1,7 +1,9 @@
1
- function unescapeJsonPointer(uri) {
2
- return decodeURI(uri.replace(/~1/g, "/").replace(/~0/g, "~"));
1
+ /**
2
+ * Unescape JSON pointer
3
+ *
4
+ * Examples:
5
+ * /foo~1bar~0baz -> /foo/bar~baz
6
+ */
7
+ export function unescapeJsonPointer(uri) {
8
+ return decodeURI(uri.replace(/~1/g, '/').replace(/~0/g, '~'));
3
9
  }
4
- export {
5
- unescapeJsonPointer
6
- };
7
- //# sourceMappingURL=unescape-json-pointer.js.map
@@ -1,6 +1 @@
1
- import { createMagicProxy, getRaw } from "./proxy.js";
2
- export {
3
- createMagicProxy,
4
- getRaw
5
- };
6
- //# sourceMappingURL=index.js.map
1
+ export { createMagicProxy, getRaw } from './proxy.js';