@hey-api/json-schema-ref-parser 1.0.8 → 1.2.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/README.md CHANGED
@@ -15,9 +15,9 @@
15
15
  Install using [npm](https://docs.npmjs.com/about-npm/):
16
16
 
17
17
  ```bash
18
- npm install @apidevtools/json-schema-ref-parser
19
- yarn add @apidevtools/json-schema-ref-parser
20
- bun add @apidevtools/json-schema-ref-parser
18
+ npm install @hey-api/json-schema-ref-parser
19
+ yarn add @hey-api/json-schema-ref-parser
20
+ bun add @hey-api/json-schema-ref-parser
21
21
  ```
22
22
 
23
23
  ## The Problem:
@@ -69,21 +69,61 @@ JavaScript objects.
69
69
  ## Example
70
70
 
71
71
  ```javascript
72
- import $RefParser from "@apidevtools/json-schema-ref-parser";
72
+ import { $RefParser } from "@hey-api/json-schema-ref-parser";
73
73
 
74
74
  try {
75
- await $RefParser.dereference(mySchema);
76
- // note - by default, mySchema is modified in place, and the returned value is a reference to the same object
77
- console.log(mySchema.definitions.person.properties.firstName);
78
-
79
- // if you want to avoid modifying the original schema, you can disable the `mutateInputSchema` option
80
- let clonedSchema = await $RefParser.dereference(mySchema, { mutateInputSchema: false });
81
- console.log(clonedSchema.definitions.person.properties.firstName);
75
+ const parser = new $RefParser();
76
+ await parser.dereference({ pathOrUrlOrSchema: mySchema });
77
+ console.log(parser.schema.definitions.person.properties.firstName);
82
78
  } catch (err) {
83
79
  console.error(err);
84
80
  }
85
81
  ```
86
82
 
83
+ ### New in this fork (@hey-api)
84
+
85
+ - **Multiple inputs with `bundleMany`**: Merge and bundle several OpenAPI/JSON Schema inputs (files, URLs, or raw objects) into a single schema. Components are prefixed to avoid name collisions, paths are namespaced on conflict, and `$ref`s are rewritten accordingly.
86
+
87
+ ```javascript
88
+ import { $RefParser } from "@hey-api/json-schema-ref-parser";
89
+
90
+ const parser = new $RefParser();
91
+ const merged = await parser.bundleMany({
92
+ pathOrUrlOrSchemas: [
93
+ "./specs/a.yaml",
94
+ "https://example.com/b.yaml",
95
+ { openapi: "3.1.0", info: { title: "Inline" }, paths: {} },
96
+ ],
97
+ });
98
+
99
+ // merged.components.* will contain prefixed names like a_<name>, b_<name>, etc.
100
+ ```
101
+
102
+ - **Dereference hooks**: Fine-tune dereferencing with `excludedPathMatcher(path) => boolean` to skip subpaths and `onDereference(path, value, parent, parentPropName)` to observe replacements.
103
+
104
+ ```javascript
105
+ const parser = new $RefParser();
106
+ parser.options.dereference.excludedPathMatcher = (p) => p.includes("/example/");
107
+ parser.options.dereference.onDereference = (p, v) => {
108
+ // inspect p / v as needed
109
+ };
110
+ await parser.dereference({ pathOrUrlOrSchema: "./openapi.yaml" });
111
+ ```
112
+
113
+ - **Smart input resolution**: You can pass a file path, URL, or raw schema object. If a raw schema includes `$id`, it is used as the base URL for resolving relative `$ref`s.
114
+
115
+ ```javascript
116
+ await new $RefParser().bundle({
117
+ pathOrUrlOrSchema: {
118
+ $id: "https://api.example.com/openapi.json",
119
+ openapi: "3.1.0",
120
+ paths: {
121
+ "/ping": { get: { responses: { 200: { description: "ok" } } } },
122
+ },
123
+ },
124
+ });
125
+ ```
126
+
87
127
  ## Polyfills
88
128
 
89
129
  If you are using Node.js < 18, you'll need a polyfill for `fetch`,
@@ -17,19 +17,16 @@ const __1 = require("..");
17
17
  const refParser = new __1.$RefParser();
18
18
  const pathOrUrlOrSchema = path_1.default.resolve("lib", "__tests__", "spec", "multiple-refs.json");
19
19
  const schema = (await refParser.bundle({ pathOrUrlOrSchema }));
20
- // First reference should be fully resolved (no $ref)
21
- (0, vitest_1.expect)(schema.paths["/test1/{pathId}"].get.parameters[0].name).toBe("pathId");
22
- (0, vitest_1.expect)(schema.paths["/test1/{pathId}"].get.parameters[0].schema.type).toBe("string");
23
- (0, vitest_1.expect)(schema.paths["/test1/{pathId}"].get.parameters[0].schema.format).toBe("uuid");
24
- (0, vitest_1.expect)(schema.paths["/test1/{pathId}"].get.parameters[0].$ref).toBeUndefined();
25
- // Second reference should be remapped to point to the first reference
26
- (0, vitest_1.expect)(schema.paths["/test2/{pathId}"].get.parameters[0].$ref).toBe("#/paths/~1test1~1%7BpathId%7D/get/parameters/0");
27
- // Both should effectively resolve to the same data
20
+ // Both parameters should now be $ref to the same internal definition
28
21
  const firstParam = schema.paths["/test1/{pathId}"].get.parameters[0];
29
22
  const secondParam = schema.paths["/test2/{pathId}"].get.parameters[0];
30
- // The second parameter should resolve to the same data as the first
31
- (0, vitest_1.expect)(secondParam.$ref).toBeDefined();
32
- (0, vitest_1.expect)(firstParam).toEqual({
23
+ // The $ref should match the output structure in file_context_0
24
+ (0, vitest_1.expect)(firstParam.$ref).toBe("#/components/parameters/path-parameter_pathId");
25
+ (0, vitest_1.expect)(secondParam.$ref).toBe("#/components/parameters/path-parameter_pathId");
26
+ // The referenced parameter should exist and match the expected structure
27
+ (0, vitest_1.expect)(schema.components).toBeDefined();
28
+ (0, vitest_1.expect)(schema.components.parameters).toBeDefined();
29
+ (0, vitest_1.expect)(schema.components.parameters["path-parameter_pathId"]).toEqual({
33
30
  name: "pathId",
34
31
  in: "path",
35
32
  required: true,
@@ -11,6 +11,7 @@ const path_1 = __importDefault(require("path"));
11
11
  const refParser = new __1.$RefParser();
12
12
  const pathOrUrlOrSchema = path_1.default.resolve("lib", "__tests__", "spec", "openapi-paths-ref.json");
13
13
  const schema = (await refParser.bundle({ pathOrUrlOrSchema }));
14
+ console.log(JSON.stringify(schema, null, 2));
14
15
  // The GET endpoint should have its schema defined inline
15
16
  const getSchema = schema.paths["/foo"].get.responses["200"].content["application/json"].schema;
16
17
  (0, vitest_1.expect)(getSchema.$ref).toBeUndefined();
@@ -18,10 +19,10 @@ const path_1 = __importDefault(require("path"));
18
19
  (0, vitest_1.expect)(getSchema.properties.bar.type).toBe("string");
19
20
  // The POST endpoint should have its schema inlined (copied) instead of a $ref
20
21
  const postSchema = schema.paths["/foo"].post.responses["200"].content["application/json"].schema;
21
- (0, vitest_1.expect)(postSchema.$ref).toBeUndefined();
22
- (0, vitest_1.expect)(postSchema.type).toBe("object");
23
- (0, vitest_1.expect)(postSchema.properties.bar.type).toBe("string");
22
+ (0, vitest_1.expect)(postSchema.$ref).toBe("#/paths/~1foo/get/responses/200/content/application~1json/schema");
23
+ (0, vitest_1.expect)(postSchema.type).toBeUndefined();
24
+ (0, vitest_1.expect)(postSchema.properties?.bar?.type).toBeUndefined();
24
25
  // Both schemas should be identical objects
25
- (0, vitest_1.expect)(postSchema).toEqual(getSchema);
26
+ (0, vitest_1.expect)(postSchema).not.toBe(getSchema);
26
27
  });
27
28
  });
@@ -13,6 +13,7 @@ export interface InventoryEntry {
13
13
  parent: any;
14
14
  pathFromRoot: any;
15
15
  value: any;
16
+ originalContainerType?: "schemas" | "parameters" | "requestBodies" | "responses" | "headers";
16
17
  }
17
18
  /**
18
19
  * Bundles all external JSON references into the main JSON schema, thus resulting in a schema that