@scalar/workspace-store 0.64.0 → 0.65.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 +86 -0
- package/README.md +45 -10
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +108 -9
- package/dist/entities/auth/schema.d.ts +236 -0
- package/dist/entities/auth/schema.d.ts.map +1 -1
- package/dist/entities/auth/schema.js +3 -1
- package/dist/helpers/chunk-index.d.ts +20 -2
- package/dist/helpers/chunk-index.d.ts.map +1 -1
- package/dist/helpers/chunk-index.js +14 -1
- package/dist/helpers/external-examples.d.ts +2 -0
- package/dist/helpers/external-examples.d.ts.map +1 -1
- package/dist/helpers/external-examples.js +1 -0
- package/dist/helpers/for-each-path-item-operation.js +4 -4
- package/dist/helpers/get-example-value.d.ts +15 -0
- package/dist/helpers/get-example-value.d.ts.map +1 -0
- package/dist/helpers/get-example-value.js +28 -0
- package/dist/helpers/get-resolved-ref.d.ts.map +1 -1
- package/dist/helpers/get-resolved-ref.js +12 -1
- package/dist/helpers/normalize-boolean-schemas.d.ts +10 -0
- package/dist/helpers/normalize-boolean-schemas.d.ts.map +1 -0
- package/dist/helpers/normalize-boolean-schemas.js +193 -0
- package/dist/helpers/operation-examples.d.ts.map +1 -1
- package/dist/helpers/operation-examples.js +5 -2
- package/dist/helpers/serialize-stream-example.d.ts +8 -0
- package/dist/helpers/serialize-stream-example.d.ts.map +1 -0
- package/dist/helpers/serialize-stream-example.js +52 -0
- package/dist/helpers/use-external-examples.d.ts.map +1 -1
- package/dist/helpers/use-external-examples.js +8 -1
- package/dist/mutators/index.d.ts +3 -3
- package/dist/mutators/operation/body.d.ts.map +1 -1
- package/dist/mutators/operation/body.js +9 -2
- package/dist/plugins/bundler/index.d.ts +1 -0
- package/dist/plugins/bundler/index.d.ts.map +1 -1
- package/dist/plugins/bundler/index.js +8 -1
- package/dist/plugins/bundler/openapi-document.d.ts +6 -0
- package/dist/plugins/bundler/openapi-document.d.ts.map +1 -0
- package/dist/plugins/bundler/openapi-document.js +57 -0
- package/dist/request-example/builder/body/build-multipart.d.ts +29 -0
- package/dist/request-example/builder/body/build-multipart.d.ts.map +1 -0
- package/dist/request-example/builder/body/build-multipart.js +191 -0
- package/dist/request-example/builder/body/build-request-body.d.ts +6 -1
- package/dist/request-example/builder/body/build-request-body.d.ts.map +1 -1
- package/dist/request-example/builder/body/build-request-body.js +80 -23
- package/dist/request-example/builder/body/encode-multipart-body.d.ts +8 -8
- package/dist/request-example/builder/body/encode-multipart-body.d.ts.map +1 -1
- package/dist/request-example/builder/body/encode-multipart-body.js +56 -18
- package/dist/request-example/builder/body/get-request-body-example.d.ts.map +1 -1
- package/dist/request-example/builder/body/get-request-body-example.js +20 -6
- package/dist/request-example/builder/body/multipart-limits.d.ts +3 -0
- package/dist/request-example/builder/body/multipart-limits.d.ts.map +1 -0
- package/dist/request-example/builder/body/multipart-limits.js +2 -0
- package/dist/request-example/builder/body/serialize-form-property.d.ts +2 -0
- package/dist/request-example/builder/body/serialize-form-property.d.ts.map +1 -1
- package/dist/request-example/builder/body/serialize-form-property.js +3 -2
- package/dist/request-example/builder/body/serialize-multipart-array.d.ts +1 -1
- package/dist/request-example/builder/build-request.js +5 -0
- package/dist/request-example/builder/header/build-request-parameters.d.ts.map +1 -1
- package/dist/request-example/builder/header/build-request-parameters.js +5 -1
- package/dist/request-example/builder/header/serialize-parameter.d.ts +11 -0
- package/dist/request-example/builder/header/serialize-parameter.d.ts.map +1 -1
- package/dist/request-example/builder/header/serialize-parameter.js +22 -0
- 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 +42 -3
- package/dist/request-example/builder/helpers/get-example.d.ts.map +1 -1
- package/dist/request-example/builder/helpers/get-example.js +5 -2
- package/dist/request-example/builder/index.d.ts +2 -2
- package/dist/request-example/builder/index.d.ts.map +1 -1
- package/dist/request-example/builder/index.js +1 -1
- package/dist/request-example/builder/security/secret-types.d.ts +4 -1
- package/dist/request-example/builder/security/secret-types.d.ts.map +1 -1
- package/dist/request-example/context/security/extract-security-scheme-secrets.d.ts.map +1 -1
- package/dist/request-example/context/security/extract-security-scheme-secrets.js +15 -0
- package/dist/request-example/index.d.ts +5 -2
- package/dist/request-example/index.d.ts.map +1 -1
- package/dist/request-example/index.js +4 -1
- package/dist/request-example/xml/serialize-xml-part.d.ts +9 -0
- package/dist/request-example/xml/serialize-xml-part.d.ts.map +1 -0
- package/dist/request-example/xml/serialize-xml-part.js +12 -0
- package/dist/schemas/extensions.d.ts +9 -0
- package/dist/schemas/extensions.d.ts.map +1 -1
- package/dist/schemas/extensions.js +9 -0
- package/dist/schemas/reference-config/index.d.ts +1 -0
- package/dist/schemas/reference-config/index.d.ts.map +1 -1
- package/dist/schemas/reference-config/settings.d.ts +1 -0
- package/dist/schemas/reference-config/settings.d.ts.map +1 -1
- package/dist/schemas/v3.1/strict/oauthflows.d.ts +26 -0
- package/dist/schemas/v3.1/strict/oauthflows.d.ts.map +1 -1
- package/dist/schemas/v3.1/strict/oauthflows.js +3 -0
- package/dist/schemas/v3.1/strict/openapi-document.d.ts +812 -7
- package/dist/schemas/v3.1/strict/openapi-document.d.ts.map +1 -1
- package/dist/schemas/v3.2/openapi/index.d.ts +5 -0
- package/dist/schemas/v3.2/openapi/index.d.ts.map +1 -1
- package/dist/schemas/v3.2/openapi/index.js +46 -12
- package/dist/schemas/v3.2/strict/openapi-document.d.ts +37 -0
- package/dist/schemas/v3.2/strict/openapi-document.d.ts.map +1 -1
- package/dist/schemas/v3.2/strict/openapi-document.js +6 -14
- package/dist/server.d.ts +10 -6
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +33 -32
- package/package.json +19 -9
- package/dist/schemas/v3.1/openapi/index.d.ts +0 -149
- package/dist/schemas/v3.1/openapi/index.d.ts.map +0 -1
- package/dist/schemas/v3.1/openapi/index.js +0 -732
- package/dist/schemas/v3.1/openapi/reference.d.ts +0 -4
- package/dist/schemas/v3.1/openapi/reference.d.ts.map +0 -1
- package/dist/schemas/v3.1/openapi/reference.js +0 -29
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { parseMimeType } from '@scalar/helpers/http/mime-type';
|
|
2
|
+
import { getResolvedRef } from '../helpers/get-resolved-ref.js';
|
|
3
|
+
/** Select an explicit example without confusing false, zero, null, or empty text with absence. */
|
|
4
|
+
export const getExampleValue = (input) => {
|
|
5
|
+
const example = getResolvedRef(input);
|
|
6
|
+
if (example?.serializedValue !== undefined) {
|
|
7
|
+
return { source: 'serialized', value: example.serializedValue };
|
|
8
|
+
}
|
|
9
|
+
if (example?.dataValue !== undefined) {
|
|
10
|
+
return { source: 'data', value: example.dataValue };
|
|
11
|
+
}
|
|
12
|
+
if (example?.value !== undefined) {
|
|
13
|
+
return { source: 'value', value: example.value };
|
|
14
|
+
}
|
|
15
|
+
// externalValue is fetched by the bundler; until then it is not an inline payload.
|
|
16
|
+
return undefined;
|
|
17
|
+
};
|
|
18
|
+
/** Preserve explicit wire text for any media type, or serialize structured JSON data. */
|
|
19
|
+
export const getExplicitExampleText = (example, contentType, indent) => {
|
|
20
|
+
if (example?.source === 'serialized') {
|
|
21
|
+
return example.value;
|
|
22
|
+
}
|
|
23
|
+
const { essence, subtype } = parseMimeType(contentType);
|
|
24
|
+
if (example?.source === 'data' && (essence === 'application/json' || subtype.endsWith('+json'))) {
|
|
25
|
+
return JSON.stringify(example.value, null, indent);
|
|
26
|
+
}
|
|
27
|
+
return undefined;
|
|
28
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-resolved-ref.d.ts","sourceRoot":"","sources":["../../src/helpers/get-resolved-ref.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,IAAI,CAAA;CAAE,CAAA;AACjF,MAAM,MAAM,SAAS,CAAC,IAAI,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;AA0ElD;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,GAAI,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,KAAG,
|
|
1
|
+
{"version":3,"file":"get-resolved-ref.d.ts","sourceRoot":"","sources":["../../src/helpers/get-resolved-ref.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,IAAI,CAAA;CAAE,CAAA;AACjF,MAAM,MAAM,SAAS,CAAC,IAAI,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;AA0ElD;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,GAAI,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,KAAG,IA2BlE,CAAA;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EACzC,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,EACrB,SAAS,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,MAAM,GACzC,IAAI,GAAG,MAAM,CAAA;AAChB,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,IAAI,CAAA;CAAE,GAAG,IAAI,CAAA;AACtF,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,SAAS,CAAA;AAW7E;;GAEG;AACH,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI,CAAC,SAAS;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAC,CAAA;CAAE,GAAG,CAAC,CAAC,SAAS,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAA"}
|
|
@@ -76,7 +76,18 @@ export const mergeSiblingReferences = (node) => {
|
|
|
76
76
|
if (!isObject(target)) {
|
|
77
77
|
return rest;
|
|
78
78
|
}
|
|
79
|
-
|
|
79
|
+
const merged = { ...target, ...rest };
|
|
80
|
+
// Plain document loaders hide reference links from serialization. Preserve the
|
|
81
|
+
// next hop explicitly so chain resolution does not depend on object spread.
|
|
82
|
+
if (Object.hasOwn(target, '$ref-value') && !Object.hasOwn(merged, '$ref-value')) {
|
|
83
|
+
Object.defineProperty(merged, '$ref-value', {
|
|
84
|
+
value: target['$ref-value'],
|
|
85
|
+
enumerable: false,
|
|
86
|
+
configurable: true,
|
|
87
|
+
writable: true,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
return merged;
|
|
80
91
|
};
|
|
81
92
|
export function getResolvedRef(node, transform = defaultTransform) {
|
|
82
93
|
if (typeof node === 'object' && node !== null && '$ref' in node) {
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Normalize boolean schemas without mutating caller-owned data.
|
|
3
|
+
* Only changed schema containers and their ancestors are copied. Unchanged bundled
|
|
4
|
+
* documents and opaque example/extension payloads retain their identity. Iterative
|
|
5
|
+
* discovery and copy propagation preserve cycles without recursive cloning.
|
|
6
|
+
* The marker represents an untyped schema; false is its negation. additionalProperties
|
|
7
|
+
* already accepts booleans and therefore retains its authored representation.
|
|
8
|
+
*/
|
|
9
|
+
export declare const normalizeBooleanSchemas: <T extends Record<string, unknown>>(document: T) => T;
|
|
10
|
+
//# sourceMappingURL=normalize-boolean-schemas.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize-boolean-schemas.d.ts","sourceRoot":"","sources":["../../src/helpers/normalize-boolean-schemas.ts"],"names":[],"mappings":"AAgDA;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,GAAI,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,CAAC,KAAG,CAkJxF,CAAA"}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { parseJsonPointerSegments } from '@scalar/helpers/json/parse-json-pointer-segments';
|
|
2
|
+
import { isObject } from '@scalar/helpers/object/is-object';
|
|
3
|
+
import { isSchemaPath } from '@scalar/helpers/openapi/is-schema-path';
|
|
4
|
+
const schemaMaps = new Set(['properties', 'patternProperties', '$defs', 'definitions', 'dependentSchemas']);
|
|
5
|
+
const schemaArrays = new Set(['allOf', 'anyOf', 'oneOf', 'prefixItems']);
|
|
6
|
+
const childSchemas = new Set([
|
|
7
|
+
'items',
|
|
8
|
+
'not',
|
|
9
|
+
'if',
|
|
10
|
+
'then',
|
|
11
|
+
'else',
|
|
12
|
+
'contains',
|
|
13
|
+
'propertyNames',
|
|
14
|
+
'contentSchema',
|
|
15
|
+
'$ref-value',
|
|
16
|
+
]);
|
|
17
|
+
const openApiMaps = new Set([
|
|
18
|
+
'paths',
|
|
19
|
+
'webhooks',
|
|
20
|
+
'responses',
|
|
21
|
+
'content',
|
|
22
|
+
'headers',
|
|
23
|
+
'examples',
|
|
24
|
+
'links',
|
|
25
|
+
'encoding',
|
|
26
|
+
'variables',
|
|
27
|
+
'parameters',
|
|
28
|
+
'requestBodies',
|
|
29
|
+
'securitySchemes',
|
|
30
|
+
'pathItems',
|
|
31
|
+
'mediaTypes',
|
|
32
|
+
'additionalOperations',
|
|
33
|
+
'callbacks',
|
|
34
|
+
'x-ext',
|
|
35
|
+
]);
|
|
36
|
+
const opaqueValues = new Set(['example', 'examples', 'default', 'enum', 'const', 'value', 'dataValue']);
|
|
37
|
+
/**
|
|
38
|
+
* Normalize boolean schemas without mutating caller-owned data.
|
|
39
|
+
* Only changed schema containers and their ancestors are copied. Unchanged bundled
|
|
40
|
+
* documents and opaque example/extension payloads retain their identity. Iterative
|
|
41
|
+
* discovery and copy propagation preserve cycles without recursive cloning.
|
|
42
|
+
* The marker represents an untyped schema; false is its negation. additionalProperties
|
|
43
|
+
* already accepts booleans and therefore retains its authored representation.
|
|
44
|
+
*/
|
|
45
|
+
export const normalizeBooleanSchemas = (document) => {
|
|
46
|
+
const nodes = new WeakMap();
|
|
47
|
+
const changed = new Set();
|
|
48
|
+
const schemas = new WeakSet();
|
|
49
|
+
const documents = new WeakSet();
|
|
50
|
+
const tasks = [];
|
|
51
|
+
const getNode = (source) => {
|
|
52
|
+
const existing = nodes.get(source);
|
|
53
|
+
if (existing) {
|
|
54
|
+
return existing;
|
|
55
|
+
}
|
|
56
|
+
const node = { source };
|
|
57
|
+
nodes.set(source, node);
|
|
58
|
+
return node;
|
|
59
|
+
};
|
|
60
|
+
const root = getNode(document);
|
|
61
|
+
const link = (parent, key, child) => {
|
|
62
|
+
const node = getNode(child);
|
|
63
|
+
if (!node.parent) {
|
|
64
|
+
node.parent = { node: parent, key };
|
|
65
|
+
}
|
|
66
|
+
else if (node.parent.node !== parent || node.parent.key !== key) {
|
|
67
|
+
const parents = (node.otherParents ??= []);
|
|
68
|
+
if (!parents.some((edge) => edge.node === parent && edge.key === key)) {
|
|
69
|
+
parents.push({ node: parent, key });
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return node;
|
|
73
|
+
};
|
|
74
|
+
const schema = (parent, key, value) => {
|
|
75
|
+
if (typeof value === 'boolean') {
|
|
76
|
+
;
|
|
77
|
+
(parent.replacements ??= new Map()).set(key, value ? { __scalar_: '' } : { __scalar_: '', not: { __scalar_: '' } });
|
|
78
|
+
changed.add(parent);
|
|
79
|
+
}
|
|
80
|
+
else if (isObject(value)) {
|
|
81
|
+
tasks.push({ node: link(parent, key, value), kind: 'schema' });
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
const reference = (pointer) => {
|
|
85
|
+
const segments = parseJsonPointerSegments(pointer);
|
|
86
|
+
let parent = root;
|
|
87
|
+
for (const [index, key] of segments.entries()) {
|
|
88
|
+
// A local reference cannot reach inherited properties or prototype setters.
|
|
89
|
+
if (!Object.hasOwn(parent.source, key)) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const value = Reflect.get(parent.source, key);
|
|
93
|
+
if (index === segments.length - 1) {
|
|
94
|
+
schema(parent, key, value);
|
|
95
|
+
}
|
|
96
|
+
else if (value !== null && typeof value === 'object') {
|
|
97
|
+
parent = link(parent, key, value);
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
tasks.push({ node: root, kind: 'document', path: [], mapDepth: 0 });
|
|
105
|
+
while (tasks.length > 0) {
|
|
106
|
+
const task = tasks.pop();
|
|
107
|
+
if (!task) {
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
const { node } = task;
|
|
111
|
+
const visited = task.kind === 'schema' ? schemas : documents;
|
|
112
|
+
if (visited.has(node.source)) {
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
visited.add(node.source);
|
|
116
|
+
if (task.kind === 'schema') {
|
|
117
|
+
const value = node.source;
|
|
118
|
+
if (typeof value.$ref === 'string' && value.$ref.startsWith('#/')) {
|
|
119
|
+
reference(value.$ref.slice(1));
|
|
120
|
+
}
|
|
121
|
+
for (const [key, child] of Object.entries(value)) {
|
|
122
|
+
if ((schemaMaps.has(key) && isObject(child)) || (schemaArrays.has(key) && Array.isArray(child))) {
|
|
123
|
+
const container = link(node, key, child);
|
|
124
|
+
for (const [name, nested] of Object.entries(child)) {
|
|
125
|
+
schema(container, name, nested);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
else if (childSchemas.has(key)) {
|
|
129
|
+
schema(node, key, child);
|
|
130
|
+
}
|
|
131
|
+
else if (['additionalProperties', 'unevaluatedProperties', 'unevaluatedItems'].includes(key) &&
|
|
132
|
+
isObject(child)) {
|
|
133
|
+
schema(node, key, child);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
const { path } = task;
|
|
139
|
+
for (const [key, child] of Object.entries(node.source)) {
|
|
140
|
+
const childPath = [...path, key];
|
|
141
|
+
const isMapEntry = task.mapDepth > 0;
|
|
142
|
+
if (key === 'schemas' && path.at(-1) === 'components' && isObject(child)) {
|
|
143
|
+
const container = link(node, key, child);
|
|
144
|
+
for (const [name, nested] of Object.entries(child)) {
|
|
145
|
+
schema(container, name, nested);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
else if ((key === 'schema' || key === 'itemSchema') && !isMapEntry && isSchemaPath(childPath)) {
|
|
149
|
+
schema(node, key, child);
|
|
150
|
+
}
|
|
151
|
+
else if (isMapEntry || (!opaqueValues.has(key) && (!key.startsWith('x-') || key === 'x-ext'))) {
|
|
152
|
+
// Vendor extensions are opaque. x-ext additionally contains bundled documents
|
|
153
|
+
// and schema targets whose context can be supplied by a local reference.
|
|
154
|
+
if (child !== null && typeof child === 'object') {
|
|
155
|
+
tasks.push({
|
|
156
|
+
node: link(node, key, child),
|
|
157
|
+
kind: 'document',
|
|
158
|
+
path: childPath,
|
|
159
|
+
mapDepth: isMapEntry ? task.mapDepth - 1 : key === 'callbacks' ? 2 : openApiMaps.has(key) ? 1 : 0,
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
const forEachParent = (node, callback) => {
|
|
166
|
+
if (node.parent) {
|
|
167
|
+
callback(node.parent);
|
|
168
|
+
}
|
|
169
|
+
node.otherParents?.forEach(callback);
|
|
170
|
+
};
|
|
171
|
+
// Set iteration also visits newly added ancestors, including shared/cyclic parents.
|
|
172
|
+
for (const node of changed) {
|
|
173
|
+
forEachParent(node, (parent) => changed.add(parent.node));
|
|
174
|
+
}
|
|
175
|
+
for (const node of changed) {
|
|
176
|
+
node.copy = Array.isArray(node.source) ? [] : {};
|
|
177
|
+
}
|
|
178
|
+
for (const node of changed) {
|
|
179
|
+
forEachParent(node, (parent) => (parent.node.replacements ??= new Map()).set(parent.key, node.copy));
|
|
180
|
+
}
|
|
181
|
+
for (const node of changed) {
|
|
182
|
+
for (const [key, value] of Object.entries(node.source)) {
|
|
183
|
+
// Define an own data property so authored keys such as __proto__ remain data.
|
|
184
|
+
Object.defineProperty(node.copy, key, {
|
|
185
|
+
value: node.replacements?.has(key) ? node.replacements.get(key) : value,
|
|
186
|
+
enumerable: true,
|
|
187
|
+
writable: true,
|
|
188
|
+
configurable: true,
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
return (root.copy ?? document);
|
|
193
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"operation-examples.d.ts","sourceRoot":"","sources":["../../src/helpers/operation-examples.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAmB,eAAe,EAAE,MAAM,wCAAwC,CAAA;AAE7G,+FAA+F;AAC/F,eAAO,MAAM,oBAAoB,GAC/B,WAAW,eAAe,EAC1B,KAAK,MAAM,EACX,cAAc,MAAM,KACnB,CAAC,aAAa,GAAG,SAAS,CAAC,EAS7B,CAAA;AAED,8FAA8F;AAC9F,eAAO,MAAM,wBAAwB,GACnC,WAAW,eAAe,EAC1B,KAAK,MAAM,EACX,aAAa,MAAM,GAAG,SAAS,EAC/B,SAAS,CAAC,OAAO,EAAE,aAAa,GAAG,SAAS,KAAK,aAAa,GAAG,SAAS,KACzE,
|
|
1
|
+
{"version":3,"file":"operation-examples.d.ts","sourceRoot":"","sources":["../../src/helpers/operation-examples.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAmB,eAAe,EAAE,MAAM,wCAAwC,CAAA;AAE7G,+FAA+F;AAC/F,eAAO,MAAM,oBAAoB,GAC/B,WAAW,eAAe,EAC1B,KAAK,MAAM,EACX,cAAc,MAAM,KACnB,CAAC,aAAa,GAAG,SAAS,CAAC,EAS7B,CAAA;AAED,8FAA8F;AAC9F,eAAO,MAAM,wBAAwB,GACnC,WAAW,eAAe,EAC1B,KAAK,MAAM,EACX,aAAa,MAAM,GAAG,SAAS,EAC/B,SAAS,CAAC,OAAO,EAAE,aAAa,GAAG,SAAS,KAAK,aAAa,GAAG,SAAS,KACzE,eAgCF,CAAA"}
|
|
@@ -37,9 +37,12 @@ export const resolveOperationExamples = (operation, key, contentType, resolve) =
|
|
|
37
37
|
const content = 'content' in resolved ? resolved.content : undefined;
|
|
38
38
|
const mediaType = Object.keys(content ?? {})[0];
|
|
39
39
|
if (mediaType && content?.[mediaType]) {
|
|
40
|
-
|
|
40
|
+
const media = mapMedia(content[mediaType]);
|
|
41
|
+
return media === content[mediaType] ? parameter : { ...resolved, content: { ...content, [mediaType]: media } };
|
|
41
42
|
}
|
|
42
|
-
|
|
43
|
+
// Keep editable source objects when there is no downloaded example to overlay.
|
|
44
|
+
const media = mapMedia(resolved);
|
|
45
|
+
return media === resolved ? parameter : { ...resolved, ...media };
|
|
43
46
|
}),
|
|
44
47
|
};
|
|
45
48
|
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Frame generated values and authored structured examples as sequential content.
|
|
3
|
+
* Callers bypass this helper for authored strings that already contain wire framing.
|
|
4
|
+
* SSE objects with no valid fields are omitted with one warning per call; an empty
|
|
5
|
+
* input sequence is valid and does not produce a warning.
|
|
6
|
+
*/
|
|
7
|
+
export declare const serializeStreamExample: (value: unknown, contentType: string, singleItem: boolean) => string | undefined;
|
|
8
|
+
//# sourceMappingURL=serialize-stream-example.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serialize-stream-example.d.ts","sourceRoot":"","sources":["../../src/helpers/serialize-stream-example.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,GACjC,OAAO,OAAO,EACd,aAAa,MAAM,EACnB,YAAY,OAAO,KAClB,MAAM,GAAG,SA2CX,CAAA"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { getStreamFormat } from '@scalar/helpers/http/is-streaming-content-type';
|
|
2
|
+
import { isObject } from '@scalar/helpers/object/is-object';
|
|
3
|
+
/**
|
|
4
|
+
* Frame generated values and authored structured examples as sequential content.
|
|
5
|
+
* Callers bypass this helper for authored strings that already contain wire framing.
|
|
6
|
+
* SSE objects with no valid fields are omitted with one warning per call; an empty
|
|
7
|
+
* input sequence is valid and does not produce a warning.
|
|
8
|
+
*/
|
|
9
|
+
export const serializeStreamExample = (value, contentType, singleItem) => {
|
|
10
|
+
if (value === undefined) {
|
|
11
|
+
return undefined;
|
|
12
|
+
}
|
|
13
|
+
const format = getStreamFormat(contentType);
|
|
14
|
+
const items = singleItem ? [value] : Array.isArray(value) ? value : [value];
|
|
15
|
+
if (format === 'json-lines') {
|
|
16
|
+
return items.map((item) => `${JSON.stringify(item)}\n`).join('');
|
|
17
|
+
}
|
|
18
|
+
if (format === 'json-seq') {
|
|
19
|
+
return items.map((item) => `\u001e${JSON.stringify(item)}\n`).join('');
|
|
20
|
+
}
|
|
21
|
+
if (format === 'sse') {
|
|
22
|
+
const frames = items.map((item) => {
|
|
23
|
+
if (!isObject(item)) {
|
|
24
|
+
return `data: ${JSON.stringify(item)}\n\n`;
|
|
25
|
+
}
|
|
26
|
+
const fields = ['event', 'id', 'retry', 'data'].flatMap((field) => {
|
|
27
|
+
const fieldValue = item[field];
|
|
28
|
+
if (field === 'retry') {
|
|
29
|
+
return typeof fieldValue === 'number' && Number.isInteger(fieldValue) && fieldValue >= 0
|
|
30
|
+
? [`retry: ${fieldValue}`]
|
|
31
|
+
: [];
|
|
32
|
+
}
|
|
33
|
+
if (field === 'data' && fieldValue !== undefined) {
|
|
34
|
+
const data = typeof fieldValue === 'string' ? fieldValue : JSON.stringify(fieldValue);
|
|
35
|
+
return data.split(/\r\n|\r|\n/).map((line) => `data: ${line}`);
|
|
36
|
+
}
|
|
37
|
+
if (typeof fieldValue !== 'string' || (field === 'id' && fieldValue.includes('\0'))) {
|
|
38
|
+
return [];
|
|
39
|
+
}
|
|
40
|
+
const lines = fieldValue.split(/\r\n|\r|\n/);
|
|
41
|
+
return lines.length === 1 ? [`${field}: ${fieldValue}`] : [];
|
|
42
|
+
});
|
|
43
|
+
return fields.length ? `${fields.join('\n')}\n\n` : '';
|
|
44
|
+
});
|
|
45
|
+
const omitted = frames.filter((frame) => frame === '').length;
|
|
46
|
+
if (omitted > 0) {
|
|
47
|
+
console.warn(`Skipped ${omitted} SSE example item(s) with no valid event, id, retry, or data fields.`);
|
|
48
|
+
}
|
|
49
|
+
return frames.join('');
|
|
50
|
+
}
|
|
51
|
+
return undefined;
|
|
52
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-external-examples.d.ts","sourceRoot":"","sources":["../../src/helpers/use-external-examples.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,uBAAuB,EAC5B,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,GAAG,EAOT,MAAM,KAAK,CAAA;AAEZ,OAAO,EAAE,KAAK,uBAAuB,EAAiC,MAAM,6BAA6B,CAAA;AACzG,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAA;AAE3E,4FAA4F;AAC5F,eAAO,MAAM,iBAAiB,EAAE,YAAY,CAAC,MAAM,uBAAuB,CAA+B,CAAA;AAEzG,0GAA0G;AAC1G,eAAO,MAAM,oBAAoB,GAAI,QAAQ,GAAG,CAAC,OAAO,GAAG,uBAAuB,GAAG,IAAI,CAAC,KAAG,GAAG,CAAC,OAAO,CAuBvG,CAAA;AAED,gGAAgG;AAChG,eAAO,MAAM,mBAAmB,GAC9B,UAAU,MAAM,CAAC,aAAa,GAAG,SAAS,CAAC,EAAE,EAC7C,UAAS,MAAM,OAAoB,EACnC,WAAW,MAAM,uBAAuB,KACvC;IACD,OAAO,EAAE,WAAW,CAAC,OAAO,CAAC,CAAA;IAC7B,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,CAAA;IAC5B,OAAO,EAAE,CAAC,OAAO,EAAE,aAAa,GAAG,SAAS,KAAK,aAAa,GAAG,SAAS,CAAA;IAC1E,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"use-external-examples.d.ts","sourceRoot":"","sources":["../../src/helpers/use-external-examples.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,uBAAuB,EAC5B,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,GAAG,EAOT,MAAM,KAAK,CAAA;AAEZ,OAAO,EAAE,KAAK,uBAAuB,EAAiC,MAAM,6BAA6B,CAAA;AACzG,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAA;AAE3E,4FAA4F;AAC5F,eAAO,MAAM,iBAAiB,EAAE,YAAY,CAAC,MAAM,uBAAuB,CAA+B,CAAA;AAEzG,0GAA0G;AAC1G,eAAO,MAAM,oBAAoB,GAAI,QAAQ,GAAG,CAAC,OAAO,GAAG,uBAAuB,GAAG,IAAI,CAAC,KAAG,GAAG,CAAC,OAAO,CAuBvG,CAAA;AAED,gGAAgG;AAChG,eAAO,MAAM,mBAAmB,GAC9B,UAAU,MAAM,CAAC,aAAa,GAAG,SAAS,CAAC,EAAE,EAC7C,UAAS,MAAM,OAAoB,EACnC,WAAW,MAAM,uBAAuB,KACvC;IACD,OAAO,EAAE,WAAW,CAAC,OAAO,CAAC,CAAA;IAC7B,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,CAAA;IAC5B,OAAO,EAAE,CAAC,OAAO,EAAE,aAAa,GAAG,SAAS,KAAK,aAAa,GAAG,SAAS,CAAA;IAC1E,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAsC3B,CAAA"}
|
|
@@ -46,7 +46,14 @@ export const useExternalExamples = (examples, enabled = () => true, resolver) =>
|
|
|
46
46
|
if (!example || example.value !== undefined || !example.externalValue)
|
|
47
47
|
return example;
|
|
48
48
|
const state = getResolver()(example);
|
|
49
|
-
|
|
49
|
+
if (state.status !== 'loaded')
|
|
50
|
+
return example;
|
|
51
|
+
// A 3.2 example can pair structured data with external wire text. Keep both in the
|
|
52
|
+
// resolved view so raw consumers display the download and form editors retain the data.
|
|
53
|
+
if (example.dataValue !== undefined && state.serializedValue !== undefined) {
|
|
54
|
+
return { ...example, serializedValue: state.serializedValue };
|
|
55
|
+
}
|
|
56
|
+
return { ...example, value: state.value };
|
|
50
57
|
},
|
|
51
58
|
retry: async () => {
|
|
52
59
|
await Promise.all(states.value.map((state) => state.load()));
|
package/dist/mutators/index.d.ts
CHANGED
|
@@ -12,8 +12,8 @@ export declare function generateClientMutators(store: WorkspaceStore | null): {
|
|
|
12
12
|
workspace: () => {
|
|
13
13
|
cookie: {
|
|
14
14
|
upsertCookie: (payload: {
|
|
15
|
-
payload: Partial<import("../schemas/extensions/general/x-scalar-cookies.js").XScalarCookie>;
|
|
16
15
|
index?: number | undefined;
|
|
16
|
+
payload: Partial<import("../schemas/extensions/general/x-scalar-cookies.js").XScalarCookie>;
|
|
17
17
|
}) => import("../schemas/extensions/general/x-scalar-cookies.js").XScalarCookie | undefined;
|
|
18
18
|
deleteCookie: (payload: {
|
|
19
19
|
index: number;
|
|
@@ -77,8 +77,8 @@ export declare function generateClientMutators(store: WorkspaceStore | null): {
|
|
|
77
77
|
};
|
|
78
78
|
cookie: {
|
|
79
79
|
upsertCookie: (payload: {
|
|
80
|
-
payload: Partial<import("../schemas/extensions/general/x-scalar-cookies.js").XScalarCookie>;
|
|
81
80
|
index?: number | undefined;
|
|
81
|
+
payload: Partial<import("../schemas/extensions/general/x-scalar-cookies.js").XScalarCookie>;
|
|
82
82
|
}) => import("../schemas/extensions/general/x-scalar-cookies.js").XScalarCookie | undefined;
|
|
83
83
|
deleteCookie: (payload: {
|
|
84
84
|
index: number;
|
|
@@ -168,8 +168,8 @@ export declare function generateClientMutators(store: WorkspaceStore | null): {
|
|
|
168
168
|
};
|
|
169
169
|
cookie: {
|
|
170
170
|
upsertCookie: (payload: {
|
|
171
|
-
payload: Partial<import("../schemas/extensions/general/x-scalar-cookies.js").XScalarCookie>;
|
|
172
171
|
index?: number | undefined;
|
|
172
|
+
payload: Partial<import("../schemas/extensions/general/x-scalar-cookies.js").XScalarCookie>;
|
|
173
173
|
}) => import("../schemas/extensions/general/x-scalar-cookies.js").XScalarCookie | undefined;
|
|
174
174
|
deleteCookie: (payload: {
|
|
175
175
|
index: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"body.d.ts","sourceRoot":"","sources":["../../../src/mutators/operation/body.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAA;AAIrE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"body.d.ts","sourceRoot":"","sources":["../../../src/mutators/operation/body.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAA;AAIrE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AA4ClD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,qCAAqC,GAChD,UAAU,iBAAiB,GAAG,IAAI,EAClC,mBAAmB,eAAe,CAAC,0CAA0C,CAAC,SAwB/E,CAAA;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,iCAAiC,GAC5C,UAAU,iBAAiB,GAAG,IAAI,EAClC,gCAAgC,eAAe,CAAC,oCAAoC,CAAC,SAStF,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,mCAAmC,GAC9C,UAAU,iBAAiB,GAAG,IAAI,EAClC,gCAAgC,eAAe,CAAC,wCAAwC,CAAC,SAS1F,CAAA"}
|
|
@@ -2,6 +2,13 @@ import { getPathItemOperation } from '../../helpers/for-each-path-item-operation
|
|
|
2
2
|
import { getResolvedRef } from '../../helpers/get-resolved-ref.js';
|
|
3
3
|
import { unpackProxyObject } from '../../helpers/unpack-proxy.js';
|
|
4
4
|
import { isOpenApiDocument } from '../../schemas/type-guards.js';
|
|
5
|
+
/** An edit replaces the authored source so the old serialized/data value cannot win. */
|
|
6
|
+
const replaceExampleValue = (example, value) => {
|
|
7
|
+
delete example.serializedValue;
|
|
8
|
+
delete example.dataValue;
|
|
9
|
+
delete example.externalValue;
|
|
10
|
+
example.value = value;
|
|
11
|
+
};
|
|
5
12
|
/** Ensure the json that we need exists up to the example object in the request body */
|
|
6
13
|
const findOrCreateRequestBodyExample = (document, contentType, meta) => {
|
|
7
14
|
if (!isOpenApiDocument(document)) {
|
|
@@ -81,7 +88,7 @@ export const updateOperationRequestBodyExample = (document, { meta, payload, con
|
|
|
81
88
|
console.error('Example not found', meta.exampleKey);
|
|
82
89
|
return;
|
|
83
90
|
}
|
|
84
|
-
example
|
|
91
|
+
replaceExampleValue(example, payload);
|
|
85
92
|
};
|
|
86
93
|
/**
|
|
87
94
|
* Stores the form data for the request body example
|
|
@@ -94,5 +101,5 @@ export const updateOperationRequestBodyFormValue = (document, { meta, payload, c
|
|
|
94
101
|
console.error('Example not found', meta.exampleKey);
|
|
95
102
|
return;
|
|
96
103
|
}
|
|
97
|
-
example
|
|
104
|
+
replaceExampleValue(example, unpackProxyObject(payload, { depth: 3 }));
|
|
98
105
|
};
|
|
@@ -117,4 +117,5 @@ export declare const syncPathParameters: () => LifecyclePlugin;
|
|
|
117
117
|
* These keys are used for internal purposes and are not needed in the final bundled document.
|
|
118
118
|
*/
|
|
119
119
|
export declare const removeExtraScalarKeys: () => LifecyclePlugin;
|
|
120
|
+
export { openApiDocument, resolveOpenApiDocument } from './openapi-document.js';
|
|
120
121
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/bundler/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAAE,KAAK,eAAe,EAAwB,MAAM,2BAA2B,CAAA;AAStF;;;;;GAKG;AACH,eAAO,MAAM,aAAa,QAAO,eAahC,CAAA;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,qBAAqB,GAAI,UAAU;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,KAAG,eA2CpE,CAAA;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,QAAO,eAwCjC,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,mBAAmB,QAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/bundler/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAAE,KAAK,eAAe,EAAwB,MAAM,2BAA2B,CAAA;AAStF;;;;;GAKG;AACH,eAAO,MAAM,aAAa,QAAO,eAahC,CAAA;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,qBAAqB,GAAI,UAAU;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,KAAG,eA2CpE,CAAA;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,QAAO,eAwCjC,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,mBAAmB,QAAO,eA6BtC,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,oBAAoB,QAAO,eAuBvC,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,aAAa,QAAO,eAyBhC,CAAA;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,kBAAkB,QAAO,eAkFrC,CAAA;AAKD;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,QAAO,eAaxC,CAAA;AAED,OAAO,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA"}
|
|
@@ -149,9 +149,15 @@ export const refsEverywhere = () => {
|
|
|
149
149
|
export const restoreOriginalRefs = () => {
|
|
150
150
|
return {
|
|
151
151
|
type: 'lifecycle',
|
|
152
|
-
|
|
152
|
+
onAfterNodeProcess: (node, context) => {
|
|
153
153
|
const ref = node['$ref'];
|
|
154
154
|
const root = context.rootNode;
|
|
155
|
+
const authoredRefs = root['x-scalar-original-refs'];
|
|
156
|
+
const authored = isObject(authoredRefs) ? authoredRefs[JSON.stringify(context.path)] : undefined;
|
|
157
|
+
if (isObject(authored) && typeof authored.original === 'string' && authored.rewritten === ref) {
|
|
158
|
+
node['$ref'] = authored.original;
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
155
161
|
const extUrls = root['x-ext-urls'];
|
|
156
162
|
// Only process if $ref is a string and x-ext-urls is a valid object
|
|
157
163
|
if (typeof ref !== 'string' || typeof extUrls !== 'object' || extUrls === null || !isLocalRef(ref)) {
|
|
@@ -334,3 +340,4 @@ export const removeExtraScalarKeys = () => {
|
|
|
334
340
|
},
|
|
335
341
|
};
|
|
336
342
|
};
|
|
343
|
+
export { openApiDocument, resolveOpenApiDocument } from './openapi-document.js';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type DocumentResolver, type LifecyclePlugin } from '@scalar/json-magic/bundle';
|
|
2
|
+
/** Resolves an OpenAPI document's declared identity against its retrieval location. */
|
|
3
|
+
export declare const resolveOpenApiDocument: DocumentResolver;
|
|
4
|
+
/** Honors `$self` for complete OpenAPI documents, including external and cached documents. */
|
|
5
|
+
export declare const openApiDocument: () => LifecyclePlugin;
|
|
6
|
+
//# sourceMappingURL=openapi-document.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openapi-document.d.ts","sourceRoot":"","sources":["../../../src/plugins/bundler/openapi-document.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,eAAe,EAAwB,MAAM,2BAA2B,CAAA;AAE7G,uFAAuF;AACvF,eAAO,MAAM,sBAAsB,EAAE,gBAcpC,CAAA;AAED,8FAA8F;AAC9F,eAAO,MAAM,eAAe,QAAO,eAsClC,CAAA"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { isObject } from '@scalar/helpers/object/is-object';
|
|
2
|
+
import { resolveReferencePath } from '@scalar/json-magic/bundle';
|
|
3
|
+
/** Resolves an OpenAPI document's declared identity against its retrieval location. */
|
|
4
|
+
export const resolveOpenApiDocument = (document, retrievalUri) => {
|
|
5
|
+
if (!isObject(document) ||
|
|
6
|
+
typeof document.openapi !== 'string' ||
|
|
7
|
+
!/^3\.2\.\d+$/.test(document.openapi) ||
|
|
8
|
+
typeof document.$self !== 'string') {
|
|
9
|
+
return undefined;
|
|
10
|
+
}
|
|
11
|
+
const self = resolveReferencePath(retrievalUri, document.$self);
|
|
12
|
+
// RFC 3986 requires a fragment-free base, while the declared identity can retain its fragment.
|
|
13
|
+
const fragmentIndex = self.indexOf('#');
|
|
14
|
+
const baseUri = fragmentIndex === -1 ? self : self.slice(0, fragmentIndex);
|
|
15
|
+
return { baseUri, metadata: { openapi: document.openapi, $self: self } };
|
|
16
|
+
};
|
|
17
|
+
/** Honors `$self` for complete OpenAPI documents, including external and cached documents. */
|
|
18
|
+
export const openApiDocument = () => {
|
|
19
|
+
const authoredRefs = new WeakMap();
|
|
20
|
+
const paths = new WeakMap();
|
|
21
|
+
const indexPaths = (value, path) => {
|
|
22
|
+
if (value === null || typeof value !== 'object' || paths.has(value))
|
|
23
|
+
return;
|
|
24
|
+
paths.set(value, path);
|
|
25
|
+
for (const [key, child] of Object.entries(value)) {
|
|
26
|
+
indexPaths(child, [...path, key]);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
return {
|
|
30
|
+
type: 'lifecycle',
|
|
31
|
+
resolveDocument: resolveOpenApiDocument,
|
|
32
|
+
onBeforeNodeProcess: (node, context) => {
|
|
33
|
+
if (typeof node.$ref === 'string' && resolveOpenApiDocument(context.rootNode, context.origin)) {
|
|
34
|
+
// Partial bundles report paths relative to the selected subtree. Index the supplied root
|
|
35
|
+
// so the saved references can also be restored when exporting the entire document.
|
|
36
|
+
indexPaths(context.rootNode, []);
|
|
37
|
+
authoredRefs.set(node, node.$ref);
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
onAfterNodeProcess: (node, context) => {
|
|
41
|
+
const authored = authoredRefs.get(node);
|
|
42
|
+
if (authored === undefined || authored === node.$ref) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
// A path-based map survives serialization and partial bundles without changing Reference Objects.
|
|
46
|
+
// Keep the first spelling, including fragments and ./, when a later pass rewrites it again.
|
|
47
|
+
const root = context.rootNode;
|
|
48
|
+
const existing = root['x-scalar-original-refs'];
|
|
49
|
+
const mapping = isObject(existing) ? existing : {};
|
|
50
|
+
const key = JSON.stringify(paths.get(node) ?? context.path);
|
|
51
|
+
const previous = mapping[key];
|
|
52
|
+
const original = isObject(previous) && previous.rewritten === authored ? previous.original : authored;
|
|
53
|
+
mapping[key] = { original, rewritten: node.$ref };
|
|
54
|
+
root['x-scalar-original-refs'] = mapping;
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { MediaTypeObject, SchemaObject } from '@scalar/workspace-store/schemas/v3.2/strict/openapi-document';
|
|
2
|
+
/** Multipart parts stay structured until sending so nested text can resolve environment variables. */
|
|
3
|
+
export type MultipartPart = {
|
|
4
|
+
key?: string;
|
|
5
|
+
contentType?: string;
|
|
6
|
+
headers?: Record<string, string>;
|
|
7
|
+
} & ({
|
|
8
|
+
type: 'text';
|
|
9
|
+
value: string;
|
|
10
|
+
} | {
|
|
11
|
+
type: 'file';
|
|
12
|
+
value: File;
|
|
13
|
+
} | {
|
|
14
|
+
type: 'blob';
|
|
15
|
+
value: Blob;
|
|
16
|
+
} | {
|
|
17
|
+
type: 'multipart';
|
|
18
|
+
value: MultipartPart[];
|
|
19
|
+
contentType: string;
|
|
20
|
+
});
|
|
21
|
+
/** Identify ordered multipart independently of the editor's row representation. */
|
|
22
|
+
export declare const isPositionalMultipart: (contentType: string, media: MediaTypeObject) => boolean;
|
|
23
|
+
/** Whether a media type needs ordered or nested multipart serialization. */
|
|
24
|
+
export declare const needsMultipartEncoding: (contentType: string, media: MediaTypeObject) => boolean;
|
|
25
|
+
/** Resolve a positional item's schema independently of the encoding prefix length. */
|
|
26
|
+
export declare const getMultipartItemSchema: (schema: SchemaObject | undefined, index: number, itemSchema?: MediaTypeObject["itemSchema"]) => SchemaObject | undefined;
|
|
27
|
+
/** Build ordered parts, applying prefix encodings independently of schema prefix lengths. */
|
|
28
|
+
export declare const buildMultipart: (value: unknown, contentType: string, encoding?: Pick<MediaTypeObject, "encoding" | "prefixEncoding" | "itemEncoding" | "itemSchema">, schema?: SchemaObject, nesting?: number) => MultipartPart[];
|
|
29
|
+
//# sourceMappingURL=build-multipart.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-multipart.d.ts","sourceRoot":"","sources":["../../../../src/request-example/builder/body/build-multipart.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAEV,eAAe,EACf,YAAY,EACb,MAAM,8DAA8D,CAAA;AAQrE,sGAAsG;AACtG,MAAM,MAAM,aAAa,GAAG;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACjC,GAAG,CACA;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,IAAI,CAAA;CAAE,GAC7B;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,IAAI,CAAA;CAAE,GAC7B;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,aAAa,EAAE,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CACrE,CAAA;AAED,mFAAmF;AACnF,eAAO,MAAM,qBAAqB,GAAI,aAAa,MAAM,EAAE,OAAO,eAAe,KAAG,OASnF,CAAA;AAED,4EAA4E;AAC5E,eAAO,MAAM,sBAAsB,GAAI,aAAa,MAAM,EAAE,OAAO,eAAe,KAAG,OASpF,CAAA;AA4CD,sFAAsF;AACtF,eAAO,MAAM,sBAAsB,GACjC,QAAQ,YAAY,GAAG,SAAS,EAChC,OAAO,MAAM,EACb,aAAa,eAAe,CAAC,YAAY,CAAC,KACzC,YAAY,GAAG,SAMa,CAAA;AAc/B,6FAA6F;AAC7F,eAAO,MAAM,cAAc,GACzB,OAAO,OAAO,EACd,aAAa,MAAM,EACnB,WAAU,IAAI,CAAC,eAAe,EAAE,UAAU,GAAG,gBAAgB,GAAG,cAAc,GAAG,YAAY,CAAM,EACnG,SAAS,YAAY,EACrB,gBAAW,KACV,aAAa,EAkIf,CAAA"}
|