@scalar/json-magic 0.9.6 → 0.10.0

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
@@ -1,5 +1,11 @@
1
1
  # @scalar/json-magic
2
2
 
3
+ ## 0.10.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#8052](https://github.com/scalar/scalar/pull/8052): feat: allow custom LoaderPlugin plugins in dereference
8
+
3
9
  ## 0.9.6
4
10
 
5
11
  ### Patch Changes
@@ -1,3 +1,4 @@
1
+ import { type Plugin } from '../bundle/index.js';
1
2
  import type { UnknownObject } from '../types.js';
2
3
  type DereferenceResult = {
3
4
  success: true;
@@ -17,7 +18,7 @@ type ReturnDereferenceResult<Opt extends {
17
18
  * Otherwise, it bundles the document, resolving all $refs (including remote ones), and returns a promise.
18
19
  *
19
20
  * @param input - JSON Schema object to dereference.
20
- * @param options - Optional settings. If `sync` is true, dereferencing is synchronous.
21
+ * @param options - Optional settings. If `sync` is true, dereferencing is synchronous. If `plugins` is provided, those plugins are used for resolution instead of the default `fetchUrls()`.
21
22
  * @returns A DereferenceResult (or Promise thereof) indicating success and the dereferenced data, or errors.
22
23
  *
23
24
  * @example
@@ -37,9 +38,15 @@ type ReturnDereferenceResult<Opt extends {
37
38
  * console.error(result.errors);
38
39
  * }
39
40
  * });
41
+ *
42
+ * @example
43
+ * // Asynchronous dereference (with custom loader plugin)
44
+ * const plugin = { type: 'loader', validate: (v) => v.startsWith('workspace:'), exec: (v) => resolve(v) };
45
+ * const result = await dereference({ $ref: 'workspace:my-schema' }, { plugins: [plugin] });
40
46
  */
41
47
  export declare const dereference: <Opts extends {
42
48
  sync?: boolean;
49
+ plugins?: Plugin[];
43
50
  }>(input: UnknownObject, options?: Opts) => ReturnDereferenceResult<Opts>;
44
51
  export {};
45
52
  //# sourceMappingURL=dereference.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dereference.d.ts","sourceRoot":"","sources":["../../src/dereference/dereference.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAE5C,KAAK,iBAAiB,GAClB;IACE,OAAO,EAAE,IAAI,CAAA;IACb,IAAI,EAAE,aAAa,CAAA;CACpB,GACD;IACE,OAAO,EAAE,KAAK,CAAA;IACd,MAAM,EAAE,MAAM,EAAE,CAAA;CACjB,CAAA;AAEL,KAAK,uBAAuB,CAAC,GAAG,SAAS;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,IAAI,GAAG,CAAC,MAAM,CAAC,SAAS,IAAI,GACnF,iBAAiB,GACjB,OAAO,CAAC,iBAAiB,CAAC,CAAA;AAE9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,eAAO,MAAM,WAAW,GAAI,IAAI,SAAS;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,EACzD,OAAO,aAAa,EACpB,UAAU,IAAI,KACb,uBAAuB,CAAC,IAAI,CAgC9B,CAAA"}
1
+ {"version":3,"file":"dereference.d.ts","sourceRoot":"","sources":["../../src/dereference/dereference.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAU,MAAM,UAAU,CAAA;AAG9C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAE5C,KAAK,iBAAiB,GAClB;IACE,OAAO,EAAE,IAAI,CAAA;IACb,IAAI,EAAE,aAAa,CAAA;CACpB,GACD;IACE,OAAO,EAAE,KAAK,CAAA;IACd,MAAM,EAAE,MAAM,EAAE,CAAA;CACjB,CAAA;AAEL,KAAK,uBAAuB,CAAC,GAAG,SAAS;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,IAAI,GAAG,CAAC,MAAM,CAAC,SAAS,IAAI,GACnF,iBAAiB,GACjB,OAAO,CAAC,iBAAiB,CAAC,CAAA;AAE9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,eAAO,MAAM,WAAW,GAAI,IAAI,SAAS;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,EAC7E,OAAO,aAAa,EACpB,UAAU,IAAI,KACb,uBAAuB,CAAC,IAAI,CAiC9B,CAAA"}
@@ -9,8 +9,9 @@ const dereference = (input, options) => {
9
9
  };
10
10
  }
11
11
  const errors = [];
