@scalar/openapi-parser 0.10.15 → 0.10.16

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 (34) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +0 -22
  3. package/dist/lib/Validator/Validator.js +1 -1
  4. package/dist/plugins/fetch-urls/fetchUrls.d.ts +0 -1
  5. package/dist/plugins/fetch-urls/fetchUrls.d.ts.map +1 -1
  6. package/dist/plugins/fetch-urls/fetchUrls.js +7 -79
  7. package/dist/plugins/fetch-urls/index.d.ts +1 -1
  8. package/dist/plugins/fetch-urls/index.d.ts.map +1 -1
  9. package/dist/plugins/fetch-urls/index.js +1 -1
  10. package/dist/plugins/read-files/index.d.ts +1 -1
  11. package/dist/plugins/read-files/index.d.ts.map +1 -1
  12. package/dist/plugins/read-files/readFiles.d.ts.map +1 -1
  13. package/dist/plugins/read-files/readFiles.js +3 -18
  14. package/dist/types/index.d.ts +4 -23
  15. package/dist/types/index.d.ts.map +1 -1
  16. package/dist/utils/dereference.js +2 -2
  17. package/dist/utils/filter.js +1 -1
  18. package/dist/utils/isFilesystem.d.ts +1 -2
  19. package/dist/utils/isFilesystem.d.ts.map +1 -1
  20. package/dist/utils/load/load.d.ts +2 -11
  21. package/dist/utils/load/load.d.ts.map +1 -1
  22. package/dist/utils/load/load.js +38 -77
  23. package/dist/utils/makeFilesystem.d.ts +1 -18
  24. package/dist/utils/makeFilesystem.d.ts.map +1 -1
  25. package/dist/utils/makeFilesystem.js +9 -55
  26. package/dist/utils/openapi/actions/details.js +1 -1
  27. package/dist/utils/openapi/actions/toJson.js +1 -1
  28. package/dist/utils/openapi/actions/toYaml.js +1 -1
  29. package/dist/utils/openapi/commands/loadCommand.d.ts +180 -180
  30. package/dist/utils/resolveReferences.d.ts +0 -6
  31. package/dist/utils/resolveReferences.d.ts.map +1 -1
  32. package/dist/utils/resolveReferences.js +9 -19
  33. package/dist/utils/upgrade.js +1 -1
  34. package/package.json +3 -4
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @scalar/openapi-parser
2
2
 
3
+ ## 0.10.16
4
+
5
+ ### Patch Changes
6
+
7
+ - c5047ee: fix: hotfix to revert the external reference commit
8
+
3
9
  ## 0.10.15
4
10
 
5
11
  ### Patch Changes
package/README.md CHANGED
@@ -239,33 +239,11 @@ import { fetchUrls } from '@scalar/openapi-parser/plugins/fetch-urls'
239
239
  const { filesystem } = await load(
240
240
  'https://cdn.jsdelivr.net/npm/@scalar/galaxy/dist/latest.yaml',
241
241
  {
242
- // Optional: If you directly pass an OpenAPI (not an URL), let it know where the content came from
243
- // That’s the only way we can resolve external references, if they are relative.
244
- source: 'https://cdn.jsdelivr.net/npm/@scalar/galaxy/dist/latest.yaml'
245
242
  plugins: [fetchUrls()],
246
243
  },
247
244
  )
