@scalar/workspace-store 0.54.3 → 0.54.4
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/CHANGELOG.md +7 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +25 -0
- package/dist/helpers/dynamic-ref.d.ts +24 -0
- package/dist/helpers/dynamic-ref.d.ts.map +1 -0
- package/dist/helpers/dynamic-ref.js +74 -0
- package/dist/request-example/builder/helpers/get-example-from-schema.d.ts +4 -1
- package/dist/request-example/builder/helpers/get-example-from-schema.d.ts.map +1 -1
- package/dist/request-example/builder/helpers/get-example-from-schema.js +97 -38
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# @scalar/workspace-store
|
|
2
2
|
|
|
3
|
+
## 0.54.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#9465](https://github.com/scalar/scalar/pull/9465): Resolve JSON Schema 2020-12 `$dynamicRef` against the active `$dynamicAnchor` when generating examples, so generic patterns like `PaginatedResponse<T>` and recursive trees produce concrete example data instead of empty placeholders
|
|
8
|
+
- [#9494](https://github.com/scalar/scalar/pull/9494): Preserve document-level UI settings (watch mode, selected server, environments, sidebar order) and user-configured servers across `rebaseDocument` — previously every rebase (e.g. a watch mode pull) silently wiped them
|
|
9
|
+
|
|
3
10
|
## 0.54.3
|
|
4
11
|
|
|
5
12
|
### Patch Changes
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/client.js
CHANGED
|
@@ -952,6 +952,25 @@ export const createWorkspaceStore = (workspaceProps) => {
|
|
|
952
952
|
// the document type discriminator.
|
|
953
953
|
originalDocuments[name] = mergedDocument;
|
|
954
954
|
intermediateDocuments[name] = deepClone(mergedDocument);
|
|
955
|
+
// Document-level UI settings never come from the upstream source and
|
|
956
|
+
// would otherwise be wiped on every rebase. Carry over only the keys
|
|
957
|
+
// that are actually set so we don't spread `undefined` into the
|
|
958
|
+
// rebuilt document. The strict document type does not declare every
|
|
959
|
+
// x-scalar-* UI extension, so read them through an untyped view.
|
|
960
|
+
const isOpenApi = isOpenApiDocument(activeDocumentRaw);
|
|
961
|
+
const environments = isOpenApi ? activeDocumentRaw['x-scalar-environments'] : undefined;
|
|
962
|
+
const order = isOpenApi ? activeDocumentRaw['x-scalar-order'] : undefined;
|
|
963
|
+
// Keep user-configured servers when the merged document has none
|
|
964
|
+
// (build-time generated specs typically declare no servers). When the
|
|
965
|
+
// merged result already carries servers — whether from upstream or
|
|
966
|
+
// preserved local edits — those stay authoritative.
|
|
967
|
+
const mergedServers = mergedDocument.servers;
|
|
968
|
+
const activeServers = activeDocumentRaw.servers;
|
|
969
|
+
const mergedHasServers = Array.isArray(mergedServers) && mergedServers.length > 0;
|
|
970
|
+
const activeHasServers = Array.isArray(activeServers) && activeServers.length > 0;
|
|
971
|
+
const preservedServers = !isAsyncApiDocument(mergedDocument) && !mergedHasServers && activeHasServers
|
|
972
|
+
? deepClone(activeServers)
|
|
973
|
+
: undefined;
|
|
955
974
|
// add the new active document to the workspace but don't re-initialize
|
|
956
975
|
await addInMemoryDocument({
|
|
957
976
|
...input,
|
|
@@ -969,6 +988,12 @@ export const createWorkspaceStore = (workspaceProps) => {
|
|
|
969
988
|
...input.meta,
|
|
970
989
|
// Preserve the registry meta
|
|
971
990
|
'x-scalar-registry-meta': activeDocumentRaw['x-scalar-registry-meta'],
|
|
991
|
+
// Preserve document-level UI settings (see note above).
|
|
992
|
+
'x-scalar-watch-mode': activeDocumentRaw['x-scalar-watch-mode'],
|
|
993
|
+
'x-scalar-selected-server': activeDocumentRaw['x-scalar-selected-server'],
|
|
994
|
+
...(environments !== undefined ? { 'x-scalar-environments': environments } : {}),
|
|
995
|
+
...(order !== undefined ? { 'x-scalar-order': order } : {}),
|
|
996
|
+
...(preservedServers !== undefined ? { servers: preservedServers } : {}),
|
|
972
997
|
// Flag local edits that need pushing - see note above.
|
|
973
998
|
'x-scalar-is-dirty': hasLocalChangesAgainstUpstream,
|
|
974
999
|
},
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { SchemaObject } from '../schemas/v3.1/strict/schema.js';
|
|
2
|
+
/**
|
|
3
|
+
* The dynamic scope, ordered outermost-first.
|
|
4
|
+
*
|
|
5
|
+
* Each entry is a schema resource on the current evaluation path. When a `$dynamicRef` is resolved,
|
|
6
|
+
* the outermost entry that declares a matching `$dynamicAnchor` wins.
|
|
7
|
+
*/
|
|
8
|
+
export type DynamicScope = SchemaObject[];
|
|
9
|
+
/** Narrow a schema to one that carries a `$dynamicRef`. */
|
|
10
|
+
export declare const isDynamicRef: (schema: unknown) => schema is SchemaObject & {
|
|
11
|
+
$dynamicRef: string;
|
|
12
|
+
};
|
|
13
|
+
export declare const collectDynamicAnchors: (resource: SchemaObject) => Map<string, SchemaObject>;
|
|
14
|
+
/** Append a schema to the dynamic scope when it could hold a `$dynamicAnchor`, otherwise return it unchanged. */
|
|
15
|
+
export declare const pushDynamicScope: (scope: DynamicScope, schema: SchemaObject) => DynamicScope;
|
|
16
|
+
/**
|
|
17
|
+
* Resolve a `$dynamicRef` fragment against the dynamic scope.
|
|
18
|
+
*
|
|
19
|
+
* Scans the scope outermost-first and returns the first resource that declares a `$dynamicAnchor` with
|
|
20
|
+
* the referenced name. Returns `undefined` when nothing matches, in which case callers should leave the
|
|
21
|
+
* reference unresolved (the schema renders as it did before, with no regression).
|
|
22
|
+
*/
|
|
23
|
+
export declare const resolveDynamicRef: (dynamicRef: string, scope: DynamicScope) => SchemaObject | undefined;
|
|
24
|
+
//# sourceMappingURL=dynamic-ref.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dynamic-ref.d.ts","sourceRoot":"","sources":["../../src/helpers/dynamic-ref.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAA;AAiBhE;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG,YAAY,EAAE,CAAA;AAEzC,2DAA2D;AAC3D,eAAO,MAAM,YAAY,GAAI,QAAQ,OAAO,KAAG,MAAM,IAAI,YAAY,GAAG;IAAE,WAAW,EAAE,MAAM,CAAA;CAItB,CAAA;AAqBvE,eAAO,MAAM,qBAAqB,GAAI,UAAU,YAAY,KAAG,GAAG,CAAC,MAAM,EAAE,YAAY,CAgCtF,CAAA;AAED,iHAAiH;AACjH,eAAO,MAAM,gBAAgB,GAAI,OAAO,YAAY,EAAE,QAAQ,YAAY,KAAG,YAClB,CAAA;AAE3D;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,GAAI,YAAY,MAAM,EAAE,OAAO,YAAY,KAAG,YAAY,GAAG,SAe1F,CAAA"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { getResolvedRef, mergeSiblingReferences } from '../helpers/get-resolved-ref.js';
|
|
2
|
+
import { unpackProxyObject } from '../helpers/unpack-proxy.js';
|
|
3
|
+
/** Narrow a schema to one that carries a `$dynamicRef`. */
|
|
4
|
+
export const isDynamicRef = (schema) => typeof schema === 'object' &&
|
|
5
|
+
schema !== null &&
|
|
6
|
+
'$dynamicRef' in schema &&
|
|
7
|
+
typeof schema.$dynamicRef === 'string';
|
|
8
|
+
/**
|
|
9
|
+
* Whether a schema introduces something a `$dynamicRef` could later bind to.
|
|
10
|
+
*
|
|
11
|
+
* We only grow the dynamic scope with schemas that could hold a `$dynamicAnchor`: those declaring one
|
|
12
|
+
* directly, or resource boundaries (`$id`) / definition containers (`$defs`) that may hold one. Plain
|
|
13
|
+
* subschemas are skipped to keep the scope small.
|
|
14
|
+
*/
|
|
15
|
+
const carriesDynamicAnchor = (schema) => '$dynamicAnchor' in schema || '$id' in schema || '$defs' in schema;
|
|
16
|
+
/**
|
|
17
|
+
* Collect the `$dynamicAnchor` declarations of a single schema resource, keyed by anchor name.
|
|
18
|
+
*
|
|
19
|
+
* Anchors are looked for at the resource root and inside `$defs` — the two placements used by the
|
|
20
|
+
* common generic and recursive patterns. Anchors nested deeper are not collected (a documented v1
|
|
21
|
+
* limitation). Each target is dereferenced so callers receive the concrete schema the anchor points to.
|
|
22
|
+
*/
|
|
23
|
+
const anchorCache = new WeakMap();
|
|
24
|
+
export const collectDynamicAnchors = (resource) => {
|
|
25
|
+
// Cache per raw schema object so repeated lookups during a walk stay cheap.
|
|
26
|
+
const cacheTarget = unpackProxyObject(resource, { depth: 1 });
|
|
27
|
+
const cached = anchorCache.get(cacheTarget);
|
|
28
|
+
if (cached) {
|
|
29
|
+
return cached;
|
|
30
|
+
}
|
|
31
|
+
const anchors = new Map();
|
|
32
|
+
const add = (node) => {
|
|
33
|
+
if (!node || typeof node !== 'object') {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const anchor = node.$dynamicAnchor;
|
|
37
|
+
if (typeof anchor === 'string' && !anchors.has(anchor)) {
|
|
38
|
+
// Resolve any sibling `$ref` so the stored target is the concrete schema (e.g. `User`).
|
|
39
|
+
anchors.set(anchor, getResolvedRef(node, mergeSiblingReferences));
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
add(resource);
|
|
43
|
+
const defs = resource.$defs;
|
|
44
|
+
if (defs && typeof defs === 'object') {
|
|
45
|
+
for (const key of Object.keys(defs)) {
|
|
46
|
+
add(defs[key]);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
anchorCache.set(cacheTarget, anchors);
|
|
50
|
+
return anchors;
|
|
51
|
+
};
|
|
52
|
+
/** Append a schema to the dynamic scope when it could hold a `$dynamicAnchor`, otherwise return it unchanged. */
|
|
53
|
+
export const pushDynamicScope = (scope, schema) => carriesDynamicAnchor(schema) ? [...scope, schema] : scope;
|
|
54
|
+
/**
|
|
55
|
+
* Resolve a `$dynamicRef` fragment against the dynamic scope.
|
|
56
|
+
*
|
|
57
|
+
* Scans the scope outermost-first and returns the first resource that declares a `$dynamicAnchor` with
|
|
58
|
+
* the referenced name. Returns `undefined` when nothing matches, in which case callers should leave the
|
|
59
|
+
* reference unresolved (the schema renders as it did before, with no regression).
|
|
60
|
+
*/
|
|
61
|
+
export const resolveDynamicRef = (dynamicRef, scope) => {
|
|
62
|
+
// Only plain-name fragments (`#itemType`) are supported; a non-fragment URI is not a dynamic anchor.
|
|
63
|
+
const name = dynamicRef.startsWith('#') ? dynamicRef.slice(1) : undefined;
|
|
64
|
+
if (!name || name.startsWith('/')) {
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
for (const resource of scope) {
|
|
68
|
+
const match = collectDynamicAnchors(resource).get(name);
|
|
69
|
+
if (match) {
|
|
70
|
+
return match;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return undefined;
|
|
74
|
+
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type DynamicScope } from '../../../helpers/dynamic-ref.js';
|
|
1
2
|
import type { SchemaObject } from '../../../schemas/v3.1/strict/openapi-document.js';
|
|
2
3
|
type GetExampleFromSchemaOptions = {
|
|
3
4
|
/** Fallback string for empty string values. */
|
|
@@ -28,13 +29,15 @@ type GetExampleFromSchemaOptions = {
|
|
|
28
29
|
* @param name - The name of the property being processed.
|
|
29
30
|
* @returns An example value for the given schema.
|
|
30
31
|
*/
|
|
31
|
-
export declare const getExampleFromSchema: (schema: SchemaObject, options?: GetExampleFromSchemaOptions, { level, parentSchema, name, seen, schemaPath, }?: Partial<{
|
|
32
|
+
export declare const getExampleFromSchema: (schema: SchemaObject, options?: GetExampleFromSchemaOptions, { level, parentSchema, name, seen, schemaPath, dynamicScope, }?: Partial<{
|
|
32
33
|
level: number;
|
|
33
34
|
parentSchema: SchemaObject;
|
|
34
35
|
name: string;
|
|
35
36
|
seen: WeakSet<object>;
|
|
36
37
|
/** Internal traversal path used to resolve nested composition selections. */
|
|
37
38
|
schemaPath: string[];
|
|
39
|
+
/** Chain of schema resources entered so far, used to resolve `$dynamicRef` (JSON Schema 2020-12). */
|
|
40
|
+
dynamicScope: DynamicScope;
|
|
38
41
|
}>) => unknown;
|
|
39
42
|
export {};
|
|
40
43
|
//# sourceMappingURL=get-example-from-schema.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-example-from-schema.d.ts","sourceRoot":"","sources":["../../../../src/request-example/builder/helpers/get-example-from-schema.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"get-example-from-schema.d.ts","sourceRoot":"","sources":["../../../../src/request-example/builder/helpers/get-example-from-schema.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,YAAY,EAAqD,MAAM,uBAAuB,CAAA;AAG5G,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wCAAwC,CAAA;AAisB1E,KAAK,2BAA2B,GAAG;IACjC,+CAA+C;IAC/C,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,4CAA4C;IAC5C,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,uDAAuD;IACvD,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;IACvB,iEAAiE;IACjE,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACnC,qDAAqD;IACrD,8BAA8B,CAAC,EAAE,OAAO,CAAA;IACxC,0DAA0D;IAC1D,oBAAoB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC9C,CAAA;AAeD;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,oBAAoB,GAC/B,QAAQ,YAAY,EACpB,UAAU,2BAA2B,EACrC,iEAOG,OAAO,CAAC;IACT,KAAK,EAAE,MAAM,CAAA;IACb,YAAY,EAAE,YAAY,CAAA;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;IACrB,6EAA6E;IAC7E,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,qGAAqG;IACrG,YAAY,EAAE,YAAY,CAAA;CAC3B,CAAM,KACN,OAmMF,CAAA"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { isDefined } from '@scalar/helpers/array/is-defined';
|
|
2
|
+
import { isDynamicRef, pushDynamicScope, resolveDynamicRef } from '../../../helpers/dynamic-ref.js';
|
|
2
3
|
import { unpackProxyObject } from '../../../helpers/unpack-proxy.js';
|
|
3
4
|
import { resolve } from '../../../resolve.js';
|
|
4
5
|
/** Maximum recursion depth to prevent infinite loops in circular references */
|
|
@@ -108,9 +109,13 @@ const getRequiredNames = (parentSchema) => {
|
|
|
108
109
|
* Cache the result for a schema if it is an object type.
|
|
109
110
|
* Primitive values are not cached to avoid unnecessary WeakMap operations.
|
|
110
111
|
* Stores a map of cacheKey strings which is made up of the options object.
|
|
112
|
+
*
|
|
113
|
+
* Skips the cache while a dynamic scope is active: the same shared schema node can resolve to
|
|
114
|
+
* different examples depending on the dynamic scope it was reached through, so caching it by object
|
|
115
|
+
* identity would leak one scope's result into another.
|
|
111
116
|
*/
|
|
112
|
-
const cache = (schema, result, cacheKey) => {
|
|
113
|
-
if (typeof result !== 'object' || result === null) {
|
|
117
|
+
const cache = (schema, result, cacheKey, skip = false) => {
|
|
118
|
+
if (skip || typeof result !== 'object' || result === null) {
|
|
114
119
|
return result;
|
|
115
120
|
}
|
|
116
121
|
const rawSchema = getSchemaCacheTarget(schema);
|
|
@@ -313,8 +318,11 @@ const sortPropertyNamesByXOrder = (properties) => Object.keys(properties).sort((
|
|
|
313
318
|
* Build an example for an object schema, including properties, patternProperties,
|
|
314
319
|
* additionalProperties, and composition (allOf/oneOf/anyOf) merging.
|
|
315
320
|
*/
|
|
316
|
-
const handleObjectSchema = (schema, options, level, seen, cacheKey, schemaPath) => {
|
|
321
|
+
const handleObjectSchema = (schema, options, level, seen, cacheKey, schemaPath, dynamicScope) => {
|
|
317
322
|
const response = {};
|
|
323
|
+
// Children are evaluated with this schema added to the dynamic scope so nested `$dynamicRef`s bind here.
|
|
324
|
+
const childScope = pushDynamicScope(dynamicScope, schema);
|
|
325
|
+
const skipCache = dynamicScope.length > 0;
|
|
318
326
|
if ('properties' in schema && schema.properties) {
|
|
319
327
|
const properties = schema.properties;
|
|
320
328
|
const propertyNames = sortPropertyNamesByXOrder(properties);
|
|
@@ -332,6 +340,7 @@ const handleObjectSchema = (schema, options, level, seen, cacheKey, schemaPath)
|
|
|
332
340
|
name: propertyName,
|
|
333
341
|
schemaPath: [...schemaPath, propertyName],
|
|
334
342
|
seen,
|
|
343
|
+
dynamicScope: childScope,
|
|
335
344
|
});
|
|
336
345
|
if (typeof value !== 'undefined') {
|
|
337
346
|
response[propertyXmlName ?? propertyName] = value;
|
|
@@ -350,6 +359,7 @@ const handleObjectSchema = (schema, options, level, seen, cacheKey, schemaPath)
|
|
|
350
359
|
name: pattern,
|
|
351
360
|
schemaPath: [...schemaPath, pattern],
|
|
352
361
|
seen,
|
|
362
|
+
dynamicScope: childScope,
|
|
353
363
|
});
|
|
354
364
|
}
|
|
355
365
|
}
|
|
@@ -376,6 +386,7 @@ const handleObjectSchema = (schema, options, level, seen, cacheKey, schemaPath)
|
|
|
376
386
|
level: level + 1,
|
|
377
387
|
schemaPath: [...schemaPath, additionalName],
|
|
378
388
|
seen,
|
|
389
|
+
dynamicScope: childScope,
|
|
379
390
|
})
|
|
380
391
|
: 'anything';
|
|
381
392
|
if (propertyNamesEnum && propertyNamesEnum.length > 0) {
|
|
@@ -396,6 +407,7 @@ const handleObjectSchema = (schema, options, level, seen, cacheKey, schemaPath)
|
|
|
396
407
|
level: level + 1,
|
|
397
408
|
schemaPath,
|
|
398
409
|
seen,
|
|
410
|
+
dynamicScope: childScope,
|
|
399
411
|
}));
|
|
400
412
|
}
|
|
401
413
|
}
|
|
@@ -407,6 +419,7 @@ const handleObjectSchema = (schema, options, level, seen, cacheKey, schemaPath)
|
|
|
407
419
|
level: level + 1,
|
|
408
420
|
parentSchema: schema,
|
|
409
421
|
seen,
|
|
422
|
+
dynamicScope: childScope,
|
|
410
423
|
});
|
|
411
424
|
merged = mergeExamples(merged, ex);
|
|
412
425
|
}
|
|
@@ -417,18 +430,33 @@ const handleObjectSchema = (schema, options, level, seen, cacheKey, schemaPath)
|
|
|
417
430
|
if (options?.xml && 'xml' in schema && schema.xml?.name && level === 0) {
|
|
418
431
|
const wrapped = {};
|
|
419
432
|
wrapped[schema.xml.name] = response;
|
|
420
|
-
return cache(schema, wrapped, cacheKey);
|
|
433
|
+
return cache(schema, wrapped, cacheKey, skipCache);
|
|
421
434
|
}
|
|
422
|
-
return cache(schema, response, cacheKey);
|
|
435
|
+
return cache(schema, response, cacheKey, skipCache);
|
|
423
436
|
};
|
|
424
437
|
/** Build an example for an array schema, including items, allOf, oneOf/anyOf, and XML wrapping */
|
|
425
|
-
const handleArraySchema = (schema, options, level, seen, cacheKey, schemaPath) => {
|
|
426
|
-
const
|
|
438
|
+
const handleArraySchema = (schema, options, level, seen, cacheKey, schemaPath, dynamicScope) => {
|
|
439
|
+
const childScope = pushDynamicScope(dynamicScope, schema);
|
|
440
|
+
const skipCache = dynamicScope.length > 0;
|
|
441
|
+
let items = 'items' in schema ? resolve.schema(schema.items) : undefined;
|
|
442
|
+
// Bind a dynamic item type (e.g. the generic `PaginatedResponse<T>` pattern) before inspecting it.
|
|
443
|
+
// Crossing a `$dynamicRef` leaves the static schema graph, so the cycle guard built up by the outer
|
|
444
|
+
// walk no longer applies to the bound type. Restart `seen` for the item recursion so recursive trees
|
|
445
|
+
// (e.g. a category whose children reference the same anchor) render their nested levels instead of
|
|
446
|
+
// tripping the shared guard. Depth stays bounded by `MAX_LEVELS_DEEP`.
|
|
447
|
+
let itemsSeen = seen;
|
|
448
|
+
if (items && isDynamicRef(items)) {
|
|
449
|
+
const resolvedDynamic = resolveDynamicRef(items.$dynamicRef, childScope);
|
|
450
|
+
if (resolvedDynamic) {
|
|
451
|
+
items = resolvedDynamic;
|
|
452
|
+
itemsSeen = new WeakSet();
|
|
453
|
+
}
|
|
454
|
+
}
|
|
427
455
|
const itemsSchemaPath = [...schemaPath, 'items'];
|
|
428
456
|
const itemsXmlTagName = items && typeof items === 'object' && 'xml' in items ? items.xml?.name : undefined;
|
|
429
457
|
const wrapItems = !!(options?.xml && 'xml' in schema && schema.xml?.wrapped && itemsXmlTagName);
|
|
430
458
|
if (schema.example !== undefined) {
|
|
431
|
-
return cache(schema, wrapItems ? { [itemsXmlTagName]: schema.example } : schema.example, cacheKey);
|
|
459
|
+
return cache(schema, wrapItems ? { [itemsXmlTagName]: schema.example } : schema.example, cacheKey, skipCache);
|
|
432
460
|
}
|
|
433
461
|
if (items && typeof items === 'object') {
|
|
434
462
|
if (Array.isArray(items.allOf) && items.allOf.length > 0) {
|
|
@@ -440,19 +468,21 @@ const handleArraySchema = (schema, options, level, seen, cacheKey, schemaPath) =
|
|
|
440
468
|
level: level + 1,
|
|
441
469
|
parentSchema: schema,
|
|
442
470
|
schemaPath: itemsSchemaPath,
|
|
443
|
-
seen,
|
|
471
|
+
seen: itemsSeen,
|
|
472
|
+
dynamicScope: childScope,
|
|
444
473
|
});
|
|
445
|
-
return cache(schema, wrapItems ? [{ [itemsXmlTagName]: merged }] : [merged], cacheKey);
|
|
474
|
+
return cache(schema, wrapItems ? [{ [itemsXmlTagName]: merged }] : [merged], cacheKey, skipCache);
|
|
446
475
|
}
|
|
447
476
|
const examples = allOf
|
|
448
477
|
.map((s) => getExampleFromSchema(resolve.schema(s), options, {
|
|
449
478
|
level: level + 1,
|
|
450
479
|
parentSchema: schema,
|
|
451
480
|
schemaPath: itemsSchemaPath,
|
|
452
|
-
seen,
|
|
481
|
+
seen: itemsSeen,
|
|
482
|
+
dynamicScope: childScope,
|
|
453
483
|
}))
|
|
454
484
|
.filter(isDefined);
|
|
455
|
-
return cache(schema, wrapItems ? examples.map((e) => ({ [itemsXmlTagName]: e })) : examples, cacheKey);
|
|
485
|
+
return cache(schema, wrapItems ? examples.map((e) => ({ [itemsXmlTagName]: e })) : examples, cacheKey, skipCache);
|
|
456
486
|
}
|
|
457
487
|
const compositionKeyword = items.oneOf ? 'oneOf' : items.anyOf ? 'anyOf' : undefined;
|
|
458
488
|
const union = compositionKeyword ? items[compositionKeyword] : undefined;
|
|
@@ -463,9 +493,10 @@ const handleArraySchema = (schema, options, level, seen, cacheKey, schemaPath) =
|
|
|
463
493
|
level: level + 1,
|
|
464
494
|
parentSchema: schema,
|
|
465
495
|
schemaPath: itemsSchemaPath,
|
|
466
|
-
seen,
|
|
496
|
+
seen: itemsSeen,
|
|
497
|
+
dynamicScope: childScope,
|
|
467
498
|
});
|
|
468
|
-
return cache(schema, wrapItems ? [{ [itemsXmlTagName]: ex }] : [ex], cacheKey);
|
|
499
|
+
return cache(schema, wrapItems ? [{ [itemsXmlTagName]: ex }] : [ex], cacheKey, skipCache);
|
|
469
500
|
}
|
|
470
501
|
}
|
|
471
502
|
const isObject = items && typeof items === 'object' && (('type' in items && items.type === 'object') || 'properties' in items);
|
|
@@ -474,11 +505,12 @@ const handleArraySchema = (schema, options, level, seen, cacheKey, schemaPath) =
|
|
|
474
505
|
const ex = getExampleFromSchema(items, options, {
|
|
475
506
|
level: level + 1,
|
|
476
507
|
schemaPath: itemsSchemaPath,
|
|
477
|
-
seen,
|
|
508
|
+
seen: itemsSeen,
|
|
509
|
+
dynamicScope: childScope,
|
|
478
510
|
});
|
|
479
|
-
return cache(schema, wrapItems ? [{ [itemsXmlTagName]: ex }] : [ex], cacheKey);
|
|
511
|
+
return cache(schema, wrapItems ? [{ [itemsXmlTagName]: ex }] : [ex], cacheKey, skipCache);
|
|
480
512
|
}
|
|
481
|
-
return cache(schema, [], cacheKey);
|
|
513
|
+
return cache(schema, [], cacheKey, skipCache);
|
|
482
514
|
};
|
|
483
515
|
/** Return primitive example value for single-type schemas, or undefined if not primitive */
|
|
484
516
|
const getPrimitiveValue = (schema, makeUpRandomData, emptyString) => {
|
|
@@ -552,12 +584,35 @@ const createOptionsCacheKey = (options) => JSON.stringify({
|
|
|
552
584
|
* @param name - The name of the property being processed.
|
|
553
585
|
* @returns An example value for the given schema.
|
|
554
586
|
*/
|
|
555
|
-
export const getExampleFromSchema = (schema, options, { level = 0, parentSchema, name, seen = new WeakSet(), schemaPath = [], } = {}) => {
|
|
587
|
+
export const getExampleFromSchema = (schema, options, { level = 0, parentSchema, name, seen = new WeakSet(), schemaPath = [], dynamicScope = [], } = {}) => {
|
|
556
588
|
// Resolve any $ref references to get the actual schema
|
|
557
589
|
const _schema = resolve.schema(schema);
|
|
558
590
|
if (!isDefined(_schema)) {
|
|
559
591
|
return undefined;
|
|
560
592
|
}
|
|
593
|
+
// Resolve a `$dynamicRef` against the active dynamic scope, then continue with the bound schema.
|
|
594
|
+
// When nothing matches, fall through and render the reference as before (no regression).
|
|
595
|
+
if (isDynamicRef(_schema)) {
|
|
596
|
+
const resolvedDynamic = resolveDynamicRef(_schema.$dynamicRef, dynamicScope);
|
|
597
|
+
if (resolvedDynamic) {
|
|
598
|
+
// The `seen` set guards against cycles in the static schema graph, but a `$dynamicRef` is resolved
|
|
599
|
+
// per evaluation path and intentionally points outside that graph. Re-entering the bound type with a
|
|
600
|
+
// fresh `seen` lets recursive examples (e.g. a category tree) render their nested levels instead of
|
|
601
|
+
// bailing out on the shared cycle guard. Depth stays bounded by `MAX_LEVELS_DEEP`.
|
|
602
|
+
return getExampleFromSchema(resolvedDynamic, options, {
|
|
603
|
+
level: level + 1,
|
|
604
|
+
parentSchema,
|
|
605
|
+
name,
|
|
606
|
+
seen: new WeakSet(),
|
|
607
|
+
schemaPath,
|
|
608
|
+
dynamicScope,
|
|
609
|
+
});
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
// Grow the scope with this schema so nested references can bind to its `$dynamicAnchor`s.
|
|
613
|
+
const childScope = pushDynamicScope(dynamicScope, _schema);
|
|
614
|
+
// The same shared node can resolve differently per scope, so skip the result cache under a scope.
|
|
615
|
+
const skipCache = dynamicScope.length > 0;
|
|
561
616
|
// Unpack from all proxies to get the raw schema object for cycle detection
|
|
562
617
|
const targetValue = getSchemaCacheTarget(_schema);
|
|
563
618
|
if (seen.has(targetValue)) {
|
|
@@ -566,11 +621,13 @@ export const getExampleFromSchema = (schema, options, { level = 0, parentSchema,
|
|
|
566
621
|
seen.add(targetValue);
|
|
567
622
|
/** Make the cache key unique per options and schema path */
|
|
568
623
|
const cacheKey = createOptionsCacheKey(options) + (schemaPath.length > 0 ? `:path:${schemaPath.join('.')}` : '');
|
|
569
|
-
// Check cache first for performance - avoid recomputing the same schema
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
624
|
+
// Check cache first for performance - avoid recomputing the same schema (skipped under a dynamic scope)
|
|
625
|
+
if (!skipCache) {
|
|
626
|
+
const cached = resultCache.get(targetValue)?.get(cacheKey);
|
|
627
|
+
if (typeof cached !== 'undefined') {
|
|
628
|
+
seen.delete(targetValue);
|
|
629
|
+
return cached;
|
|
630
|
+
}
|
|
574
631
|
}
|
|
575
632
|
// Prevent infinite recursion in circular references
|
|
576
633
|
if (level > MAX_LEVELS_DEEP) {
|
|
@@ -591,45 +648,45 @@ export const getExampleFromSchema = (schema, options, { level = 0, parentSchema,
|
|
|
591
648
|
// Type coercion for numeric types
|
|
592
649
|
if ('type' in _schema && (_schema.type === 'number' || _schema.type === 'integer')) {
|
|
593
650
|
seen.delete(targetValue);
|
|
594
|
-
return cache(_schema, Number(value), cacheKey);
|
|
651
|
+
return cache(_schema, Number(value), cacheKey, skipCache);
|
|
595
652
|
}
|
|
596
653
|
seen.delete(targetValue);
|
|
597
|
-
return cache(_schema, value, cacheKey);
|
|
654
|
+
return cache(_schema, value, cacheKey, skipCache);
|
|
598
655
|
}
|
|
599
656
|
}
|
|
600
657
|
// Priority order: examples > example > default > const > enum
|
|
601
658
|
if (Array.isArray(_schema.examples) && _schema.examples.length > 0) {
|
|
602
659
|
seen.delete(targetValue);
|
|
603
|
-
return cache(_schema, _schema.examples[0], cacheKey);
|
|
660
|
+
return cache(_schema, _schema.examples[0], cacheKey, skipCache);
|
|
604
661
|
}
|
|
605
662
|
if (_schema.example !== undefined) {
|
|
606
663
|
seen.delete(targetValue);
|
|
607
|
-
return cache(_schema, _schema.example, cacheKey);
|
|
664
|
+
return cache(_schema, _schema.example, cacheKey, skipCache);
|
|
608
665
|
}
|
|
609
666
|
if (_schema.default !== undefined) {
|
|
610
667
|
const normalizedDefault = normalizeSchemaDefault(_schema);
|
|
611
668
|
if (normalizedDefault !== INVALID_DEFAULT) {
|
|
612
669
|
seen.delete(targetValue);
|
|
613
|
-
return cache(_schema, normalizedDefault, cacheKey);
|
|
670
|
+
return cache(_schema, normalizedDefault, cacheKey, skipCache);
|
|
614
671
|
}
|
|
615
672
|
}
|
|
616
673
|
if (_schema.const !== undefined) {
|
|
617
674
|
seen.delete(targetValue);
|
|
618
|
-
return cache(_schema, _schema.const, cacheKey);
|
|
675
|
+
return cache(_schema, _schema.const, cacheKey, skipCache);
|
|
619
676
|
}
|
|
620
677
|
if (Array.isArray(_schema.enum) && _schema.enum.length > 0) {
|
|
621
678
|
seen.delete(targetValue);
|
|
622
|
-
return cache(_schema, _schema.enum[0], cacheKey);
|
|
679
|
+
return cache(_schema, _schema.enum[0], cacheKey, skipCache);
|
|
623
680
|
}
|
|
624
681
|
// Handle object types - check for properties to identify objects
|
|
625
682
|
if ('properties' in _schema || ('type' in _schema && _schema.type === 'object')) {
|
|
626
|
-
const result = handleObjectSchema(_schema, options, level, seen, cacheKey, schemaPath);
|
|
683
|
+
const result = handleObjectSchema(_schema, options, level, seen, cacheKey, schemaPath, dynamicScope);
|
|
627
684
|
seen.delete(targetValue);
|
|
628
685
|
return result;
|
|
629
686
|
}
|
|
630
687
|
// Handle array types
|
|
631
688
|
if (('type' in _schema && _schema.type === 'array') || 'items' in _schema) {
|
|
632
|
-
const result = handleArraySchema(_schema, options, level, seen, cacheKey, schemaPath);
|
|
689
|
+
const result = handleArraySchema(_schema, options, level, seen, cacheKey, schemaPath, dynamicScope);
|
|
633
690
|
seen.delete(targetValue);
|
|
634
691
|
return result;
|
|
635
692
|
}
|
|
@@ -637,7 +694,7 @@ export const getExampleFromSchema = (schema, options, { level = 0, parentSchema,
|
|
|
637
694
|
const primitive = getPrimitiveValue(_schema, makeUpRandomData, options?.emptyString);
|
|
638
695
|
if (primitive !== undefined) {
|
|
639
696
|
seen.delete(targetValue);
|
|
640
|
-
return cache(_schema, primitive, cacheKey);
|
|
697
|
+
return cache(_schema, primitive, cacheKey, skipCache);
|
|
641
698
|
}
|
|
642
699
|
// Handle composition schemas (oneOf, anyOf)
|
|
643
700
|
const compositionKeyword = _schema.oneOf ? 'oneOf' : _schema.anyOf ? 'anyOf' : undefined;
|
|
@@ -658,11 +715,12 @@ export const getExampleFromSchema = (schema, options, { level = 0, parentSchema,
|
|
|
658
715
|
level: level + 1,
|
|
659
716
|
schemaPath,
|
|
660
717
|
seen,
|
|
661
|
-
|
|
718
|
+
dynamicScope: childScope,
|
|
719
|
+
}), cacheKey, skipCache);
|
|
662
720
|
}
|
|
663
721
|
}
|
|
664
722
|
seen.delete(targetValue);
|
|
665
|
-
return cache(_schema, null, cacheKey);
|
|
723
|
+
return cache(_schema, null, cacheKey, skipCache);
|
|
666
724
|
}
|
|
667
725
|
// Handle allOf at root level (non-object/array schemas)
|
|
668
726
|
if (Array.isArray(_schema.allOf) && _schema.allOf.length > 0) {
|
|
@@ -674,6 +732,7 @@ export const getExampleFromSchema = (schema, options, { level = 0, parentSchema,
|
|
|
674
732
|
parentSchema: _schema,
|
|
675
733
|
schemaPath,
|
|
676
734
|
seen,
|
|
735
|
+
dynamicScope: childScope,
|
|
677
736
|
});
|
|
678
737
|
if (merged === undefined) {
|
|
679
738
|
merged = ex;
|
|
@@ -687,15 +746,15 @@ export const getExampleFromSchema = (schema, options, { level = 0, parentSchema,
|
|
|
687
746
|
}
|
|
688
747
|
}
|
|
689
748
|
seen.delete(targetValue);
|
|
690
|
-
return cache(_schema, merged ?? null, cacheKey);
|
|
749
|
+
return cache(_schema, merged ?? null, cacheKey, skipCache);
|
|
691
750
|
}
|
|
692
751
|
// Handle union types (array of types)
|
|
693
752
|
const unionPrimitive = getUnionPrimitiveValue(_schema, makeUpRandomData, options?.emptyString);
|
|
694
753
|
if (unionPrimitive !== undefined) {
|
|
695
754
|
seen.delete(targetValue);
|
|
696
|
-
return cache(_schema, unionPrimitive, cacheKey);
|
|
755
|
+
return cache(_schema, unionPrimitive, cacheKey, skipCache);
|
|
697
756
|
}
|
|
698
757
|
// Default fallback
|
|
699
758
|
seen.delete(targetValue);
|
|
700
|
-
return cache(_schema, null, cacheKey);
|
|
759
|
+
return cache(_schema, null, cacheKey, skipCache);
|
|
701
760
|
};
|
package/package.json
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"openapi",
|
|
17
17
|
"scalar"
|
|
18
18
|
],
|
|
19
|
-
"version": "0.54.
|
|
19
|
+
"version": "0.54.4",
|
|
20
20
|
"engines": {
|
|
21
21
|
"node": ">=22"
|
|
22
22
|
},
|
|
@@ -150,11 +150,11 @@
|
|
|
150
150
|
"yaml": "^2.8.3",
|
|
151
151
|
"@scalar/helpers": "0.8.2",
|
|
152
152
|
"@scalar/json-magic": "0.12.16",
|
|
153
|
-
"@scalar/schemas": "0.4.3",
|
|
154
153
|
"@scalar/openapi-upgrader": "0.2.9",
|
|
155
|
-
"@scalar/
|
|
156
|
-
"@scalar/types": "0.
|
|
157
|
-
"@scalar/validation": "0.6.0"
|
|
154
|
+
"@scalar/schemas": "0.5.0",
|
|
155
|
+
"@scalar/types": "0.14.0",
|
|
156
|
+
"@scalar/validation": "0.6.0",
|
|
157
|
+
"@scalar/snippetz": "0.9.17"
|
|
158
158
|
},
|
|
159
159
|
"devDependencies": {
|
|
160
160
|
"@google-cloud/storage": "7.16.0",
|