@speclynx/apidom-reference 3.0.0 → 3.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.
Files changed (53) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +97 -0
  3. package/dist/apidom-reference.browser.js +3862 -3241
  4. package/dist/apidom-reference.browser.min.js +1 -1
  5. package/package.json +48 -25
  6. package/src/dereference/index.cjs +4 -0
  7. package/src/dereference/index.mjs +4 -0
  8. package/src/dereference/strategies/apidom/visitor.cjs +139 -59
  9. package/src/dereference/strategies/apidom/visitor.mjs +142 -62
  10. package/src/dereference/strategies/arazzo-1/index.cjs +1 -4
  11. package/src/dereference/strategies/arazzo-1/index.mjs +2 -4
  12. package/src/dereference/strategies/arazzo-1/visitor.cjs +289 -199
  13. package/src/dereference/strategies/arazzo-1/visitor.mjs +292 -203
  14. package/src/dereference/strategies/asyncapi-2/index.cjs +1 -4
  15. package/src/dereference/strategies/asyncapi-2/index.mjs +2 -4
  16. package/src/dereference/strategies/asyncapi-2/visitor.cjs +325 -229
  17. package/src/dereference/strategies/asyncapi-2/visitor.mjs +328 -233
  18. package/src/dereference/strategies/openapi-2/index.cjs +1 -4
  19. package/src/dereference/strategies/openapi-2/index.mjs +2 -4
  20. package/src/dereference/strategies/openapi-2/visitor.cjs +420 -318
  21. package/src/dereference/strategies/openapi-2/visitor.mjs +425 -324
  22. package/src/dereference/strategies/openapi-3-0/index.cjs +1 -4
  23. package/src/dereference/strategies/openapi-3-0/index.mjs +2 -4
  24. package/src/dereference/strategies/openapi-3-0/visitor.cjs +405 -286
  25. package/src/dereference/strategies/openapi-3-0/visitor.mjs +409 -291
  26. package/src/dereference/strategies/openapi-3-1/index.cjs +1 -4
  27. package/src/dereference/strategies/openapi-3-1/index.mjs +2 -4
  28. package/src/dereference/strategies/openapi-3-1/visitor.cjs +598 -484
  29. package/src/dereference/strategies/openapi-3-1/visitor.mjs +602 -489
  30. package/src/errors/DereferenceError.cjs +1 -1
  31. package/src/errors/DereferenceError.mjs +2 -2
  32. package/src/errors/ResolveError.cjs +1 -1
  33. package/src/errors/ResolveError.mjs +2 -2
  34. package/src/errors/UnresolvableReferenceError.cjs +11 -0
  35. package/src/errors/UnresolvableReferenceError.mjs +6 -0
  36. package/src/index.cjs +3 -1
  37. package/src/index.mjs +1 -0
  38. package/src/options/index.cjs +10 -1
  39. package/src/options/index.mjs +10 -1
  40. package/src/util/plugins.cjs +1 -6
  41. package/src/util/plugins.mjs +2 -5
  42. package/types/apidom-reference.d.ts +10 -2
  43. package/types/dereference/strategies/apidom/visitor.d.ts +10 -0
  44. package/types/dereference/strategies/arazzo-1/visitor.d.ts +19 -5
  45. package/types/dereference/strategies/asyncapi-2/visitor.d.ts +21 -7
  46. package/types/dereference/strategies/openapi-2/visitor.d.ts +21 -8
  47. package/types/dereference/strategies/openapi-3-0/visitor.d.ts +21 -7
  48. package/types/dereference/strategies/openapi-3-1/visitor.d.ts +21 -7
  49. package/types/errors/DereferenceError.d.ts +2 -2
  50. package/types/errors/ResolveError.d.ts +2 -2
  51. package/types/errors/UnresolvableReferenceError.d.ts +7 -0
  52. package/types/index.d.ts +1 -0
  53. package/types/options/index.d.ts +2 -0
@@ -6,5 +6,5 @@ var _apidomError = require("@speclynx/apidom-error");
6
6
  /**
7
7
  * @public
8
8
  */
9
- class DereferenceError extends _apidomError.ApiDOMError {}
9
+ class DereferenceError extends _apidomError.ApiDOMStructuredError {}
10
10
  var _default = exports.default = DereferenceError;
@@ -1,7 +1,7 @@
1
- import { ApiDOMError } from '@speclynx/apidom-error';
1
+ import { ApiDOMStructuredError } from '@speclynx/apidom-error';
2
2
 