12
+ const plugins = options?.plugins || [fetchUrls()];
12
13
  return bundle(input, {
13
- plugins: [fetchUrls()],
14
+ plugins,
14
15
  treeShake: false,
15
16
  urlMap: true,
16
17
  hooks: {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/dereference/dereference.ts"],
4
- "sourcesContent": ["import { bundle } from '@/bundle'\nimport { fetchUrls } from '@/bundle/plugins/fetch-urls'\nimport { createMagicProxy } from '@/magic-proxy'\nimport type { UnknownObject } from '@/types'\n\ntype DereferenceResult =\n | {\n success: true\n data: UnknownObject\n }\n | {\n success: false\n errors: string[]\n }\n\ntype ReturnDereferenceResult<Opt extends { sync?: boolean }> = Opt['sync'] extends true\n ? DereferenceResult\n : Promise<DereferenceResult>\n\n/**\n * Dereferences a JSON object, resolving all $ref pointers.\n *\n * This function can operate synchronously (no remote refs, no async plugins) or asynchronously (with remote refs).\n * If `options.sync` is true, it simply wraps the input in a magic proxy and returns it.\n * Otherwise, it bundles the document, resolving all $refs (including remote ones), and returns a promise.\n *\n * @param input - JSON Schema object to dereference.\n * @param options - Optional settings. If `sync` is true, dereferencing is synchronous.\n * @returns A DereferenceResult (or Promise thereof) indicating success and the dereferenced data, or errors.\n *\n * @example\n * // Synchronous dereference (no remote refs)\n * const result = dereference({ openapi: '3.0.0', info: { title: 'My API', version: '1.0.0' } }, { sync: true });\n * if (result.success) {\n * console.log(result.data); // Magic proxy-wrapped document\n * }\n *\n * @example\n * // Asynchronous dereference (with remote refs)\n * dereference({ $ref: 'https://example.com/api.yaml' })\n * .then(result => {\n * if (result.success) {\n * console.log(result.data); // Fully dereferenced document\n * } else {\n * console.error(result.errors);\n * }\n * });\n */\nexport const dereference = <Opts extends { sync?: boolean }>(\n input: UnknownObject,\n options?: Opts,\n): ReturnDereferenceResult<Opts> => {\n if (options?.sync) {\n return {\n success: true,\n data: createMagicProxy(input),\n } as ReturnDereferenceResult<Opts>\n }\n\n const errors: string[] = []\n\n return bundle(input, {\n plugins: [fetchUrls()],\n treeShake: false,\n urlMap: true,\n hooks: {\n onResolveError(node) {\n errors.push(`Failed to resolve ${node.$ref}`)\n },\n },\n }).then((result) => {\n if (errors.length > 0) {\n return {\n success: false,\n errors,\n }\n }\n\n return {\n success: true,\n data: createMagicProxy(result as UnknownObject),\n }\n }) as ReturnDereferenceResult<Opts>\n}\n"],
5
- "mappings": "AAAA,SAAS,cAAc;AACvB,SAAS,iBAAiB;AAC1B,SAAS,wBAAwB;AA8C1B,MAAM,cAAc,CACzB,OACA,YACkC;AAClC,MAAI,SAAS,MAAM;AACjB,WAAO;AAAA,MACL,SAAS;AAAA,MACT,MAAM,iBAAiB,KAAK;AAAA,IAC9B;AAAA,EACF;AAEA,QAAM,SAAmB,CAAC;AAE1B,SAAO,OAAO,OAAO;AAAA,IACnB,SAAS,CAAC,UAAU,CAAC;AAAA,IACrB,WAAW;AAAA,IACX,QAAQ;AAAA,IACR,OAAO;AAAA,MACL,eAAe,MAAM;AACnB,eAAO,KAAK,qBAAqB,KAAK,IAAI,EAAE;AAAA,MAC9C;AAAA,IACF;AAAA,EACF,CAAC,EAAE,KAAK,CAAC,WAAW;AAClB,QAAI,OAAO,SAAS,GAAG;AACrB,aAAO;AAAA,QACL,SAAS;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,MACL,SAAS;AAAA,MACT,MAAM,iBAAiB,MAAuB;AAAA,IAChD;AAAA,EACF,CAAC;AACH;",
4
+ "sourcesContent": ["import { type Plugin, bundle } from '@/bundle'\nimport { fetchUrls } from '@/bundle/plugins/fetch-urls'\nimport { createMagicProxy } from '@/magic-proxy'\nimport type { UnknownObject } from '@/types'\n\ntype DereferenceResult =\n | {\n success: true\n data: UnknownObject\n }\n | {\n success: false\n errors: string[]\n }\n\ntype ReturnDereferenceResult<Opt extends { sync?: boolean }> = Opt['sync'] extends true\n ? DereferenceResult\n : Promise<DereferenceResult>\n\n/**\n * Dereferences a JSON object, resolving all $ref pointers.\n *\n * This function can operate synchronously (no remote refs, no async plugins) or asynchronously (with remote refs).\n * If `options.sync` is true, it simply wraps the input in a magic proxy and returns it.\n * Otherwise, it bundles the document, resolving all $refs (including remote ones), and returns a promise.\n *\n * @param input - JSON Schema object to dereference.\n * @param options - Optional settings. If `sync` is true, dereferencing is synchronous. If `plugins` is provided, those plugins are used for resolution instead of the default `fetchUrls()`.\n * @returns A DereferenceResult (or Promise thereof) indicating success and the dereferenced data, or errors.\n *\n * @example\n * // Synchronous dereference (no remote refs)\n * const result = dereference({ openapi: '3.0.0', info: { title: 'My API', version: '1.0.0' } }, { sync: true });\n * if (result.success) {\n * console.log(result.data); // Magic proxy-wrapped document\n * }\n *\n * @example\n * // Asynchronous dereference (with remote refs)\n * dereference({ $ref: 'https://example.com/api.yaml' })\n * .then(result => {\n * if (result.success) {\n * console.log(result.data); // Fully dereferenced document\n * } else {\n * console.error(result.errors);\n * }\n * });\n *\n * @example\n * // Asynchronous dereference (with custom loader plugin)\n * const plugin = { type: 'loader', validate: (v) => v.startsWith('workspace:'), exec: (v) => resolve(v) };\n * const result = await dereference({ $ref: 'workspace:my-schema' }, { plugins: [plugin] });\n */\nexport const dereference = <Opts extends { sync?: boolean; plugins?: Plugin[] }>(\n input: UnknownObject,\n options?: Opts,\n): ReturnDereferenceResult<Opts> => {\n if (options?.sync) {\n return {\n success: true,\n data: createMagicProxy(input),\n } as ReturnDereferenceResult<Opts>\n }\n\n const errors: string[] = []\n const plugins = options?.plugins || [fetchUrls()]\n\n return bundle(input, {\n plugins,\n treeShake: false,\n urlMap: true,\n hooks: {\n onResolveError(node) {\n errors.push(`Failed to resolve ${node.$ref}`)\n },\n },\n }).then((result) => {\n if (errors.length > 0) {\n return {\n success: false,\n errors,\n }\n }\n\n return {\n success: true,\n data: createMagicProxy(result as UnknownObject),\n }\n }) as ReturnDereferenceResult<Opts>\n}\n"],
5
+ "mappings": "AAAA,SAAsB,cAAc;AACpC,SAAS,iBAAiB;AAC1B,SAAS,wBAAwB;AAmD1B,MAAM,cAAc,CACzB,OACA,YACkC;AAClC,MAAI,SAAS,MAAM;AACjB,WAAO;AAAA,MACL,SAAS;AAAA,MACT,MAAM,iBAAiB,KAAK;AAAA,IAC9B;AAAA,EACF;AAEA,QAAM,SAAmB,CAAC;AAC1B,QAAM,UAAU,SAAS,WAAW,CAAC,UAAU,CAAC;AAEhD,SAAO,OAAO,OAAO;AAAA,IACnB;AAAA,IACA,WAAW;AAAA,IACX,QAAQ;AAAA,IACR,OAAO;AAAA,MACL,eAAe,MAAM;AACnB,eAAO,KAAK,qBAAqB,KAAK,IAAI,EAAE;AAAA,MAC9C;AAAA,IACF;AAAA,EACF,CAAC,EAAE,KAAK,CAAC,WAAW;AAClB,QAAI,OAAO,SAAS,GAAG;AACrB,aAAO;AAAA,QACL,SAAS;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,MACL,SAAS;AAAA,MACT,MAAM,iBAAiB,MAAuB;AAAA,IAChD;AAAA,EACF,CAAC;AACH;",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -10,7 +10,7 @@
10
10
  "url": "git+https://github.com/scalar/scalar.git",
11
11
  "directory": "packages/json-magic"
12
12
  },
13
- "version": "0.9.6",
13
+ "version": "0.10.0",
14
14
  "engines": {
15
15
  "node": ">=20"
16
16
  },