@speclynx/apidom-reference 2.8.0 → 2.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.
@@ -33,7 +33,10 @@ async function parseSourceDescription(sourceDescription, ctx) {
33
33
  parseResult.push(annotation);
34
34
  return parseResult;
35
35
  }
36
- const retrievalURI = url.resolve(ctx.baseURI, sourceDescriptionURI);
36
+
37
+ // normalize URI for consistent cycle detection and cache key matching
38
+ const retrievalURI = url.sanitize(url.stripHash(url.resolve(ctx.baseURI, sourceDescriptionURI)));
39
+ parseResult.setMetaProperty('retrievalURI', retrievalURI);
37
40
 
38
41
  // skip if already visited (cycle detection)
39
42
  if (ctx.visitedUrls.has(retrievalURI)) {
@@ -49,6 +52,9 @@ async function parseSourceDescription(sourceDescription, ctx) {
49
52
  mediaType: 'text/plain',
50
53
  // allow parser plugin detection
51
54
  parserOpts: {
55
+ // nested documents should parse all their source descriptions
56
+ // (parent's name filter doesn't apply to nested documents)
57
+ sourceDescriptions: true,
52
58
  [ARAZZO_RECURSION_KEY]: {
53
59
  sourceDescriptionsDepth: ctx.currentDepth + 1,
54
60
  sourceDescriptionsVisitedUrls: ctx.visitedUrls
@@ -101,27 +107,42 @@ async function parseSourceDescription(sourceDescription, ctx) {
101
107
  /**
102
108
  * Parses source descriptions from an Arazzo document's ParseResult.
103
109
  *
110
+ * Each source description result is attached to its corresponding
111
+ * SourceDescriptionElement's meta as 'parseResult' for easy access,
112
+ * regardless of success or failure. On failure, the ParseResultElement
113
+ * contains annotations explaining what went wrong.
114
+ *
104
115
  * @param parseResult - ParseResult containing an Arazzo specification
105
116
  * @param parseResultRetrievalURI - URI from which the parseResult was retrieved
106
- * @param options - Full ReferenceOptions (caller responsibility to construct)
117
+ * @param options - Full ReferenceOptions. Pass `sourceDescriptions` as an array of names
118
+ * in `parse.parserOpts` to filter which source descriptions to process.
107
119
  * @param parserName - Parser name for options lookup (defaults to 'arazzo-json-1')
108
- * @returns Array of ParseResultElements. On success, returns one ParseResultElement per
109
- * source description (each with class 'source-description' and name/type metadata).
120
+ * @returns Array of ParseResultElements. Returns one ParseResultElement per source description
121
+ * (each with class 'source-description' and metadata: name, type, retrievalURI).
110
122
  * May return early with a single-element array containing a warning annotation when:
111
123
  * - The API is not an Arazzo specification
112
124
  * - The sourceDescriptions field is missing or not an array
113
125
  * - Maximum parse depth is exceeded (error annotation)
114
- * Returns an empty array when sourceDescriptions option is disabled or no names match.
126
+ * Returns an empty array when no source description names match the filter.
115
127
  *
116
128
  * @example
117
129
  * ```typescript
130
+ * import { toValue } from '@speclynx/apidom-core';
118
131
  * import { options, mergeOptions } from '@speclynx/apidom-reference';
119
132
  * import { parseSourceDescriptions } from '@speclynx/apidom-reference/parse/parsers/arazzo-json-1';
120
133
  *
121
- * const fullOptions = mergeOptions(options, {
122
- * parse: { parserOpts: { sourceDescriptions: true } }
123
- * });
124
- * const results = await parseSourceDescriptions(parseResult, uri, fullOptions);
134
+ * // Parse all source descriptions
135
+ * const results = await parseSourceDescriptions(parseResult, uri, options);
136
+ *
137
+ * // Filter by name
138
+ * const filtered = await parseSourceDescriptions(parseResult, uri, mergeOptions(options, {
139
+ * parse: { parserOpts: { sourceDescriptions: ['petStore'] } }
140
+ * }));
141
+ *
142
+ * // Access parsed document from source description element
143
+ * const sourceDesc = parseResult.api.sourceDescriptions.get(0);
144
+ * const parsedDoc = sourceDesc.meta.get('parseResult');
145
+ * const retrievalURI = toValue(parsedDoc.meta.get('retrievalURI'));
125
146
  * ```
126
147
  *
127
148
  * @public
@@ -174,13 +195,8 @@ export async function parseSourceDescriptions(parseResult, parseResultRetrievalU
174
195
  visitedUrls
175
196
  };
176
197
 
177
- // determine which source descriptions to parse
198
+ // determine which source descriptions to parse (array filters by name)
178
199
  const sourceDescriptionsOption = options?.parse?.parserOpts?.[parserName]?.sourceDescriptions ?? options?.parse?.parserOpts?.sourceDescriptions;
179
-
180
- // handle false or other falsy values - no source descriptions should be parsed
181
- if (!sourceDescriptionsOption) {
182
- return results;
183
- }
184
200
  const sourceDescriptions = Array.isArray(sourceDescriptionsOption) ? api.sourceDescriptions.filter(sd => {
185
201
  if (!isSourceDescriptionElement(sd)) return false;
186
202
  const name = toValue(sd.name);
@@ -190,6 +206,8 @@ export async function parseSourceDescriptions(parseResult, parseResultRetrievalU
190
206
  // process sequentially to ensure proper cycle detection with shared visitedUrls
191
207
  for (const sourceDescription of sourceDescriptions) {
192
208
  const sourceDescriptionParseResult = await parseSourceDescription(sourceDescription, ctx);
209
+ // always attach result (even on failure - contains annotations)
210
+ sourceDescription.meta.set('parseResult', sourceDescriptionParseResult);
193
211
  results.push(sourceDescriptionParseResult);
194
212
  }
195
213
  return results;
@@ -29,4 +29,5 @@ declare class Arazzo1DereferenceStrategy extends DereferenceStrategy {
29
29
  }
30
30
  export { Arazzo1DereferenceVisitor };
31
31
  export { resolveSchema$refField, resolveSchema$idField, maybeRefractToJSONSchemaElement, } from './util.ts';
32
+ export { dereferenceSourceDescriptions } from './source-descriptions.ts';
32
33
  export default Arazzo1DereferenceStrategy;
@@ -0,0 +1,44 @@
1
+ import { ParseResultElement } from '@speclynx/apidom-datamodel';
2
+ import type { ReferenceOptions } from '../../../options/index.ts';
3
+ /**
4
+ * Dereferences source descriptions from an Arazzo document.
5
+ *
6
+ * Each source description result is attached to its corresponding
7
+ * SourceDescriptionElement's meta as 'parseResult' for easy access,
8
+ * regardless of success or failure. On failure, the ParseResultElement
9
+ * contains annotations explaining what went wrong.
10
+ *
11
+ * @param parseResult - ParseResult containing a parsed (optionally dereferenced) Arazzo specification
12
+ * @param parseResultRetrievalURI - URI from which the parseResult was retrieved
13
+ * @param options - Full ReferenceOptions. Pass `sourceDescriptions` as an array of names
14
+ * in `dereference.strategyOpts` to filter which source descriptions to process.
15
+ * @param strategyName - Strategy name for options lookup (defaults to 'arazzo-1')
16
+ * @returns Array of ParseResultElements. Returns one ParseResultElement per source description
17
+ * (each with class 'source-description' and metadata: name, type, retrievalURI).
18
+ * May return early with a single-element array containing a warning annotation when:
19
+ * - The API is not an Arazzo specification
20
+ * - The sourceDescriptions field is missing or not an array
21
+ * - Maximum dereference depth is exceeded (error annotation)
22
+ * Returns an empty array when no source description names match the filter.
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * import { toValue } from '@speclynx/apidom-core';
27
+ *
28
+ * // Dereference all source descriptions
29
+ * await dereferenceSourceDescriptions(parseResult, uri, options);
30
+ *
31
+ * // Filter by name
32
+ * await dereferenceSourceDescriptions(parseResult, uri, mergeOptions(options, {
33
+ * dereference: { strategyOpts: { sourceDescriptions: ['petStore'] } },
34
+ * }));
35
+ *
36
+ * // Access dereferenced document from source description element
37
+ * const sourceDesc = parseResult.api.sourceDescriptions.get(0);
38
+ * const dereferencedDoc = sourceDesc.meta.get('parseResult');
39
+ * const retrievalURI = toValue(dereferencedDoc.meta.get('retrievalURI'));
40
+ * ```
41
+ *
42
+ * @public
43
+ */
44
+ export declare function dereferenceSourceDescriptions(parseResult: ParseResultElement, parseResultRetrievalURI: string, options: ReferenceOptions, strategyName?: string): Promise<ParseResultElement[]>;
@@ -3,27 +3,42 @@ import type { ReferenceOptions } from '../../../options/index.ts';
3
3
  /**
4
4
  * Parses source descriptions from an Arazzo document's ParseResult.
5
5
  *
6
+ * Each source description result is attached to its corresponding
7
+ * SourceDescriptionElement's meta as 'parseResult' for easy access,
8
+ * regardless of success or failure. On failure, the ParseResultElement
9
+ * contains annotations explaining what went wrong.
10
+ *
6
11
  * @param parseResult - ParseResult containing an Arazzo specification
7
12
  * @param parseResultRetrievalURI - URI from which the parseResult was retrieved
8
- * @param options - Full ReferenceOptions (caller responsibility to construct)
13
+ * @param options - Full ReferenceOptions. Pass `sourceDescriptions` as an array of names
14
+ * in `parse.parserOpts` to filter which source descriptions to process.
9
15
  * @param parserName - Parser name for options lookup (defaults to 'arazzo-json-1')
10
- * @returns Array of ParseResultElements. On success, returns one ParseResultElement per
11
- * source description (each with class 'source-description' and name/type metadata).
16
+ * @returns Array of ParseResultElements. Returns one ParseResultElement per source description
17
+ * (each with class 'source-description' and metadata: name, type, retrievalURI).
12
18
  * May return early with a single-element array containing a warning annotation when:
13
19
  * - The API is not an Arazzo specification
14
20
  * - The sourceDescriptions field is missing or not an array
15
21
  * - Maximum parse depth is exceeded (error annotation)
16
- * Returns an empty array when sourceDescriptions option is disabled or no names match.
22
+ * Returns an empty array when no source description names match the filter.
17
23
  *
18
24
  * @example
19
25
  * ```typescript
26
+ * import { toValue } from '@speclynx/apidom-core';
20
27
  * import { options, mergeOptions } from '@speclynx/apidom-reference';
21
28
  * import { parseSourceDescriptions } from '@speclynx/apidom-reference/parse/parsers/arazzo-json-1';
22
29
  *
23
- * const fullOptions = mergeOptions(options, {
24
- * parse: { parserOpts: { sourceDescriptions: true } }
25
- * });
26
- * const results = await parseSourceDescriptions(parseResult, uri, fullOptions);
30
+ * // Parse all source descriptions
31
+ * const results = await parseSourceDescriptions(parseResult, uri, options);
32
+ *
33
+ * // Filter by name
34
+ * const filtered = await parseSourceDescriptions(parseResult, uri, mergeOptions(options, {
35
+ * parse: { parserOpts: { sourceDescriptions: ['petStore'] } }
36
+ * }));
37
+ *
38
+ * // Access parsed document from source description element
39
+ * const sourceDesc = parseResult.api.sourceDescriptions.get(0);
40
+ * const parsedDoc = sourceDesc.meta.get('parseResult');
41
+ * const retrievalURI = toValue(parsedDoc.meta.get('retrievalURI'));
27
42
  * ```
28
43
  *
29
44
  * @public
@@ -1,8 +0,0 @@
1
- import { ParseResultElement } from '@speclynx/apidom-datamodel';
2
- import Reference from '../../../Reference.ts';
3
- import type { ReferenceOptions } from '../../../options/index.ts';
4
- /**
5
- * Dereferences source descriptions from an Arazzo document.
6
- * @public
7
- */
8
- export declare function dereferenceSourceDescriptions(parseResult: ParseResultElement, reference: Reference, options: ReferenceOptions): Promise<ParseResultElement[]>;