3
3
  /**
4
4
  * @public
5
5
  */
6
- class DereferenceError extends ApiDOMError {}
6
+ class DereferenceError extends ApiDOMStructuredError {}
7
7
  export default DereferenceError;
@@ -6,5 +6,5 @@ var _apidomError = require("@speclynx/apidom-error");
6
6
  /**
7
7
  * @public
8
8
  */
9
- class ResolveError extends _apidomError.ApiDOMError {}
9
+ class ResolveError extends _apidomError.ApiDOMStructuredError {}
10
10
  var _default = exports.default = ResolveError;
@@ -1,7 +1,7 @@
1
- import { ApiDOMError } from '@speclynx/apidom-error';
1
+ import { ApiDOMStructuredError } from '@speclynx/apidom-error';
2
2
 
3
3
  /**
4
4
  * @public
5
5
  */
6
- class ResolveError extends ApiDOMError {}
6
+ class ResolveError extends ApiDOMStructuredError {}
7
7
  export default ResolveError;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault").default;
4
+ exports.__esModule = true;
5
+ exports.default = void 0;
6
+ var _DereferenceError = _interopRequireDefault(require("./DereferenceError.cjs"));
7
+ /**
8
+ * @public
9
+ */
10
+ class UnresolvableReferenceError extends _DereferenceError.default {}
11
+ var _default = exports.default = UnresolvableReferenceError;
@@ -0,0 +1,6 @@
1
+ import DereferenceError from "./DereferenceError.mjs";
2
+ /**
3
+ * @public
4
+ */
5
+ class UnresolvableReferenceError extends DereferenceError {}
6
+ export default UnresolvableReferenceError;
package/src/index.cjs CHANGED
@@ -3,7 +3,7 @@
3
3
  var _interopRequireWildcard = require("@babel/runtime-corejs3/helpers/interopRequireWildcard").default;
4
4
  var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault").default;
5
5
  exports.__esModule = true;
6
- exports.url = exports.resolveApiDOM = exports.resolve = exports.readFile = exports.parse = exports.options = exports.mergeOptions = exports.dereferenceApiDOM = exports.dereference = exports.bundle = exports.UnmatchedResolverError = exports.UnmatchedResolveStrategyError = exports.UnmatchedParserError = exports.UnmatchedDereferenceStrategyError = exports.UnmatchedBundleStrategyError = exports.ResolverError = exports.Resolver = exports.ResolveStrategy = exports.ResolveError = exports.Reference = exports.PluginError = exports.ParserError = exports.Parser = exports.ParseError = exports.MaximumResolveDepthError = exports.MaximumDereferenceDepthError = exports.MaximumBundleDepthError = exports.JsonSchemaURIError = exports.JsonSchema$anchorError = exports.InvalidJsonSchema$anchorError = exports.HTTPResolver = exports.EvaluationJsonSchemaUriError = exports.EvaluationJsonSchema$anchorError = exports.EvaluationElementIdError = exports.DereferenceStrategy = exports.DereferenceError = exports.DereferenceAncestorLineage = exports.BundleStrategy = exports.BundleError = void 0;
6
+ exports.url = exports.resolveApiDOM = exports.resolve = exports.readFile = exports.parse = exports.options = exports.mergeOptions = exports.dereferenceApiDOM = exports.dereference = exports.bundle = exports.UnresolvableReferenceError = exports.UnmatchedResolverError = exports.UnmatchedResolveStrategyError = exports.UnmatchedParserError = exports.UnmatchedDereferenceStrategyError = exports.UnmatchedBundleStrategyError = exports.ResolverError = exports.Resolver = exports.ResolveStrategy = exports.ResolveError = exports.Reference = exports.PluginError = exports.ParserError = exports.Parser = exports.ParseError = exports.MaximumResolveDepthError = exports.MaximumDereferenceDepthError = exports.MaximumBundleDepthError = exports.JsonSchemaURIError = exports.JsonSchema$anchorError = exports.InvalidJsonSchema$anchorError = exports.HTTPResolver = exports.EvaluationJsonSchemaUriError = exports.EvaluationJsonSchema$anchorError = exports.EvaluationElementIdError = exports.DereferenceStrategy = exports.DereferenceError = exports.DereferenceAncestorLineage = exports.BundleStrategy = exports.BundleError = void 0;
7
7
  var _File = _interopRequireDefault(require("./File.cjs"));
8
8
  exports.File = _File.default;
9
9
  var _ReferenceSet = _interopRequireDefault(require("./ReferenceSet.cjs"));
