@scalar/workspace-store 0.67.1 → 0.68.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +37 -15
- package/dist/helpers/asyncapi-chunk-groups.d.ts +3 -0
- package/dist/helpers/asyncapi-chunk-groups.d.ts.map +1 -0
- package/dist/helpers/asyncapi-chunk-groups.js +55 -0
- package/dist/helpers/asyncapi-model-chunk-reference.d.ts +3 -0
- package/dist/helpers/asyncapi-model-chunk-reference.d.ts.map +1 -0
- package/dist/helpers/asyncapi-model-chunk-reference.js +11 -0
- package/dist/navigation/helpers/traverse-schemas.d.ts.map +1 -1
- package/dist/navigation/helpers/traverse-schemas.js +1 -0
- package/dist/request-example/builder/helpers/get-example.d.ts.map +1 -1
- package/dist/request-example/builder/helpers/get-example.js +30 -6
- package/dist/server.d.ts +2 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +85 -19
- package/package.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @scalar/workspace-store
|
|
2
2
|
|
|
3
|
+
## 0.68.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#10432](https://github.com/scalar/scalar/pull/10432): Generate lazy AsyncAPI channel, operation, message, and schema chunks. Group shared dependencies to reduce requests while preserving direct model loading, recursive references, navigation, servers, and authentication.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- [#10458](https://github.com/scalar/scalar/pull/10458): Stop walking every path through shared schemas when collecting a parameter's declared example values. A shared schema found to declare no values is now skipped on the other paths that reach it, so a request whose parameter points into a deep graph of shared schemas no longer takes seconds to minutes to render.
|
|
12
|
+
|
|
13
|
+
## 0.67.2
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- [#10429](https://github.com/scalar/scalar/pull/10429): Use the schema title for sidebar entries of models grouped with `x-tags`, matching untagged models.
|
|
18
|
+
|
|
3
19
|
## 0.67.1
|
|
4
20
|
|
|
5
21
|
### 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":"AAMA,OAAO,EAAE,KAAK,YAAY,EAAU,MAAM,2BAA2B,CAAA;AAErE,OAAO,EAAE,KAAK,UAAU,EAAe,KAAK,EAAE,MAAM,yBAAyB,CAAA;AAQ7E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAI5C,OAAO,EAAE,KAAK,SAAS,EAAmB,MAAM,iBAAiB,CAAA;AACjE,OAAO,EAAE,KAAK,YAAY,EAAsB,MAAM,oBAAoB,CAAA;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/client.js
CHANGED
|
@@ -16,6 +16,7 @@ import { reactive } from 'vue';
|
|
|
16
16
|
import YAML from 'yaml';
|
|
17
17
|
import { createAuthStore } from './entities/auth/index.js';
|
|
18
18
|
import { createHistoryStore } from './entities/history/index.js';
|
|
19
|
+
import { asyncApiModelChunkReference } from './helpers/asyncapi-model-chunk-reference.js';
|
|
19
20
|
import { chunkReference, expandChunkIndex } from './helpers/chunk-index.js';
|
|
20
21
|
import { deepClone } from './helpers/deep-clone.js';
|
|
21
22
|
import { createDetectChangesProxy } from './helpers/detect-changes-proxy.js';
|
|
@@ -532,15 +533,16 @@ export const createWorkspaceStore = (workspaceProps) => {
|
|
|
532
533
|
'x-scalar-original-document-hash': input.documentHash,
|
|
533
534
|
'x-scalar-original-source-url': input.documentSource,
|
|
534
535
|
});
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
536
|
+
if (asyncApiDocument[extensions.document.navigation] === undefined) {
|
|
537
|
+
await withMeasurementAsync('bundle', async () => await bundle(getRaw(asyncApiDocument), {
|
|
538
|
+
treeShake: false,
|
|
539
|
+
plugins: loaders,
|
|
540
|
+
urlMap: true,
|
|
541
|
+
origin: input.documentSource,
|
|
542
|
+
}));
|
|
543
|
+
const coerced = withMeasurementSync('coerceValue', () => coerce(asyncApiObjectSchema, deepClone(getRaw(asyncApiDocument))));
|
|
544
|
+
withMeasurementSync('mergeObjects', () => mergeObjects(asyncApiDocument, coerced));
|
|
545
|
+
}
|
|
544
546
|
if (asyncApiDocument[extensions.document.navigation] === undefined) {
|
|
545
547
|
const navigation = traverseAsyncApiDocument(name, asyncApiDocument, navigationOptions);
|
|
546
548
|
asyncApiDocument[extensions.document.navigation] = navigation;
|
|
@@ -787,13 +789,18 @@ export const createWorkspaceStore = (workspaceProps) => {
|
|
|
787
789
|
* key in place, so asking again retries.
|
|
788
790
|
*/
|
|
789
791
|
const loadNavigationChildren = async (documentName) => {
|
|
792
|
+
// An inherited entry can point at a prototype, which must never receive chunk writes.
|
|
793
|
+
if (!Object.hasOwn(workspace.documents, documentName)) {
|
|
794
|
+
return;
|
|
795
|
+
}
|
|
790
796
|
const document = workspace.documents[documentName];
|
|
791
|
-
if (!isOpenApiDocument(document)) {
|
|
797
|
+
if (!isOpenApiDocument(document) && !isAsyncApiDocument(document)) {
|
|
792
798
|
return;
|
|
793
799
|
}
|
|
794
|
-
const
|
|
800
|
+
const chunkDocument = document;
|
|
801
|
+
const ref = chunkDocument[extensions.document.navigationChunk];
|
|
795
802
|
const navigation = document[extensions.document.navigation];
|
|
796
|
-
if (ref === undefined || navigation === undefined) {
|
|
803
|
+
if (ref === undefined || navigation === undefined || !Object.hasOwn(document, extensions.document.navigation)) {
|
|
797
804
|
return;
|
|
798
805
|
}
|
|
799
806
|
const pending = navigationChildrenLoads.get(document);
|
|
@@ -809,7 +816,7 @@ export const createWorkspaceStore = (workspaceProps) => {
|
|
|
809
816
|
// Assigned through the store's document, so the write is observed: a Vue effect reading the
|
|
810
817
|
// children re-runs, and the workspace plugins see the document change.
|
|
811
818
|
navigation.children = chunk.children ?? [];
|
|
812
|
-
delete
|
|
819
|
+
delete chunkDocument[extensions.document.navigationChunk];
|
|
813
820
|
})();
|
|
814
821
|
navigationChildrenLoads.set(document, load);
|
|
815
822
|
try {
|
|
@@ -821,7 +828,7 @@ export const createWorkspaceStore = (workspaceProps) => {
|
|
|
821
828
|
};
|
|
822
829
|
// Cache to track visited nodes during reference resolution to prevent bundling the same subtree multiple times
|
|
823
830
|
// This is needed because we are doing partial bundle operations
|
|
824
|
-
const
|
|
831
|
+
const visitedNodesCaches = new WeakMap();
|
|
825
832
|
return {
|
|
826
833
|
externalExamples: (documentName) => {
|
|
827
834
|
const name = documentName ?? getActiveDocumentName();
|
|
@@ -904,6 +911,16 @@ export const createWorkspaceStore = (workspaceProps) => {
|
|
|
904
911
|
console.error(`Invalid path provided for resolution. Path: [${path.join(', ')}]. Found value of type: ${typeof target}. Expected an object.`);
|
|
905
912
|
return Promise.resolve();
|
|
906
913
|
}
|
|
914
|
+
if (isAsyncApiDocument(activeDocument) &&
|
|
915
|
+
path.length === 3 &&
|
|
916
|
+
path[0] === 'components' &&
|
|
917
|
+
path[1] === 'schemas') {
|
|
918
|
+
const node = getRaw(target);
|
|
919
|
+
const name = path[2];
|
|
920
|
+
if (name && typeof node.$ref === 'string' && node.$global === true) {
|
|
921
|
+
node.$ref = asyncApiModelChunkReference(node.$ref, name);
|
|
922
|
+
}
|
|
923
|
+
}
|
|
907
924
|
// Bundle the target document with the active document as root, resolving any external references
|
|
908
925
|
// and tracking resolution status through hooks.
|
|
909
926
|
//
|
|
@@ -911,6 +928,11 @@ export const createWorkspaceStore = (workspaceProps) => {
|
|
|
911
928
|
// references relative to the document (`./chunks/…`), and without the origin the loader has
|
|
912
929
|
// nothing to resolve them against, so every chunk fails before a request is made. SSR
|
|
913
930
|
// workspaces write absolute URLs and never needed it.
|
|
931
|
+
const visitedNodes = activeDocument
|
|
932
|
+
? (visitedNodesCaches.get(activeDocument) ?? new Set())
|
|
933
|
+
: new Set();
|
|
934
|
+
if (activeDocument)
|
|
935
|
+
visitedNodesCaches.set(activeDocument, visitedNodes);
|
|
914
936
|
return bundle(target, {
|
|
915
937
|
root: activeDocument,
|
|
916
938
|
origin: activeDocument?.['x-scalar-original-source-url'],
|
|
@@ -926,7 +948,7 @@ export const createWorkspaceStore = (workspaceProps) => {
|
|
|
926
948
|
externalValueResolver({ lazy: true }),
|
|
927
949
|
],
|
|
928
950
|
urlMap: true,
|
|
929
|
-
visitedNodes
|
|
951
|
+
visitedNodes,
|
|
930
952
|
});
|
|
931
953
|
},
|
|
932
954
|
addDocument,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"asyncapi-chunk-groups.d.ts","sourceRoot":"","sources":["../../src/helpers/asyncapi-chunk-groups.ts"],"names":[],"mappings":"AAOA,kGAAkG;AAClG,eAAO,MAAM,mBAAmB,GAAI,UAAU,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CA+CzF,CAAA"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Buffer } from 'node:buffer';
|
|
2
|
+
import { parseJsonPointerSegments } from '@scalar/helpers/json/parse-json-pointer-segments';
|
|
3
|
+
/** Maximum size of a group of components normally consumed by the same parent. */
|
|
4
|
+
const GROUP_MAX_BYTES = 64 * 1024;
|
|
5
|
+
/** Groups components with the same referring parents, bounding incidental model-page transfer. */
|
|
6
|
+
export const asyncApiChunkGroups = (document) => {
|
|
7
|
+
const parents = new Map();
|
|
8
|
+
const components = document.components;
|
|
9
|
+
const collections = {
|
|
10
|
+
channels: (document.channels ?? {}),
|
|
11
|
+
operations: (document.operations ?? {}),
|
|
12
|
+
...Object.fromEntries(Object.entries(components ?? {})
|
|
13
|
+
.filter(([, value]) => value && typeof value === 'object')
|
|
14
|
+
.map(([type, entries]) => [`components-${type}`, entries])),
|
|
15
|
+
};
|
|
16
|
+
const walk = (value, source) => {
|
|
17
|
+
if (!value || typeof value !== 'object')
|
|
18
|
+
return;
|
|
19
|
+
for (const [key, child] of Object.entries(value)) {
|
|
20
|
+
if (key === '$ref' && typeof child === 'string' && child.startsWith('#/')) {
|
|
21
|
+
const [collection, typeOrName, name] = parseJsonPointerSegments(child.slice(1));
|
|
22
|
+
const target = collection === 'components' ? `components-${typeOrName}/${name}` : `${collection}/${typeOrName}`;
|
|
23
|
+
if (target !== source) {
|
|
24
|
+
const references = parents.get(target) ?? new Set();
|
|
25
|
+
references.add(source);
|
|
26
|
+
parents.set(target, references);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
else
|
|
30
|
+
walk(child, source);
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
for (const [section, entries] of Object.entries(collections)) {
|
|
34
|
+
for (const [name, value] of Object.entries(entries))
|
|
35
|
+
walk(value, `${section}/${name}`);
|
|
36
|
+
}
|
|
37
|
+
const groups = new Map();
|
|
38
|
+
for (const [section, entries] of Object.entries(collections)) {
|
|
39
|
+
const buckets = new Map();
|
|
40
|
+
let group = 0;
|
|
41
|
+
for (const [name, value] of Object.entries(entries)) {
|
|
42
|
+
if (!section.startsWith('components-'))
|
|
43
|
+
continue;
|
|
44
|
+
const sources = parents.get(`${section}/${name}`);
|
|
45
|
+
const signature = sources?.size ? `parents:${JSON.stringify([...sources].sort())}` : `orphan:${name}`;
|
|
46
|
+
const bytes = Buffer.byteLength(JSON.stringify({ [name]: value })) + 1;
|
|
47
|
+
const previous = buckets.get(signature);
|
|
48
|
+
const bucket = previous && previous.bytes + bytes <= GROUP_MAX_BYTES ? previous : { id: `group-${group++}`, bytes: 0 };
|
|
49
|
+
bucket.bytes += bytes;
|
|
50
|
+
buckets.set(signature, bucket);
|
|
51
|
+
groups.set(`${section}/${name}`, bucket.id);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return groups;
|
|
55
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"asyncapi-model-chunk-reference.d.ts","sourceRoot":"","sources":["../../src/helpers/asyncapi-model-chunk-reference.ts"],"names":[],"mappings":"AAIA,wFAAwF;AACxF,eAAO,MAAM,2BAA2B,GAAI,WAAW,MAAM,EAAE,MAAM,MAAM,KAAG,MAM7E,CAAA"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { escapeJsonPointer } from '@scalar/json-magic/helpers/escape-json-pointer';
|
|
2
|
+
import { encodeChunkName } from '../helpers/encode-chunk-name.js';
|
|
3
|
+
/** Model pages use singleton chunks instead of the groups consumed by channel pages. */
|
|
4
|
+
export const asyncApiModelChunkReference = (reference, name) => {
|
|
5
|
+
const section = '/asyncapi/components-schemas/';
|
|
6
|
+
const index = reference.indexOf(section);
|
|
7
|
+
if (index === -1)
|
|
8
|
+
return reference;
|
|
9
|
+
const file = reference.slice(index).includes('.json#');
|
|
10
|
+
return `${reference.slice(0, index)}/asyncapi/models/${file ? encodeChunkName(name) : encodeURIComponent(escapeJsonPointer(name))}${file ? '.json#' : '#'}`;
|
|
11
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"traverse-schemas.d.ts","sourceRoot":"","sources":["../../../src/navigation/helpers/traverse-schemas.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AACtE,OAAO,KAAK,EAAa,eAAe,EAAE,MAAM,sBAAsB,CAAA;AACtE,OAAO,KAAK,EAAE,eAAe,EAAgB,MAAM,wCAAwC,CAAA;AA2C3F;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,GAAI,gDAK7B;IACD,QAAQ,EAAE,eAAe,CAAA;IACzB,wCAAwC;IACxC,OAAO,EAAE,OAAO,CAAA;IAChB,UAAU,EAAE,mBAAmB,CAAC,YAAY,CAAC,CAAA;IAC7C,UAAU,EAAE,MAAM,CAAA;CACnB,KAAG,eAAe,
|
|
1
|
+
{"version":3,"file":"traverse-schemas.d.ts","sourceRoot":"","sources":["../../../src/navigation/helpers/traverse-schemas.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AACtE,OAAO,KAAK,EAAa,eAAe,EAAE,MAAM,sBAAsB,CAAA;AACtE,OAAO,KAAK,EAAE,eAAe,EAAgB,MAAM,wCAAwC,CAAA;AA2C3F;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,GAAI,gDAK7B;IACD,QAAQ,EAAE,eAAe,CAAA;IACzB,wCAAwC;IACxC,OAAO,EAAE,OAAO,CAAA;IAChB,UAAU,EAAE,mBAAmB,CAAC,YAAY,CAAC,CAAA;IAC7C,UAAU,EAAE,MAAM,CAAA;CACnB,KAAG,eAAe,EAkDlB,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-example.d.ts","sourceRoot":"","sources":["../../../../src/request-example/builder/helpers/get-example.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,eAAe,EACf,eAAe,EACf,iBAAiB,EAGlB,MAAM,8DAA8D,CAAA;
|
|
1
|
+
{"version":3,"file":"get-example.d.ts","sourceRoot":"","sources":["../../../../src/request-example/builder/helpers/get-example.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,eAAe,EACf,eAAe,EACf,iBAAiB,EAGlB,MAAM,8DAA8D,CAAA;AAoHrE;;;;;;;;GAQG;AACH,eAAO,MAAM,UAAU,GACrB,OAAO,eAAe,GAAG,iBAAiB,GAAG,eAAe,EAC5D,aAAa,MAAM,GAAG,SAAS,EAC/B,aAAa,MAAM,GAAG,SAAS,KAC9B,aAAa,GAAG,SAyBlB,CAAA"}
|
|
@@ -23,8 +23,13 @@ const getExampleFromExamples = (examples, exampleField, exampleName) => {
|
|
|
23
23
|
* Keep parameter fallback precedence while collecting only values declared by the schema.
|
|
24
24
|
* The general schema generator also invents values for properties without examples, which would
|
|
25
25
|
* unexpectedly populate and enable optional request parameters.
|
|
26
|
+
*
|
|
27
|
+
* The walk has no depth cap, so a schema reached along many paths is remembered once it is known to
|
|
28
|
+
* declare nothing; otherwise a deep graph of shared schemas costs one visit per path. Another path
|
|
29
|
+
* walks the same schemas, except that it stops at its own ancestors, and a stop can only drop values.
|
|
30
|
+
* So while every ancestor the first walk stopped at is still an ancestor, the walk finds nothing again.
|
|
26
31
|
*/
|
|
27
|
-
const getSchemaExample = (input,
|
|
32
|
+
const getSchemaExample = (input, walk = { ancestors: new Set(), withoutValues: new Map(), stops: new Set() }) => {
|
|
28
33
|
const schema = resolve.schema(input);
|
|
29
34
|
if ('default' in schema && schema.default !== undefined) {
|
|
30
35
|
return { value: schema.default };
|
|
@@ -40,16 +45,35 @@ const getSchemaExample = (input, ancestors = new Set()) => {
|
|
|
40
45
|
}
|
|
41
46
|
// Reference siblings create a fresh merged object, so track the underlying schema for cycles.
|
|
42
47
|
const target = getResolvedRef(input) ?? input;
|
|
43
|
-
if (!('properties' in schema) || !schema.properties
|
|
48
|
+
if (!('properties' in schema) || !schema.properties) {
|
|
44
49
|
return undefined;
|
|
45
50
|
}
|
|
46
|
-
ancestors.
|
|
51
|
+
if (walk.ancestors.has(target)) {
|
|
52
|
+
walk.stops.add(target);
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
const known = walk.withoutValues.get(target);
|
|
56
|
+
if (known?.properties === schema.properties && known.stops.every((stop) => walk.ancestors.has(stop))) {
|
|
57
|
+
known.stops.forEach((stop) => walk.stops.add(stop));
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
const outerStops = walk.stops;
|
|
61
|
+
walk.stops = new Set();
|
|
62
|
+
walk.ancestors.add(target);
|
|
47
63
|
const properties = Object.entries(schema.properties).flatMap(([name, property]) => {
|
|
48
|
-
const example = getSchemaExample(property,
|
|
64
|
+
const example = getSchemaExample(property, walk);
|
|
49
65
|
return example === undefined ? [] : [[name, example.value]];
|
|
50
66
|
});
|
|
51
|
-
ancestors.delete(target);
|
|
52
|
-
|
|
67
|
+
walk.ancestors.delete(target);
|
|
68
|
+
// Stops at schemas inside this walk have left the path, so the rest point above it.
|
|
69
|
+
const stops = [...walk.stops].filter((stop) => walk.ancestors.has(stop));
|
|
70
|
+
walk.stops = outerStops;
|
|
71
|
+
stops.forEach((stop) => outerStops.add(stop));
|
|
72
|
+
if (properties.length > 0) {
|
|
73
|
+
return { value: Object.fromEntries(properties) };
|
|
74
|
+
}
|
|
75
|
+
walk.withoutValues.set(target, { properties: schema.properties, stops });
|
|
76
|
+
return undefined;
|
|
53
77
|
};
|
|
54
78
|
/**
|
|
55
79
|
* Resolve an example value for a parameter or requestBody from either `examples` or `content.*.examples`.
|
package/dist/server.d.ts
CHANGED
|
@@ -32,7 +32,8 @@ type CreateServerWorkspaceStoreBase = {
|
|
|
32
32
|
* exactly what it would have held without this option.
|
|
33
33
|
*
|
|
34
34
|
* `getResolvedDocument()` is unaffected: it carries the whole document and its navigation either
|
|
35
|
-
* way. AsyncAPI documents
|
|
35
|
+
* way. AsyncAPI documents externalize their channels, operations, and components; compact mode
|
|
36
|
+
* moves their navigation children into a chunk too.
|
|
36
37
|
*
|
|
37
38
|
* @default false
|
|
38
39
|
*/
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
package/dist/server.js
CHANGED
|
@@ -13,7 +13,8 @@ import { createMagicProxy, getRaw } from '@scalar/json-magic/magic-proxy';
|
|
|
13
13
|
import { upgrade } from '@scalar/openapi-upgrader';
|
|
14
14
|
import { asyncApiObjectSchema } from '@scalar/schemas/asyncapi/3.1';
|
|
15
15
|
import { coerce } from '@scalar/validation';
|
|
16
|
-
import {
|
|
16
|
+
import { asyncApiChunkGroups } from './helpers/asyncapi-chunk-groups.js';
|
|
17
|
+
import { CHUNK_INDEX_KEY, buildChunkIndex, chunkRefTemplates, chunkReference, fillChunkRef, navigationHeader, } from './helpers/chunk-index.js';
|
|
17
18
|
import { createChunkWriter } from './helpers/create-chunk-writer.js';
|
|
18
19
|
import { deepClone } from './helpers/deep-clone.js';
|
|
19
20
|
import { encodeChunkName } from './helpers/encode-chunk-name.js';
|
|
@@ -277,11 +278,9 @@ export async function createServerWorkspaceStore(workspaceProps) {
|
|
|
277
278
|
/**
|
|
278
279
|
* Adds an AsyncAPI document to the workspace.
|
|
279
280
|
*
|
|
280
|
-
*
|
|
281
|
-
*
|
|
282
|
-
*
|
|
283
|
-
* therefore kept whole, and only the AsyncAPI upgrader runs so 1.x/2.x documents reach the 3.x
|
|
284
|
-
* shape the traversal and renderer expect.
|
|
281
|
+
* Channels, operations and components become global chunk references. References inside each
|
|
282
|
+
* chunk retain their document-relative pointers so shared and recursive dependencies resolve
|
|
283
|
+
* against the same root. The whole document remains available for server rendering.
|
|
285
284
|
*
|
|
286
285
|
* @param document - The AsyncAPI document to process and add
|
|
287
286
|
* @param meta - The document name plus any metadata to merge onto the stored document
|
|
@@ -300,9 +299,6 @@ export async function createServerWorkspaceStore(workspaceProps) {
|
|
|
300
299
|
// shapes like `channels: null` straight through to the browser. Merged rather than assigned, so
|
|
301
300
|
// nothing the schema does not model is dropped.
|
|
302
301
|
mergeObjects(asyncApiDocument, coerce(asyncApiObjectSchema, deepClone(asyncApiDocument)));
|
|
303
|
-
// Nothing is externalized, so the document owns no chunks. The empty entry keeps `get()` and
|
|
304
|
-
// chunk generation well defined for the document name.
|
|
305
|
-
assets[name] = {};
|
|
306
302
|
// Traversed before the spread below: its last act is a top-level `x-scalar-order` write on the
|
|
307
303
|
// document, and a snapshot taken first would both miss it and preserve whatever stale order the
|
|
308
304
|
// input arrived with.
|
|
@@ -312,19 +308,73 @@ export async function createServerWorkspaceStore(workspaceProps) {
|
|
|
312
308
|
// traversal falls back to the map key — so the sidebar reads `planetCreated` where the
|
|
313
309
|
// rendered page reads "Planet Created".
|
|
314
310
|
resolveLocalReferences(asyncApiDocument), navigationOptions ?? workspaceProps.navigationOptions);
|
|
315
|
-
|
|
311
|
+
const whole = {
|
|
316
312
|
...documentMeta,
|
|
317
313
|
...asyncApiDocument,
|
|
318
314
|
'x-original-aas-version': originalAasVersion,
|
|
319
315
|
[extensions.document.navigation]: navigation,
|
|
320
316
|
};
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
317
|
+
delete whole['openapi'];
|
|
318
|
+
const options = workspaceProps.mode === 'static'
|
|
319
|
+
? { mode: 'static', name }
|
|
320
|
+
: { mode: 'ssr', name, baseUrl: workspaceProps.baseUrl };
|
|
321
|
+
const refs = chunkRefTemplates(options);
|
|
322
|
+
const asyncapi = {};
|
|
323
|
+
const resolvedComponents = getRaw(getResolvedRef(resolveLocalReferences(asyncApiDocument).components));
|
|
324
|
+
const groups = asyncApiChunkGroups({ ...asyncApiDocument, components: resolvedComponents });
|
|
325
|
+
const externalize = (section, entries = {}) => {
|
|
326
|
+
const chunks = {};
|
|
327
|
+
const references = Object.entries(entries).map(([key, value]) => {
|
|
328
|
+
const group = groups.get(`${section}/${key}`);
|
|
329
|
+
const filename = group ?? key;
|
|
330
|
+
if (group) {
|
|
331
|
+
const values = (chunks[escapeJsonPointer(group)] ??= {});
|
|
332
|
+
Object.defineProperty(values, key, { value, enumerable: true, configurable: true, writable: true });
|
|
333
|
+
}
|
|
334
|
+
else
|
|
335
|
+
Object.defineProperty(chunks, escapeJsonPointer(key), {
|
|
336
|
+
value,
|
|
337
|
+
enumerable: true,
|
|
338
|
+
configurable: true,
|
|
339
|
+
writable: true,
|
|
340
|
+
});
|
|
341
|
+
const fragment = group ? `#/${encodeURIComponent(escapeJsonPointer(key))}` : '#';
|
|
342
|
+
return [
|
|
343
|
+
key,
|
|
344
|
+
chunkReference(workspaceProps.mode === 'static'
|
|
345
|
+
? `./chunks/${encodeChunkName(name)}/asyncapi/${section}/${encodeChunkName(filename)}.json${fragment}`
|
|
346
|
+
: `${workspaceProps.baseUrl}/${name}/asyncapi/${section}/${encodeURIComponent(escapeJsonPointer(filename))}${fragment}`),
|
|
347
|
+
];
|
|
348
|
+
});
|
|
349
|
+
asyncapi[section] = chunks;
|
|
350
|
+
return Object.fromEntries(references);
|
|
351
|
+
};
|
|
352
|
+
const components = Object.fromEntries(Object.entries(resolvedComponents ?? {}).map(([type, entries]) => [
|
|
353
|
+
type,
|
|
354
|
+
type === 'servers' || type === 'securitySchemes'
|
|
355
|
+
? entries
|
|
356
|
+
: externalize(`components-${type}`, entries),
|
|
357
|
+
]));
|
|
358
|
+
asyncapi.models = Object.fromEntries(Object.entries(resolvedComponents?.schemas ?? {}).map(([key, value]) => [escapeJsonPointer(key), value]));
|
|
359
|
+
const channels = externalize('channels', asyncApiDocument.channels);
|
|
360
|
+
const operations = externalize('operations', asyncApiDocument.operations);
|
|
361
|
+
assets[name] = {
|
|
362
|
+
asyncapi,
|
|
363
|
+
...(workspaceProps.compact ? { navigation } : {}),
|
|
364
|
+
};
|
|
365
|
+
workspace.documents[name] = {
|
|
366
|
+
...whole,
|
|
367
|
+
components,
|
|
368
|
+
channels,
|
|
369
|
+
operations,
|
|
370
|
+
...(workspaceProps.compact
|
|
371
|
+
? {
|
|
372
|
+
[extensions.document.navigation]: navigationHeader(navigation),
|
|
373
|
+
[extensions.document.navigationChunk]: fillChunkRef(refs.navigation),
|
|
374
|
+
}
|
|
375
|
+
: {}),
|
|
376
|
+
};
|
|
377
|
+
resolvedDocuments[name] = resolveLocalReferences(whole);
|
|
328
378
|
};
|
|
329
379
|
/**
|
|
330
380
|
* Adds a new document to the workspace.
|
|
@@ -479,11 +529,24 @@ export async function createServerWorkspaceStore(workspaceProps) {
|
|
|
479
529
|
const basePath = resolve(workspaceProps.directory ?? DEFAULT_ASSETS_FOLDER);
|
|
480
530
|
const writeChunk = await createChunkWriter(basePath);
|
|
481
531
|
await writeChunk([WORKSPACE_FILE_NAME], workspace);
|
|
482
|
-
for (const [name, { components, operations, navigation }] of Object.entries(assets)) {
|
|
532
|
+
for (const [name, { components, operations, navigation, asyncapi }] of Object.entries(assets)) {
|
|
483
533
|
// Only compact documents chunk their navigation; otherwise it stays whole on the document.
|
|
484
534
|
if (navigation !== undefined) {
|
|
485
535
|
await writeChunk(['chunks', encodeChunkName(name), 'navigation.json'], navigation);
|
|
486
536
|
}
|
|
537
|
+
if (asyncapi) {
|
|
538
|
+
for (const [section, entries] of Object.entries(asyncapi)) {
|
|
539
|
+
for (const [key, value] of Object.entries(entries)) {
|
|
540
|
+
await writeChunk([
|
|
541
|
+
'chunks',
|
|
542
|
+
encodeChunkName(name),
|
|
543
|
+
'asyncapi',
|
|
544
|
+
section,
|
|
545
|
+
`${encodeChunkName(unescapeJsonPointer(key))}.json`,
|
|
546
|
+
], value);
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
}
|
|
487
550
|
if (components) {
|
|
488
551
|
for (const [type, component] of Object.entries(components)) {
|
|
489
552
|
for (const [key, value] of Object.entries(component)) {
|
|
@@ -526,7 +589,10 @@ export async function createServerWorkspaceStore(workspaceProps) {
|
|
|
526
589
|
}
|
|
527
590
|
})();
|
|
528
591
|
// Keep the path segments escaped cuz we store them on the filesystem as escaped sequences
|
|
529
|
-
const
|
|
592
|
+
const segments = pointerPath.split('/').slice(1);
|
|
593
|
+
const path = segments[1] === 'asyncapi'
|
|
594
|
+
? segments.map((segment) => escapeJsonPointer(decodeURIComponent(segment).replaceAll('~1', '/').replaceAll('~0', '~')))
|
|
595
|
+
: parseJsonPointerSegments(pointerPath).map(escapeJsonPointer);
|
|
530
596
|
return getValueAtPath(assets, path);
|
|
531
597
|
},
|
|
532
598
|
addDocument,
|
package/package.json
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"openapi",
|
|
17
17
|
"scalar"
|
|
18
18
|
],
|
|
19
|
-
"version": "0.
|
|
19
|
+
"version": "0.68.0",
|
|
20
20
|
"engines": {
|
|
21
21
|
"node": ">=22"
|
|
22
22
|
},
|
|
@@ -155,13 +155,13 @@
|
|
|
155
155
|
"dependencies": {
|
|
156
156
|
"@scalar/asyncapi-upgrader": "0.1.14",
|
|
157
157
|
"@scalar/helpers": "0.16.0",
|
|
158
|
-
"@scalar/json-magic": "0.15.
|
|
158
|
+
"@scalar/json-magic": "0.15.4",
|
|
159
159
|
"@scalar/openapi-upgrader": "0.4.1",
|
|
160
|
-
"@scalar/schemas": "0.12.
|
|
161
|
-
"@scalar/snippetz": "0.10.
|
|
160
|
+
"@scalar/schemas": "0.12.3",
|
|
161
|
+
"@scalar/snippetz": "0.10.5",
|
|
162
162
|
"@scalar/typebox": "0.1.3",
|
|
163
|
-
"@scalar/types": "0.22.
|
|
164
|
-
"@scalar/validation": "0.6.
|
|
163
|
+
"@scalar/types": "0.22.4",
|
|
164
|
+
"@scalar/validation": "0.6.6",
|
|
165
165
|
"js-base64": "^3.9.2",
|
|
166
166
|
"type-fest": "^5.8.0",
|
|
167
167
|
"vue": "^3.5.40",
|