248
245
  ```
249
246
 
250
- #### Bundle external references
251
-
252
- By default, `dereference` tries to resolve both internal and external references. You can disable resolving internal references by setting `resolveInternalRefs` to `false`:
253
-
254
- ```ts
255
- import { dereference, load } from '@scalar/openapi-parser'
256
- import { fetchUrls } from '@scalar/openapi-parser/plugins/fetch-urls'
257
-
258
- // Load a file and all referenced files
259
- const { filesystem } = await load('https://cdn.jsdelivr.net/npm/@scalar/galaxy/dist/latest.yaml', {
260
- plugins: [fetchUrls()],
261
- })
262
-
263
- const result = await dereference(filesystem, {
264
- // Skips internal references like `$ref: '#/components/schemas/foobar'`
265
- resolveInternalRefs: false,
266
- })
267
- ```
268
-
269
247
  #### Intercept HTTP requests
270
248
 
271
249
  If you’re using the package in a browser environment, you may run into CORS issues when fetching from URLs. You can intercept the requests, for example to use a proxy, though:
@@ -27,7 +27,7 @@ class Validator {
27
27
  */
28
28
  async validate(filesystem, options) {
29
29
  const entrypoint = filesystem.find((file) => file.isEntrypoint);
30
- const specification = entrypoint?.content;
30
+ const specification = entrypoint?.specification;
31
31
  // TODO: How does this work with a filesystem?
32
32
  this.specification = specification;
33
33
  // TODO: defaulting info.version to keep parser compatible with the previous one
@@ -12,5 +12,4 @@ export declare const fetchUrls: (customConfiguration?: {
12
12
  */
13
13
  fetch?: (url: string) => Promise<Response>;
14
14
  }) => LoadPlugin;
15
- export declare function getAbsoluteUrl(value: string, source?: unknown): string;
16
15
  //# sourceMappingURL=fetchUrls.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fetchUrls.d.ts","sourceRoot":"","sources":["../../../src/plugins/fetch-urls/fetchUrls.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AAE1D,eAAO,MAAM,6BAA6B;;CAEzC,CAAA;AAED,eAAO,MAAM,SAAS,EAAE,CAAC,mBAAmB,CAAC,EAAE;IAC7C;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,KAAK,CAAA;IACtB;;OAEG;IACH,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;CAC3C,KAAK,UAqDL,CAAA;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,UAyE7D"}
1
+ {"version":3,"file":"fetchUrls.d.ts","sourceRoot":"","sources":["../../../src/plugins/fetch-urls/fetchUrls.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AAE1D,eAAO,MAAM,6BAA6B;;CAEzC,CAAA;AAED,eAAO,MAAM,SAAS,EAAE,CAAC,mBAAmB,CAAC,EAAE;IAC7C;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,KAAK,CAAA;IACtB;;OAEG;IACH,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;CAC3C,KAAK,UA2CL,CAAA"}
@@ -1,5 +1,5 @@
1
1
  const fetchUrlsDefaultConfiguration = {
2
- limit: 100,
2
+ limit: 20,
3
3
  };
4
4
  const fetchUrls = (customConfiguration) => {
5
5
  // State
@@ -10,24 +10,18 @@ const fetchUrls = (customConfiguration) => {
10
10
  ...customConfiguration,
11
11
  };
12
12
  return {
13
- // Make it run after readFiles
14
- priority: 0,
15
13
  check(value) {
16
14
  // Not a string
17
15
  if (typeof value !== 'string') {
18
16
  return false;
19
17
  }
20
- // Seems to be JSON
21
- if (value.startsWith('{') || value.startsWith('[')) {
22
- return false;
23
- }
24
- // Seems to be YAML
25
- if (value.includes('\n')) {
18
+ // Not http/https
19
+ if (!value.startsWith('http://') && !value.startsWith('https://')) {
26
20
  return false;
27
21
  }
28
22
  return true;
29
23
  },
30
- async get(url) {
24
+ async get(value) {
31
25
  // Limit ht enumber of requests
32
26
  if (configuration?.limit !== false && numberOfRequests >= configuration?.limit) {
33
27
  console.warn(`[fetchUrls] Maximum number of requests reeached (${configuration?.limit}), skipping request`);
@@ -35,81 +29,15 @@ const fetchUrls = (customConfiguration) => {
35
29
  }
36
30
  try {
37
31
  numberOfRequests++;
38
- const response = await (configuration?.fetch ? configuration.fetch(url) : fetch(url));
32
+ const response = await (configuration?.fetch ? configuration.fetch(value) : fetch(value));
39
33
  return await response.text();
40
34
  }
41
35
  catch (error) {
42
- console.error('[fetchUrls]', error.message, `(${url})`);
36
+ console.error('[fetchUrls]', error.message, `(${value})`);
43
37
  return undefined;
44
38
  }
45
39
  },
46
- getUri(value, source) {
47
- return getAbsoluteUrl(value, source);
48
- },
49
40
  };
50
41
  };
51
- function getAbsoluteUrl(value, source) {
52
- if (typeof source !== 'string') {
53
- return value;
54
- }
55
- // Already an absolute URL
56
- if (value.startsWith('http')) {
57
- return value;
58
- }
59
- // Make it an absolute URL
60
- if (source) {
61
- // Skip if source or value is JSON/YAML content
62
- if (source.startsWith('{') ||
63
- source.startsWith('[') ||
64
- source.includes('\n') ||
65
- value.startsWith('{') ||
66
- value.startsWith('[') ||
67
- value.includes('\n')) {
68
- return value;
69
- }
70
- try {
71
- // If source is an HTTP URL, handle both absolute and relative paths
72
- if (source.startsWith('http')) {
73
- const sourceUrl = new URL(source);
74
- // If value starts with /, treat it as relative to the host root
75
- if (value.startsWith('/')) {
76
- // Simply combine the origin with the absolute path
77
- return `${sourceUrl.origin}${value}`;
78
- }
79
- // Otherwise treat it as relative to the source URL's directory
80
- return new URL(value, sourceUrl.href).toString();
81
- }
82
- // Handle file system paths
83
- if (source.startsWith('/') || !source.startsWith('http')) {
84
- const sourceParts = source.split('/').filter(Boolean).slice(0, -1);
85
- const valueParts = value.split('/').filter(Boolean);
86
- const isAbsolute = source.startsWith('/');
87
- // If value is absolute path, start fresh
88
- if (value.startsWith('/')) {
89
- return value;
90
- }
91
- // Process each part of the path
92
- const resultParts = [...sourceParts];
93
- for (const part of valueParts) {
94
- if (part === '..') {
95
- resultParts.pop();
96
- }
97
- else if (part !== '.') {
98
- resultParts.push(part);
99
- }
100
- }
101
- // Preserve the leading slash for absolute paths, but avoid double slashes
102
- return isAbsolute ? '/' + resultParts.join('/') : resultParts.join('/');
103
- }
104
- return new URL(value, source).toString();
105
- }
106
- catch (error) {
107
- console.warn('[fetchUrls] Failed to resolve URL:', error.message, `(${value})`);
108
- return value;
109
- }
110
- }
111
- // Otherwise, return the value as is
112
- return value;
113
- }
114
42
 
115
- export { fetchUrls, fetchUrlsDefaultConfiguration, getAbsoluteUrl };
43
+ export { fetchUrls, fetchUrlsDefaultConfiguration };
@@ -1,2 +1,2 @@
1
- export { fetchUrlsDefaultConfiguration, fetchUrls, getAbsoluteUrl, } from './fetchUrls.ts';
1
+ export * from './fetchUrls.ts';
2
2
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/fetch-urls/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,6BAA6B,EAC7B,SAAS,EACT,cAAc,GACf,MAAM,gBAAgB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/fetch-urls/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAA"}
@@ -1 +1 @@
1
- export { fetchUrls, fetchUrlsDefaultConfiguration, getAbsoluteUrl } from './fetchUrls.js';
1
+ export { fetchUrls, fetchUrlsDefaultConfiguration } from './fetchUrls.js';
@@ -1,2 +1,2 @@
1
- export { readFiles } from './readFiles.ts';
1
+ export * from './readFiles.ts';
2
2
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/read-files/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/read-files/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"readFiles.d.ts","sourceRoot":"","sources":["../../../src/plugins/read-files/readFiles.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AAE1D,eAAO,MAAM,SAAS,EAAE,MAAM,UAyE7B,CAAA"}
1
+ {"version":3,"file":"readFiles.d.ts","sourceRoot":"","sources":["../../../src/plugins/read-files/readFiles.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AAE1D,eAAO,MAAM,SAAS,EAAE,MAAM,UAqD7B,CAAA"}
@@ -6,8 +6,6 @@ import { isYaml } from '../../utils/isYaml.js';
6
6
 
7
7
  const readFiles = () => {
8
8
  return {
9
- // Make it run before fetchUrls
10
- priority: 100,
11
9
  check(value) {
12
10
  // Not a string
13
11
  if (typeof value !== 'string') {
@@ -32,9 +30,6 @@ const readFiles = () => {
32
30
  return true;
33
31
  },
34
32
  async get(value) {
35
- if (typeof value !== 'string') {
36
- return false;
37
- }
38
33
  if (!fs.existsSync(value)) {
39
34
  throw new Error(ERRORS.FILE_DOES_NOT_EXIST.replace('%s', value));
40
35
  }
@@ -46,19 +41,9 @@ const readFiles = () => {
46
41
  return false;
47
42
  }
48
43
  },
49
- getUri(value, source) {
50
- if (typeof value !== 'string') {
51
- return undefined;
52
- }
53
- if (typeof source !== 'string') {
54
- return value;
55
- }
56
- // Already absolute
57
- if (value.startsWith('/')) {
58
- return value;
59
- }
60
- const dir = dirname(source);
61
- return join(dir, value);
44
+ resolvePath(value, reference) {
45
+ const dir = dirname(value);
46
+ return join(dir, reference);
62
47
  },
63
48
  getDir(value) {
64
49
  return dirname(value);
@@ -55,30 +55,11 @@ export type Filesystem = FilesystemEntry[];
55
55
  * Holds all information about a single file (doesn’t have to be a literal file, see Filesystem).
56
56
  */
57
57
  export type FilesystemEntry = {
58
- /**
59
- * The absolute path or URL to the file.
60
- *
61
- * @example https://example.com/path/to/file.yaml
62
- * @example /Users/username/project/path/to/file.yaml
63
- */
64
- uri: string | null;
65
- /**
66
- * Whether this is the base document, everything else is just referenced by it.
67
- */
58
+ dir: string;
68
59
  isEntrypoint: boolean;
69
- /**
70
- * A map of the references to other files.
71
- *
72
- * @example {
73
- * 'file.yaml': 'https://example.com/folder/file.yaml',
74
- * '../file2.yaml': 'https://example.com/file2.yaml',
75
- * }
76
- */
77
- references: Record<string, string>;
78
- /**
79
- * The actual content of the document
80
- */
81
- content: AnyObject;
60
+ references: string[];
61
+ filename: string;
62
+ specification: AnyObject;
82
63
  };
83
64
  /**
84
65
  * Options, that can apply to all commands
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
@@ -11,10 +11,10 @@ async function dereference(value, options) {
11
11
  const entrypoint = getEntrypoint(filesystem);
12
12
  const result = resolveReferences(filesystem, options);
13
13
  return {
14
- specification: entrypoint.content,
14
+ specification: entrypoint.specification,
15
15
  errors: result.errors,
16
16
  schema: result.schema,
17
- ...details(entrypoint.content),
17
+ ...details(entrypoint.specification),
18
18
  };
19
19
  }
20
20
 
@@ -8,7 +8,7 @@ import { traverse } from './traverse.js';
8
8
  function filter(specification, callback) {
9
9
  const filesystem = makeFilesystem(specification);
10
10
  return {
11
- specification: traverse(getEntrypoint(filesystem).content, (schema) => {
11
+ specification: traverse(getEntrypoint(filesystem).specification, (schema) => {
12
12
  return callback(schema) ? schema : undefined;
13
13
  }),
14
14
  };
@@ -1,6 +1,5 @@
1
- import type { Filesystem } from '../types/index.ts';
2
1
  /**
3
2
  * Check if the value is a filesystem
4
3
  */
5
- export declare function isFilesystem(value: any): value is Filesystem;
4
+ export declare function isFilesystem(value: any): boolean;
6
5
  //# sourceMappingURL=isFilesystem.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"isFilesystem.d.ts","sourceRoot":"","sources":["../../src/utils/isFilesystem.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAEnD;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,GAAG,GAAG,KAAK,IAAI,UAAU,CAO5D"}
1
+ {"version":3,"file":"isFilesystem.d.ts","sourceRoot":"","sources":["../../src/utils/isFilesystem.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,GAAG,WAOtC"}
@@ -1,19 +1,14 @@
1
1
  import type { AnyApiDefinitionFormat, Filesystem, LoadResult, ThrowOnErrorOption } from '../../types/index.ts';
2
2
  export type LoadPlugin = {
3
- priority?: number;
4
3
  check: (value?: any) => boolean;
5
- get: (value: any, source?: string) => any;
6
- /**
7
- * @deprecated Use `getUri` instead
8
- */
4
+ get: (value: any) => any;
9
5
  resolvePath?: (value: any, reference: string) => string;
10
- getUri?: (value: any, source?: string) => string;
11
6
  getDir?: (value: any) => string;
12
7
  getFilename?: (value: any) => string;
13
8
  };
14
9
  export type LoadOptions = {
15
10
  plugins?: LoadPlugin[];
16
- source?: string | undefined;
11
+ filename?: string;
17
12
  filesystem?: Filesystem;
18
13
  } & ThrowOnErrorOption;
19
14
  /**
@@ -24,10 +19,6 @@ export type LoadOptions = {
24
19
  *
25
20
  * It builds a filesystem representation of all loaded content and collects any errors
26
21
  * encountered during the process.
27
- *
28
- * Known limitation:
29
- * - TODO: Internal references inside external reference might not work
30
- * - TODO: Protocol-relative URLs don’t work yet
31
22
  */
32
23
  export declare function load(value: AnyApiDefinitionFormat, options?: LoadOptions): Promise<LoadResult>;
33
24
  //# sourceMappingURL=load.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"load.d.ts","sourceRoot":"","sources":["../../../src/utils/load/load.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,sBAAsB,EAGtB,UAAU,EACV,UAAU,EACV,kBAAkB,EACnB,MAAM,kBAAkB,CAAA;AAMzB,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,CAAC,KAAK,CAAC,EAAE,GAAG,KAAK,OAAO,CAAA;IAC/B,GAAG,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,GAAG,CAAA;IACzC;;OAEG;IACH,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,KAAK,MAAM,CAAA;IACvD,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,MAAM,CAAA;IAChD,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,MAAM,CAAA;IAC/B,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,MAAM,CAAA;CACrC,CAAA;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,OAAO,CAAC,EAAE,UAAU,EAAE,CAAA;IACtB,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,UAAU,CAAC,EAAE,UAAU,CAAA;CACxB,GAAG,kBAAkB,CAAA;AAEtB;;;;;;;;;;;;GAYG;AACH,wBAAsB,IAAI,CAAC,KAAK,EAAE,sBAAsB,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAgKpG"}
1
+ {"version":3,"file":"load.d.ts","sourceRoot":"","sources":["../../../src/utils/load/load.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,sBAAsB,EAGtB,UAAU,EACV,UAAU,EACV,kBAAkB,EACnB,MAAM,sBAAsB,CAAA;AAM7B,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE,CAAC,KAAK,CAAC,EAAE,GAAG,KAAK,OAAO,CAAA;IAC/B,GAAG,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,GAAG,CAAA;IACxB,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,KAAK,MAAM,CAAA;IACvD,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,MAAM,CAAA;IAC/B,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,MAAM,CAAA;CACrC,CAAA;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,OAAO,CAAC,EAAE,UAAU,EAAE,CAAA;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,UAAU,CAAA;CACxB,GAAG,kBAAkB,CAAA;AAEtB;;;;;;;;GAQG;AACH,wBAAsB,IAAI,CAAC,KAAK,EAAE,sBAAsB,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAyHpG"}
@@ -1,7 +1,7 @@
1
1
  import { ERRORS } from '../../configuration/index.js';
2
2
  import { getEntrypoint } from '../getEntrypoint.js';
3
3
  import { getListOfReferences } from '../getListOfReferences.js';
4
- import { makeFilesystemEntry } from '../makeFilesystem.js';
4
+ import { makeFilesystem } from '../makeFilesystem.js';
5
5
  import { normalize } from '../normalize.js';
6
6
 
7
7
  /**
@@ -12,39 +12,25 @@ import { normalize } from '../normalize.js';
12
12
  *
13
13
  * It builds a filesystem representation of all loaded content and collects any errors
14
14
  * encountered during the process.
15
- *
16
- * Known limitation:
17
- * - TODO: Internal references inside external reference might not work
18
- * - TODO: Protocol-relative URLs don’t work yet
19
15
  */
20
16
  async function load(value, options) {
21
17
  const errors = [];
22
- const filesystem = [...(options?.filesystem ?? [])];
23
- // Don't load a reference twice, check the filesystem before fetching something
24
- if (filesystem.find((entry) => entry.uri === options?.source)) {
18
+ // Don’t load a reference twice, check the filesystem before fetching something
19
+ if (options?.filesystem?.find((entry) => entry.filename === value)) {
25
20
  return {
26
- specification: getEntrypoint(filesystem)?.content,
27
- filesystem,
21
+ specification: getEntrypoint(options.filesystem)?.specification,
22
+ filesystem: options.filesystem,
28
23
  errors,
29
24
  };
30
25
  }
26
+ // Check whether the value is an URL or file path
27
+ const plugin = options?.plugins?.find((thisPlugin) => thisPlugin.check(value));
31
28
  let content;
32
- let uri;
33
- // Check whether the value is an file or URL
34
- const plugin = sortPlugins(options?.plugins)?.find((thisPlugin) => thisPlugin.check(value));
35
- if (options?.source) {
36
- uri = options.source;
37
- }
38
- // Seems to be a file or URL
39
29
  if (plugin) {
40
30
  try {
41
- // Get the absolute URI/path
42
- uri = plugin.getUri(value, options?.source);
43
- // Fetch/read the content
44
- content = normalize(await plugin.get(uri));
31
+ content = normalize(await plugin.get(value));
45
32
  }
46
33
  catch (_error) {
47
- // Couldn’t fetch/read the content
48
34
  if (options?.throwOnError) {
49
35
  throw new Error(ERRORS.EXTERNAL_REFERENCE_NOT_FOUND.replace('%s', value));
50
36
  }
@@ -54,16 +40,15 @@ async function load(value, options) {
54
40
  });
55
41
  return {
56
42
  specification: null,
57
- filesystem,
43
+ filesystem: [],
58
44
  errors,
59
45
  };
60
46
  }
61
47
  }
62
48
  else {
63
- // No plugin found, so it’s just the content, I guess.
64
49
  content = normalize(value);
65
50
  }
66
- // Oops, no content
51
+ // No content
67
52
  if (content === undefined) {
68
53
  if (options?.throwOnError) {
69
54
  throw new Error('No content to load');
@@ -74,85 +59,61 @@ async function load(value, options) {
74
59
  });
75
60
  return {
76
61
  specification: null,
77
- filesystem,
62
+ filesystem: [],
78
63
  errors,
79
64
  };
80
65
  }
81
- const entryExistsAlready = options?.filesystem?.find((entry) => uri && entry.uri === uri);
82
- if (entryExistsAlready) {
83
- return {
84
- specification: getEntrypoint(filesystem)?.content,
85
- filesystem,
86
- errors,
87
- };
88
- }
89
- // Get all external references from the content
90
- const listOfReferences = getListOfReferences(content);
91
- const source =
92
- // A given URL/path
93
- options?.source ??
94
- // The reference that we come from
95
- (typeof value === 'string'
96
- ? value
97
- : // Nothing
98
- undefined);
99
- // Map the references to their absolute URIs
100
- const mapOfReferences = listOfReferences.reduce((acc, reference) => {
101
- const plugin = sortPlugins(options?.plugins)?.find((p) => p.check(reference));
102
- const absoluteUri = plugin?.getUri(reference, source);
103
- return { ...acc, [reference]: absoluteUri };
104
- }, {});
105
- const entry = makeFilesystemEntry(content, {
106
- isEntrypoint: false,
107
- uri,
108
- references: mapOfReferences,
66
+ let filesystem = makeFilesystem(content, {
67
+ filename: options?.filename ?? null,
109
68
  });
110
- if (!filesystem.find((entry) => entry.uri === uri)) {
111
- filesystem.push({
112
- ...entry,
113
- isEntrypoint: filesystem.length === 0,
114
- });
115
- }
69
+ // Get references from file system entry, or from the content
70
+ const newEntry = options?.filename
71
+ ? filesystem.find((entry) => entry.filename === options?.filename)
72
+ : getEntrypoint(filesystem);
73
+ const listOfReferences = newEntry.references ?? getListOfReferences(content);
116
74
  // No other references
117
75
  if (listOfReferences.length === 0) {
118
76
  return {
119
- specification: entry.content,
77
+ specification: getEntrypoint(filesystem)?.specification,
120
78
  filesystem,
121
79
  errors,
122
80
  };
123
81
  }
124
82
  // Load other external references
125
83
  for (const reference of listOfReferences) {
126
- // Work with the absolute URI
127
- const absoluteUri = mapOfReferences[reference];
128
84
  // Find a matching plugin
129
- const otherPlugin = sortPlugins(options?.plugins)?.find((thisPlugin) => thisPlugin.check(absoluteUri));
130
- // Skip if no plugin is found (internal references don't need a plugin for example)
85
+ const otherPlugin = options?.plugins?.find((thisPlugin) => thisPlugin.check(reference));
86
+ // Skip if no plugin is found (internal references don’t need a plugin for example)
131
87
  if (!otherPlugin) {
132
88
  continue;
133
89
  }
134
- // Don't load a reference twice, check the filesystem before fetching something
135
- if (options?.filesystem?.find((entry) => entry.uri === absoluteUri)) {
90
+ const target = otherPlugin.check(reference) && otherPlugin.resolvePath ? otherPlugin.resolvePath(value, reference) : reference;
91
+ // Don’t load a reference twice, check the filesystem before fetching something
92
+ if (filesystem.find((entry) => entry.filename === reference)) {
136
93
  continue;
137
94
  }
138
- const { filesystem: referencedFiles, errors: newErrors } = await load(absoluteUri, {
95
+ const { filesystem: referencedFiles, errors: newErrors } = await load(target, {
139
96
  ...options,
140
- source: absoluteUri,
141
- filesystem,
97
+ // Make the filename the exact same value as the $ref
98
+ // TODO: This leads to problems, if there are multiple references with the same file name but in different folders
99
+ filename: reference,
142
100
  });
143
101
  errors.push(...newErrors);
144
- referencedFiles
145
- .filter((file) => !filesystem.find((entry) => entry.uri === file.uri))
146
- .forEach((file) => filesystem.push(file));
102
+ filesystem = [
103
+ ...filesystem,
104
+ ...referencedFiles.map((file) => {
105
+ return {
106
+ ...file,
107
+ isEntrypoint: false,
108
+ };
109
+ }),
110
+ ];
147
111
  }
148
112
  return {
149
- specification: entry.content,
113
+ specification: getEntrypoint(filesystem)?.specification,
150
114
  filesystem,
151
115
  errors,
152
116
  };
153
117
  }
154
- function sortPlugins(plugins = []) {
155
- return plugins?.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
156
- }
157
118
 
158
119
  export { load };
@@ -1,20 +1,3 @@
1
1
  import type { AnyObject, Filesystem, FilesystemEntry } from '../types/index.ts';
2
- export declare function makeFilesystem(
3
- /**
4
- * Pass whatever you have, it will be normalized and then used as the content.
5
- */
6
- value: string | AnyObject | Filesystem | FilesystemEntry,
7
- /**
8
- * If you know better, you can overwrite the default values.
9
- */
10
- overwrites?: Partial<FilesystemEntry> & (FilesystemEntry['references'] | {})): Filesystem;
11
- export declare function makeFilesystemEntry(
12
- /**
13
- * Pass whatever you have, it will be normalized and then used as the content.
14
- */
15
- value: string | AnyObject | Filesystem,
16
- /**
17
- * If you know better, you can overwrite the default values.
18
- */
19
- overwrites?: Partial<FilesystemEntry> & (FilesystemEntry['references'] | {})): FilesystemEntry;
2
+ export declare function makeFilesystem(value: string | AnyObject | Filesystem, overwrites?: Partial<FilesystemEntry>): Filesystem;
20
3
  //# sourceMappingURL=makeFilesystem.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"makeFilesystem.d.ts","sourceRoot":"","sources":["../../src/utils/makeFilesystem.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAI/E,wBAAgB,cAAc;AAC5B;;GAEG;AACH,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,GAAG,eAAe;AACxD;;GAEG;AACH,UAAU,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,CAAC,eAAe,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC,GAC3E,UAAU,CA4BZ;AAED,wBAAgB,mBAAmB;AACjC;;GAEG;AACH,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU;AACtC;;GAEG;AACH,UAAU,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,CAAC,eAAe,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC,GAC3E,eAAe,CAmBjB"}
1
+ {"version":3,"file":"makeFilesystem.d.ts","sourceRoot":"","sources":["../../src/utils/makeFilesystem.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAK/E,wBAAgB,cAAc,CAC5B,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,EACtC,UAAU,GAAE,OAAO,CAAC,eAAe,CAAM,GACxC,UAAU,CAoBZ"}