@@ -43,6 +43,8 @@ var _UnmatchedBundleStrategyError = _interopRequireDefault(require("./errors/Unm
43
43
  exports.UnmatchedBundleStrategyError = _UnmatchedBundleStrategyError.default;
44
44
  var _DereferenceError = _interopRequireDefault(require("./errors/DereferenceError.cjs"));
45
45
  exports.DereferenceError = _DereferenceError.default;
46
+ var _UnresolvableReferenceError = _interopRequireDefault(require("./errors/UnresolvableReferenceError.cjs"));
47
+ exports.UnresolvableReferenceError = _UnresolvableReferenceError.default;
46
48
  var _EvaluationElementIdError = _interopRequireDefault(require("./errors/EvaluationElementIdError.cjs"));
47
49
  exports.EvaluationElementIdError = _EvaluationElementIdError.default;
48
50
  var _EvaluationJsonSchema$anchorError = _interopRequireDefault(require("./errors/EvaluationJsonSchema$anchorError.cjs"));
package/src/index.mjs CHANGED
@@ -25,6 +25,7 @@ export { default as BundleError } from "./errors/BundleError.mjs";
25
25
  export { default as MaximumBundleDepthError } from "./errors/MaximumBundleDepthError.mjs";
26
26
  export { default as UnmatchedBundleStrategyError } from "./errors/UnmatchedBundleStrategyError.mjs";
27
27
  export { default as DereferenceError } from "./errors/DereferenceError.mjs";
28
+ export { default as UnresolvableReferenceError } from "./errors/UnresolvableReferenceError.mjs";
28
29
  export { default as EvaluationElementIdError } from "./errors/EvaluationElementIdError.mjs";
29
30
  export { default as EvaluationJsonSchema$anchorError } from "./errors/EvaluationJsonSchema$anchorError.mjs";
30
31
  export { default as EvaluationJsonSchemaUriError } from "./errors/EvaluationJsonSchemaUriError.mjs";
@@ -150,7 +150,16 @@ const defaultOptions = {
150
150
  * true - the dereferencing process will be immutable (deep cloning of ApiDOM is involved)
151
151
  * false - the dereferencing process will be mutable
152
152
  */
153
- immutable: true
153
+ immutable: true,
154
+ /**
155
+ * Controls error handling during dereferencing.
156
+ *
157
+ * false - fail fast, throw on first error (default)
158
+ * true - skip unresolvable references silently, continue dereferencing
159
+ * (error) => void - callback invoked for each error; if the callback
160
+ * itself throws, dereferencing stops with that error
161
+ */
162
+ continueOnError: false
154
163
  },
155
164
  bundle: {
156
165
  /**
@@ -147,7 +147,16 @@ const defaultOptions = {
147
147
  * true - the dereferencing process will be immutable (deep cloning of ApiDOM is involved)
148
148
  * false - the dereferencing process will be mutable
149
149
  */
150
- immutable: true
150
+ immutable: true,
151
+ /**
152
+ * Controls error handling during dereferencing.
153
+ *
154
+ * false - fail fast, throw on first error (default)
155
+ * true - skip unresolvable references silently, continue dereferencing
156
+ * (error) => void - callback invoked for each error; if the callback
157
+ * itself throws, dereferencing stops with that error
158
+ */
159
+ continueOnError: false
151
160
  },
152
161
  bundle: {
153
162
  /**
@@ -1,10 +1,8 @@
1
1
  "use strict";
2
2
 
3
- var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault").default;
4
3
  exports.__esModule = true;
5
4
  exports.run = exports.filter = void 0;
6
5
  var _ramdaAdjunct = require("ramda-adjunct");
7
- var _PluginError = _interopRequireDefault(require("../errors/PluginError.cjs"));
8
6
  /**
9
7
  * Filters the given plugins, returning only the ones return `true` for the given method.
10
8
  */
@@ -33,10 +31,7 @@ const run = async (method, parameters, plugins) => {
33
31
  result
34
32
  };
35
33
  } catch (error) {
36
- lastError = new _PluginError.default('Error while running plugin', {
37
- cause: error,
38
- plugin
39
- });
34
+ lastError = error;
40
35
  }
41
36
  }
42
37
  return Promise.reject(lastError);
@@ -1,5 +1,5 @@
1
1
  import { invokeArgs } from 'ramda-adjunct';
2
- import PluginError from "../errors/PluginError.mjs";
2
+
3
3
  /**
4
4
  * Filters the given plugins, returning only the ones return `true` for the given method.
5
5
  */
@@ -27,10 +27,7 @@ export const run = async (method, parameters, plugins) => {
27
27
  result
28
28
  };
29
29
  } catch (error) {
30
- lastError = new PluginError('Error while running plugin', {
31
- cause: error,
32
- plugin
33
- });
30
+ lastError = error;
34
31
  }
