@ir-kit/openapi-loader 0.2.0 → 0.3.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
@@ -2,7 +2,7 @@
2
2
 
3
3
  Load an OpenAPI 3.x spec from a file path, URL, or pre-parsed object. Bundles `$ref`s via `@hey-api/json-schema-ref-parser` and runs optional hey-api-aware normalization.
4
4
 
5
- Part of [ir-kit](https://github.com/ir-kit/ir-kit). For multi-format input (OpenAPI + AsyncAPI + TypeSpec under one API), reach for [`@ir-kit/spec-loader`](../../shared/spec-loader) instead.
5
+ Part of [ir-kit](https://github.com/ahmedrowaihi/ir-kit). For multi-format input (OpenAPI + AsyncAPI + TypeSpec under one API), reach for [`@ir-kit/spec-loader`](../../shared/spec-loader) instead.
6
6
 
7
7
  ## Install
8
8
 
package/dist/index.d.ts CHANGED
@@ -8,5 +8,11 @@ export interface LoadOpenAPIOptions {
8
8
  normalize?: boolean | NormalizeOptions;
9
9
  }
10
10
  export declare function loadOpenAPI(opts: LoadOpenAPIOptions): Promise<Record<string, unknown>>;
11
+ /**
12
+ * `x-` extensions are opaque to OpenAPI, so an external `$ref` inside one
13
+ * (Spotify's `x-spotify-policy: { $ref: ../policies.yaml }`) is data, not a
14
+ * dependency of the spec. Rename it to `x-$ref` so bundling never fetches it.
15
+ */
16
+ export declare function detachExtensionRefs(node: unknown, inExtension?: boolean): void;
11
17
  export declare function resolveOpenAPIInput(input: OpenAPIInput, cwd?: string): OpenAPIInput;
12
18
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,gBAAgB,EAGtB,MAAM,iBAAiB,CAAC;AAEzB,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE5D,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,YAAY,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;4DACwD;IACxD,SAAS,CAAC,EAAE,OAAO,GAAG,gBAAgB,CAAC;CACxC;AAED,wBAAsB,WAAW,CAC/B,IAAI,EAAE,kBAAkB,GACvB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAalC;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,YAAY,EACnB,GAAG,GAAE,MAAsB,GAC1B,YAAY,CASd"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,gBAAgB,EAGtB,MAAM,iBAAiB,CAAC;AAEzB,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE5D,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,YAAY,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;4DACwD;IACxD,SAAS,CAAC,EAAE,OAAO,GAAG,gBAAgB,CAAC;CACxC;AAED,wBAAsB,WAAW,CAC/B,IAAI,EAAE,kBAAkB,GACvB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CA0BlC;AAwBD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,EAAE,WAAW,UAAQ,GAAG,IAAI,CAuB5E;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,YAAY,EACnB,GAAG,GAAE,MAAsB,GAC1B,YAAY,CASd"}
package/dist/index.js CHANGED
@@ -1,15 +1,77 @@
1
1
  import { isAbsolute, resolve } from "node:path";
2
2
  import { $RefParser } from "@hey-api/json-schema-ref-parser";
3
- import { normalizeSpec, SAFE_NORMALIZE, } from "@ir-kit/openapi";
3
+ import { hoistForeignSchemaRefs, normalizeSpec, SAFE_NORMALIZE, } from "@ir-kit/openapi";
4
4
  export async function loadOpenAPI(opts) {
5
- const bundled = (await new $RefParser().bundle({
6
- pathOrUrlOrSchema: resolveOpenAPIInput(opts.input, opts.cwd),
5
+ const parser = new $RefParser();
6
+ const input = resolveOpenAPIInput(opts.input, opts.cwd);
7
+ const { schema } = await parser.parse({ pathOrUrlOrSchema: input });
8
+ const root = parser.$refs._root$Ref;
9
+ detachExtensionRefs(schema);
10
+ const bundled = (await parser.bundle({
11
+ pathOrUrlOrSchema: input,
12
+ resolvedInput: {
13
+ path: root.path ?? "",
14
+ schema,
15
+ type: typeof input === "string" ? root.pathType : "json",
16
+ },
7
17
  }));
18
+ hoistForeignSchemaRefs(bundled);
8
19
  if (opts.normalize) {
9
20
  normalizeSpec(bundled, opts.normalize === true ? SAFE_NORMALIZE : opts.normalize);
10
21
  }
11
22
  return bundled;
12
23
  }
24
+ /** Keys whose children are user-named entries, never `x-` extensions. */
25
+ const NAMED_ENTRY_MAPS = new Set([
26
+ "$defs",
27
+ "callbacks",
28
+ "content",
29
+ "definitions",
30
+ "encoding",
31
+ "examples",
32
+ "headers",
33
+ "links",
34
+ "mapping",
35
+ "parameters",
36
+ "pathItems",
37
+ "patternProperties",
38
+ "properties",
39
+ "requestBodies",
40
+ "responses",
41
+ "schemas",
42
+ "securitySchemes",
43
+ "variables",
44
+ ]);
45
+ /**
46
+ * `x-` extensions are opaque to OpenAPI, so an external `$ref` inside one
47
+ * (Spotify's `x-spotify-policy: { $ref: ../policies.yaml }`) is data, not a
48
+ * dependency of the spec. Rename it to `x-$ref` so bundling never fetches it.
49
+ */
50
+ export function detachExtensionRefs(node, inExtension = false) {
51
+ if (!node || typeof node !== "object")
52
+ return;
53
+ if (Array.isArray(node)) {
54
+ for (const item of node)
55
+ detachExtensionRefs(item, inExtension);
56
+ return;
57
+ }
58
+ const obj = node;
59
+ if (inExtension &&
60
+ typeof obj.$ref === "string" &&
61
+ !obj.$ref.startsWith("#")) {
62
+ obj["x-$ref"] = obj.$ref;
63
+ delete obj.$ref;
64
+ }
65
+ for (const [key, value] of Object.entries(obj)) {
66
+ if (NAMED_ENTRY_MAPS.has(key) && value && typeof value === "object") {
67
+ for (const entry of Object.values(value))
68
+ detachExtensionRefs(entry, inExtension);
69
+ }
70
+ else {
71
+ detachExtensionRefs(value, inExtension || key.startsWith("x-"));
72
+ }
73
+ }
74
+ }
13
75
  export function resolveOpenAPIInput(input, cwd = process.cwd()) {
14
76
  if (typeof input !== "string")
15
77
  return input;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAC7D,OAAO,EAEL,aAAa,EACb,cAAc,GACf,MAAM,iBAAiB,CAAC;AAYzB,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,IAAwB;IAExB,MAAM,OAAO,GAAG,CAAC,MAAM,IAAI,UAAU,EAAE,CAAC,MAAM,CAAC;QAC7C,iBAAiB,EAAE,mBAAmB,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC;KAC7D,CAAC,CAA4B,CAAC;IAE/B,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;QACnB,aAAa,CACX,OAAO,EACP,IAAI,CAAC,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAC1D,CAAC;IACJ,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,KAAmB,EACnB,MAAc,OAAO,CAAC,GAAG,EAAE;IAE3B,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5C,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,OAAO,KAAK,EAAE,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;IACD,IAAI,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,OAAO,CAAC;IAClD,IAAI,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,OAAO,CAAC;IACxC,OAAO,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;AAC/B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ir-kit/openapi-loader",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Load an OpenAPI 3.x spec from a file path, URL, or pre-parsed object. Bundles `$ref`s via `@hey-api/json-schema-ref-parser` and runs optional hey-api-aware normalization.",
5
5
  "keywords": [
6
6
  "openapi",
@@ -9,9 +9,9 @@
9
9
  "spec",
10
10
  "ir-kit"
11
11
  ],
12
- "homepage": "https://github.com/ir-kit/ir-kit/tree/main/packages/openapi/loader",
12
+ "homepage": "https://github.com/ahmedrowaihi/ir-kit/tree/main/packages/openapi/loader",
13
13
  "bugs": {
14
- "url": "https://github.com/ir-kit/ir-kit/issues"
14
+ "url": "https://github.com/ahmedrowaihi/ir-kit/issues"
15
15
  },
16
16
  "license": "MIT",
17
17
  "author": {
@@ -20,7 +20,7 @@
20
20
  },
21
21
  "repository": {
22
22
  "type": "git",
23
- "url": "git+https://github.com/ir-kit/ir-kit.git",
23
+ "url": "git+https://github.com/ahmedrowaihi/ir-kit.git",
24
24
  "directory": "packages/openapi/loader"
25
25
  },
26
26
  "type": "module",
@@ -45,7 +45,7 @@
45
45
  },
46
46
  "dependencies": {
47
47
  "@hey-api/json-schema-ref-parser": "^1.4.1",
48
- "@ir-kit/openapi": "0.3.0"
48
+ "@ir-kit/openapi": "0.4.0"
49
49
  },
50
50
  "devDependencies": {
51
51
  "@types/node": "^22",