35
32
  }
36
33
  return Promise.reject(lastError);
@@ -1,4 +1,5 @@
1
1
  import { ApiDOMError } from '@speclynx/apidom-error';
2
+ import { ApiDOMStructuredError } from '@speclynx/apidom-error';
2
3
  import { Element as Element_2 } from '@speclynx/apidom-datamodel';
3
4
  import { ParseResultElement } from '@speclynx/apidom-datamodel';
4
5
  import type { RefElement } from '@speclynx/apidom-datamodel';
@@ -23,6 +24,7 @@ export declare interface ApiDOMReferenceDereferenceOptions {
23
24
  circular: 'ignore' | 'replace' | 'error';
24
25
  circularReplacer: (ref: RefElement) => unknown;
25
26
  immutable: boolean;
27
+ continueOnError: boolean | ((error: UnresolvableReferenceError) => void);
26
28
  }
27
29
 
28
30
  /**
@@ -122,7 +124,7 @@ export declare const dereferenceApiDOM: <T extends Element_2>(element: T, option
122
124
  /**
123
125
  * @public
124
126
  */
125
- export declare class DereferenceError extends ApiDOMError {
127
+ export declare class DereferenceError extends ApiDOMStructuredError {
126
128
  }
127
129
 
128
130
  /**
@@ -463,7 +465,7 @@ export declare const resolveApiDOM: <T extends Element_2>(element: T, options?:
463
465
  /**
464
466
  * @public
465
467
  */
466
- export declare class ResolveError extends ApiDOMError {
468
+ export declare class ResolveError extends ApiDOMStructuredError {
467
469
  }
468
470
 
469
471
  /**
@@ -566,6 +568,12 @@ export declare class UnmatchedResolverError extends ResolverError {
566
568
  export declare class UnmatchedResolveStrategyError extends ResolveError {
567
569
  }
568
570
 
571
+ /**
572
+ * @public
573
+ */
574
+ export declare class UnresolvableReferenceError extends DereferenceError {
575
+ }
576
+
569
577
  /**
570
578
  * Unsanitizes/Decodes URI to it's url encoded form.
571
579
  * This function already assumes that hash part of the URI
@@ -28,6 +28,16 @@ declare class ApiDOMDereferenceVisitor {
28
28
  constructor({ reference, options }: ApiDOMDereferenceVisitorOptions);
29
29
  protected toBaseURI(uri: string): string;
30
30
  protected toReference(uri: string): Promise<Reference>;
31
+ /**
32
+ * Handles an error according to the continueOnError option.
33
+ *
34
+ * For new errors: wraps in UnresolvableReferenceError with structured context.
35
+ * For errors already wrapped by a nested visitor: prepends the current hop to the trace.
36
+ *
37
+ * Inner/intermediate visitors always throw to let the trace accumulate.
38
+ * Only the entry document visitor respects continueOnError (callback/swallow/throw).
39
+ */
40
+ protected handleError(message: string, error: Error, referencingElement: Element, refFieldName: string | null, refFieldValue: string, visitorPath: Path<Element>): void;
31
41
  RefElement(path: Path<Element>): Promise<void>;
32
42
  }
33
43
  export default ApiDOMDereferenceVisitor;
@@ -1,4 +1,4 @@
1
- import { Element, Namespace } from '@speclynx/apidom-datamodel';
1
+ import { Element } from '@speclynx/apidom-datamodel';
2
2
  import { Path } from '@speclynx/apidom-traverse';
3
3
  import Reference from '../../../Reference.ts';
4
4
  import { AncestorLineage } from '../../util.ts';
@@ -7,7 +7,6 @@ import type { ReferenceOptions } from '../../../options/index.ts';
7
7
  * @public
8
8
  */
9
9
  export interface Arazzo1DereferenceVisitorOptions {
10
- readonly namespace: Namespace;
11
10
  readonly reference: Reference;
12
11
  readonly options: ReferenceOptions;
13
12
  readonly indirections?: Element[];
@@ -18,14 +17,29 @@ export interface Arazzo1DereferenceVisitorOptions {
18
17
  */
19
18
  declare class Arazzo1DereferenceVisitor {
20
19
  protected readonly indirections: Element[];
21
- protected readonly namespace: Namespace;
22
20
  protected readonly reference: Reference;
23
21
  protected readonly options: ReferenceOptions;
22
+ /**
23
+ * Tracks element ancestors across dive-deep traversal boundaries.
24
+ * Used for cycle detection: if a referenced element is found in
25
+ * the ancestor lineage, a circular reference is detected.
26
+ */
24
27
  protected readonly ancestors: AncestorLineage<Element>;
25
- constructor({ reference, namespace, options, indirections, ancestors, }: Arazzo1DereferenceVisitorOptions);
28
+ constructor({ reference, options, indirections, ancestors, }: Arazzo1DereferenceVisitorOptions);
29
+ protected toAncestorLineage(path: Path<Element>): [AncestorLineage<Element>, Set<Element>];
26
30
  protected toBaseURI(uri: string): string;
27
31
  protected toReference(uri: string): Promise<Reference>;
28
- protected toAncestorLineage(path: Path<Element>): [AncestorLineage<Element>, Set<Element>];
32
+ /**
33
+ * Handles an error according to the continueOnError option.
34
+ *
35
+ * For new errors: wraps in UnresolvableReferenceError with structured context
36
+ * (type, uri, location, codeFrame, refFieldName, refFieldValue, trace).
37
+ * For errors already wrapped by a nested visitor: prepends the current hop to the trace.
38
+ *
39
+ * Inner/intermediate visitors always throw to let the trace accumulate.
40
+ * Only the entry document visitor respects continueOnError (callback/swallow/throw).
41
+ */
42
+ protected handleError(message: string, error: Error, referencingElement: Element, refFieldName: string, refFieldValue: string, visitorPath: Path<Element>): void;
29
43
  ReusableElement(path: Path<Element>): void;
30
44
  JSONSchemaElement(path: Path<Element>): Promise<void>;
31
45
  }
@@ -1,4 +1,4 @@
1
- import { Namespace, Element } from '@speclynx/apidom-datamodel';
1
+ import { Element } from '@speclynx/apidom-datamodel';
2
2
  import { Path } from '@speclynx/apidom-traverse';
3
3
  import { AncestorLineage } from '../../util.ts';
4
4
  import Reference from '../../../Reference.ts';
@@ -7,27 +7,41 @@ import type { ReferenceOptions } from '../../../options/index.ts';
7
7
  * @public
8
8
  */
9
9
  export interface AsyncAPI2DereferenceVisitorOptions {
10
- readonly namespace: Namespace;
11
10
  readonly reference: Reference;
12
11
  readonly options: ReferenceOptions;
13
12
  readonly indirections?: Element[];
13
+ readonly refractCache?: WeakMap<Element, Element>;
14
14
  readonly ancestors?: AncestorLineage<Element>;
15
- readonly refractCache?: Map<string, Element>;
16
15
  }
17
16
  /**
18
17
  * @public
19
18
  */
20
19
  declare class AsyncAPI2DereferenceVisitor {
21
20
  protected readonly indirections: Element[];
22
- protected readonly namespace: Namespace;
23
21
  protected readonly reference: Reference;
24
22
  protected readonly options: ReferenceOptions;
23
+ protected readonly refractCache: WeakMap<Element, Element>;
24
+ /**
25
+ * Tracks element ancestors across dive-deep traversal boundaries.
26
+ * Used for cycle detection: if a referenced element is found in
27
+ * the ancestor lineage, a circular reference is detected.
28
+ */
25
29
  protected readonly ancestors: AncestorLineage<Element>;
26
- protected readonly refractCache: Map<string, Element>;
27
- constructor({ reference, namespace, options, indirections, ancestors, refractCache, }: AsyncAPI2DereferenceVisitorOptions);
30
+ constructor({ reference, options, indirections, ancestors, refractCache, }: AsyncAPI2DereferenceVisitorOptions);
31
+ protected toAncestorLineage(path: Path<Element>): [AncestorLineage<Element>, Set<Element>];
28
32
  protected toBaseURI(uri: string): string;
29
33
  protected toReference(uri: string): Promise<Reference>;
30
- protected toAncestorLineage(path: Path<Element>): [AncestorLineage<Element>, Set<Element>];
34
+ /**
35
+ * Handles an error according to the continueOnError option.
36
+ *
37
+ * For new errors: wraps in UnresolvableReferenceError with structured context
38
+ * (type, uri, location, codeFrame, refFieldName, refFieldValue, trace).
39
+ * For errors already wrapped by a nested visitor: prepends the current hop to the trace.
40
+ *
41
+ * Inner/intermediate visitors always throw to let the trace accumulate.
42
+ * Only the entry document visitor respects continueOnError (callback/swallow/throw).
43
+ */
44
+ protected handleError(message: string, error: Error, referencingElement: Element, refFieldName: string, refFieldValue: string, visitorPath: Path<Element>): void;
31
45
  ReferenceElement(path: Path<Element>): Promise<void>;
32
46
  ChannelItemElement(path: Path<Element>): Promise<void>;
33
47
  }
@@ -1,34 +1,47 @@
1
- import { Element, Namespace } from '@speclynx/apidom-datamodel';
1
+ import { Element } from '@speclynx/apidom-datamodel';
2
2
  import { Path } from '@speclynx/apidom-traverse';
3
3
  import { AncestorLineage } from '../../util.ts';
4
4
  import Reference from '../../../Reference.ts';
5
5
  import type { ReferenceOptions } from '../../../options/index.ts';
6
- import { AsyncAPI2DereferenceVisitorOptions } from '../asyncapi-2/visitor.ts';
7
6
  /**
8
7
  * @public
9
8
  */
10
9
  export interface OpenAPI2DereferenceVisitorOptions {
11
- readonly namespace: Namespace;
12
10
  readonly reference: Reference;
13
11
  readonly options: ReferenceOptions;
14
12
  readonly indirections?: Element[];
13
+ readonly refractCache?: WeakMap<Element, Element>;
15
14
  readonly ancestors?: AncestorLineage<Element>;
16
- readonly refractCache?: Map<string, Element>;
17
15
  }
18
16
  /**
19
17
  * @public
20
18
  */
21
19
  declare class OpenAPI2DereferenceVisitor {
22
20
  protected readonly indirections: Element[];
23
- protected readonly namespace: Namespace;
24
21
  protected readonly reference: Reference;
25
22
  protected readonly options: ReferenceOptions;
23
+ protected readonly refractCache: WeakMap<Element, Element>;
24
+ /**
25
+ * Tracks element ancestors across dive-deep traversal boundaries.
26
+ * Used for cycle detection: if a referenced element is found in
27
+ * the ancestor lineage, a circular reference is detected.
28
+ */
26
29
  protected readonly ancestors: AncestorLineage<Element>;
27
- protected readonly refractCache: Map<string, Element>;
28
- constructor({ reference, namespace, options, indirections, ancestors, refractCache, }: AsyncAPI2DereferenceVisitorOptions);
30
+ constructor({ reference, options, indirections, ancestors, refractCache, }: OpenAPI2DereferenceVisitorOptions);
31
+ protected toAncestorLineage(path: Path<Element>): [AncestorLineage<Element>, Set<Element>];
29
32
  protected toBaseURI(uri: string): string;
30
33
  protected toReference(uri: string): Promise<Reference>;
31
- protected toAncestorLineage(path: Path<Element>): [AncestorLineage<Element>, Set<Element>];
34
+ /**
35
+ * Handles an error according to the continueOnError option.
36
+ *
37
+ * For new errors: wraps in UnresolvableReferenceError with structured context
38
+ * (type, uri, location, codeFrame, refFieldName, refFieldValue, trace).
39
+ * For errors already wrapped by a nested visitor: prepends the current hop to the trace.
40
+ *
41
+ * Inner/intermediate visitors always throw to let the trace accumulate.
42
+ * Only the entry document visitor respects continueOnError (callback/swallow/throw).
43
+ */
44
+ protected handleError(message: string, error: Error, referencingElement: Element, refFieldName: string, refFieldValue: string, visitorPath: Path<Element>): void;
32
45
  ReferenceElement(path: Path<Element>): Promise<void>;
33
46
  PathItemElement(path: Path<Element>): Promise<void>;
34
47
  JSONReferenceElement(path: Path<Element>): Promise<void>;
@@ -1,4 +1,4 @@
1
- import { Element, Namespace } from '@speclynx/apidom-datamodel';
1
+ import { Element } from '@speclynx/apidom-datamodel';
2
2
  import { Path } from '@speclynx/apidom-traverse';
3
3
  import Reference from '../../../Reference.ts';
4
4
  import { AncestorLineage } from '../../util.ts';
@@ -7,27 +7,41 @@ import type { ReferenceOptions } from '../../../options/index.ts';
7
7
  * @public
8
8
  */
9
9
  export interface OpenAPI3_0DereferenceVisitorOptions {
10
- readonly namespace: Namespace;
11
10
  readonly reference: Reference;
12
11
  readonly options: ReferenceOptions;
13
12
  readonly indirections?: Element[];
13
+ readonly refractCache?: WeakMap<Element, Element>;
14
14
  readonly ancestors?: AncestorLineage<Element>;
15
- readonly refractCache?: Map<string, Element>;
16
15
  }
17
16
  /**
18
17
  * @public
19
18
  */
20
19
  declare class OpenAPI3_0DereferenceVisitor {
21
20
  protected readonly indirections: Element[];
22
- protected readonly namespace: Namespace;
23
21
  protected readonly reference: Reference;
24
22
  protected readonly options: ReferenceOptions;
23
+ protected readonly refractCache: WeakMap<Element, Element>;
24
+ /**
25
+ * Tracks element ancestors across dive-deep traversal boundaries.
26
+ * Used for cycle detection: if a referenced element is found in
27
+ * the ancestor lineage, a circular reference is detected.
28
+ */
25
29
  protected readonly ancestors: AncestorLineage<Element>;
26
- protected readonly refractCache: Map<string, Element>;
27
- constructor({ reference, namespace, options, indirections, ancestors, refractCache, }: OpenAPI3_0DereferenceVisitorOptions);
30
+ constructor({ reference, options, indirections, ancestors, refractCache, }: OpenAPI3_0DereferenceVisitorOptions);
31
+ protected toAncestorLineage(path: Path<Element>): [AncestorLineage<Element>, Set<Element>];
28
32
  protected toBaseURI(uri: string): string;
29
33
  protected toReference(uri: string): Promise<Reference>;
30
- protected toAncestorLineage(path: Path<Element>): [AncestorLineage<Element>, Set<Element>];
34
+ /**
35
+ * Handles an error according to the continueOnError option.
36
+ *
37
+ * For new errors: wraps in UnresolvableReferenceError with structured context
38
+ * (type, uri, location, codeFrame, refFieldName, refFieldValue, trace).
39
+ * For errors already wrapped by a nested visitor: prepends the current hop to the trace.
40
+ *
41
+ * Inner/intermediate visitors always throw to let the trace accumulate.
42
+ * Only the entry document visitor respects continueOnError (callback/swallow/throw).
43
+ */
44
+ protected handleError(message: string, error: Error, referencingElement: Element, refFieldName: string, refFieldValue: string, visitorPath: Path<Element>): void;
31
45
  ReferenceElement(path: Path<Element>): Promise<void>;
32
46
  PathItemElement(path: Path<Element>): Promise<void>;
33
47
  LinkElement(path: Path<Element>): Promise<void>;
@@ -1,4 +1,4 @@
1
- import { Element, Namespace } from '@speclynx/apidom-datamodel';
1
+ import { Element } from '@speclynx/apidom-datamodel';
2
2
  import { Path } from '@speclynx/apidom-traverse';
3
3
  import Reference from '../../../Reference.ts';
4
4
  import { AncestorLineage } from '../../util.ts';
@@ -7,27 +7,41 @@ import type { ReferenceOptions } from '../../../options/index.ts';
7
7
  * @public
8
8
  */
9
9
  export interface OpenAPI3_1DereferenceVisitorOptions {
10
- readonly namespace: Namespace;
11
10
  readonly reference: Reference;
12
11
  readonly options: ReferenceOptions;
13
12
  readonly indirections?: Element[];
13
+ readonly refractCache?: WeakMap<Element, Element>;
14
14
  readonly ancestors?: AncestorLineage<Element>;
15
- readonly refractCache?: Map<string, Element>;
16
15
  }
17
16
  /**
18
17
  * @public
19
18
  */
20
19
  declare class OpenAPI3_1DereferenceVisitor {
21
20
  protected readonly indirections: Element[];
22
- protected readonly namespace: Namespace;
23
21
  protected readonly reference: Reference;
24
22
  protected readonly options: ReferenceOptions;
23
+ protected readonly refractCache: WeakMap<Element, Element>;
24
+ /**
25
+ * Tracks element ancestors across dive-deep traversal boundaries.
26
+ * Used for cycle detection: if a referenced element is found in
27
+ * the ancestor lineage, a circular reference is detected.
28
+ */
25
29
  protected readonly ancestors: AncestorLineage<Element>;
26
- protected readonly refractCache: Map<string, Element>;
27
- constructor({ reference, namespace, options, indirections, ancestors, refractCache, }: OpenAPI3_1DereferenceVisitorOptions);
30
+ constructor({ reference, options, indirections, refractCache, ancestors, }: OpenAPI3_1DereferenceVisitorOptions);
31
+ protected toAncestorLineage(path: Path<Element>): [AncestorLineage<Element>, Set<Element>];
28
32
  protected toBaseURI(uri: string): string;
29
33
  protected toReference(uri: string): Promise<Reference>;
30
- protected toAncestorLineage(path: Path<Element>): [AncestorLineage<Element>, Set<Element>];
34
+ /**
35
+ * Handles an error according to the continueOnError option.
36
+ *
37
+ * For new errors: wraps in UnresolvableReferenceError with structured context
38
+ * (type, uri, location, codeFrame, refFieldName, refFieldValue, trace).
39
+ * For errors already wrapped by a nested visitor: prepends the current hop to the trace.
40
+ *
41
+ * Inner/intermediate visitors always throw to let the trace accumulate.
42
+ * Only the entry document visitor respects continueOnError (callback/swallow/throw).
43
+ */
44
+ protected handleError(message: string, error: Error, referencingElement: Element, refFieldName: string, refFieldValue: string, visitorPath: Path<Element>): void;
31
45
  ReferenceElement(path: Path<Element>): Promise<void>;
32
46
  PathItemElement(path: Path<Element>): Promise<void>;
33
47
  LinkElement(path: Path<Element>): Promise<void>;
@@ -1,7 +1,7 @@
1
- import { ApiDOMError } from '@speclynx/apidom-error';
1
+ import { ApiDOMStructuredError } from '@speclynx/apidom-error';
2
2
  /**
3
3
  * @public
4
4
  */
5
- declare class DereferenceError extends ApiDOMError {
5
+ declare class DereferenceError extends ApiDOMStructuredError {
6
6
  }
7
7
  export default DereferenceError;
@@ -1,7 +1,7 @@
1
- import { ApiDOMError } from '@speclynx/apidom-error';
1
+ import { ApiDOMStructuredError } from '@speclynx/apidom-error';
2
2
  /**
3
3
  * @public
4
4
  */
5
- declare class ResolveError extends ApiDOMError {
5
+ declare class ResolveError extends ApiDOMStructuredError {
6
6
  }
7
7
  export default ResolveError;
@@ -0,0 +1,7 @@
1
+ import DereferenceError from './DereferenceError.ts';
2
+ /**
3
+ * @public
4
+ */
5
+ declare class UnresolvableReferenceError extends DereferenceError {
6
+ }
7
+ export default UnresolvableReferenceError;
package/types/index.d.ts CHANGED
@@ -29,6 +29,7 @@ export { default as BundleError } from './errors/BundleError.ts';
29
29
  export { default as MaximumBundleDepthError } from './errors/MaximumBundleDepthError.ts';
30
30
  export { default as UnmatchedBundleStrategyError } from './errors/UnmatchedBundleStrategyError.ts';
31
31
  export { default as DereferenceError } from './errors/DereferenceError.ts';
32
+ export { default as UnresolvableReferenceError } from './errors/UnresolvableReferenceError.ts';
32
33
  export { default as EvaluationElementIdError } from './errors/EvaluationElementIdError.ts';
33
34
  export { default as EvaluationJsonSchema$anchorError } from './errors/EvaluationJsonSchema$anchorError.ts';
34
35
  export { default as EvaluationJsonSchemaUriError } from './errors/EvaluationJsonSchemaUriError.ts';
@@ -5,6 +5,7 @@ import type ResolveStrategy from '../resolve/strategies/ResolveStrategy.ts';
5
5
  import type DereferenceStrategy from '../dereference/strategies/DereferenceStrategy.ts';
6
6
  import type ReferenceSet from '../ReferenceSet.ts';
7
7
  import type BundleStrategy from '../bundle/strategies/BundleStrategy.ts';
8
+ import type UnresolvableReferenceError from '../errors/UnresolvableReferenceError.ts';
8
9
  /**
9
10
  * @public
10
11
  */
@@ -37,6 +38,7 @@ export interface ReferenceDereferenceOptions {
37
38
  circular: 'ignore' | 'replace' | 'error';
38
39
  circularReplacer: (ref: RefElement) => unknown;
39
40
  immutable: boolean;
41
+ continueOnError: boolean | ((error: UnresolvableReferenceError) => void);
40
42
  }
41
43
  /**
42
44
  * @public