@scalar/workspace-store 0.60.0 → 0.61.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 +48 -0
- package/README.md +6 -0
- package/dist/channel-example/build-connection-url.d.ts.map +1 -1
- package/dist/channel-example/build-connection-url.js +3 -3
- package/dist/channel-example/dedupe-requirements.d.ts +1 -1
- package/dist/channel-example/get-async-api-protocols.js +2 -2
- package/dist/channel-example/get-asyncapi-security-requirements.d.ts +1 -1
- package/dist/channel-example/get-channel-connection-security.d.ts +1 -1
- package/dist/channel-example/get-channel-operations.d.ts.map +1 -1
- package/dist/channel-example/get-channel-operations.js +4 -1
- package/dist/channel-example/get-channel-parameters.d.ts.map +1 -1
- package/dist/channel-example/get-channel-parameters.js +3 -1
- package/dist/channel-example/resolve-channel.d.ts.map +1 -1
- package/dist/channel-example/resolve-channel.js +2 -0
- package/dist/channel-example/resolve-operation-channel.d.ts.map +1 -1
- package/dist/channel-example/resolve-operation-channel.js +4 -0
- package/dist/channel-example/resolve-operation-with-traits.js +2 -2
- package/dist/channel-example/servers.d.ts.map +1 -1
- package/dist/channel-example/servers.js +3 -1
- package/dist/channel-example/types.d.ts +1 -1
- package/dist/client.d.ts +1 -1
- package/dist/client.js +3 -3
- package/dist/entities/auth/schema.d.ts +460 -20
- package/dist/entities/auth/schema.d.ts.map +1 -1
- package/dist/entities/auth/schema.js +2 -2
- package/dist/events/definitions/auth.d.ts +2 -2
- package/dist/events/definitions/document.d.ts +1 -1
- package/dist/events/definitions/operation.d.ts +3 -2
- package/dist/events/definitions/operation.d.ts.map +1 -1
- package/dist/events/definitions/server.d.ts +1 -1
- package/dist/events/old-definitions.d.ts +1 -1
- package/dist/helpers/create-chunk-writer.d.ts +6 -0
- package/dist/helpers/create-chunk-writer.d.ts.map +1 -0
- package/dist/helpers/create-chunk-writer.js +44 -0
- package/dist/helpers/dynamic-ref.d.ts +13 -2
- package/dist/helpers/dynamic-ref.d.ts.map +1 -1
- package/dist/helpers/dynamic-ref.js +20 -7
- package/dist/helpers/encode-chunk-name.d.ts +3 -0
- package/dist/helpers/encode-chunk-name.d.ts.map +1 -0
- package/dist/helpers/encode-chunk-name.js +9 -0
- package/dist/helpers/for-each-path-item-operation.d.ts +2 -2
- package/dist/helpers/get-first-server.d.ts +1 -1
- package/dist/helpers/get-resolved-ref.d.ts +6 -1
- package/dist/helpers/get-resolved-ref.d.ts.map +1 -1
- package/dist/helpers/get-resolved-ref.js +3 -10
- package/dist/helpers/is-non-optional-security-requirement.d.ts +1 -1
- package/dist/helpers/merge-object.d.ts +2 -2
- package/dist/helpers/merge-object.d.ts.map +1 -1
- package/dist/helpers/merge-object.js +2 -5
- package/dist/mutators/auth.d.ts +1 -1
- package/dist/mutators/auth.d.ts.map +1 -1
- package/dist/mutators/auth.js +9 -4
- package/dist/mutators/index.d.ts +10 -10
- package/dist/mutators/operation/body.js +2 -2
- package/dist/mutators/operation/helpers/fetch-request-to-har.d.ts.map +1 -1
- package/dist/mutators/operation/helpers/fetch-request-to-har.js +12 -2
- package/dist/mutators/operation/helpers/har-to-operation.d.ts +1 -1
- package/dist/mutators/operation/helpers/har-to-operation.d.ts.map +1 -1
- package/dist/mutators/operation/helpers/har-to-operation.js +9 -5
- package/dist/mutators/operation/helpers/sync-path-parameters.d.ts +2 -2
- package/dist/mutators/operation/history.js +2 -2
- package/dist/mutators/operation/operation.d.ts.map +1 -1
- package/dist/mutators/operation/operation.js +4 -0
- package/dist/mutators/operation/parameters.js +1 -1
- package/dist/mutators/server.d.ts +3 -3
- package/dist/mutators/server.js +1 -1
- package/dist/mutators/tag.d.ts.map +1 -1
- package/dist/mutators/tag.js +4 -0
- package/dist/navigation/helpers/get-openapi-object.d.ts +1 -1
- package/dist/navigation/helpers/traverse-asyncapi-document.d.ts.map +1 -1
- package/dist/navigation/helpers/traverse-asyncapi-document.js +2 -2
- package/dist/navigation/helpers/traverse-description.d.ts +1 -1
- package/dist/navigation/helpers/traverse-document.d.ts +1 -1
- package/dist/navigation/helpers/traverse-examples.d.ts +12 -1
- package/dist/navigation/helpers/traverse-examples.d.ts.map +1 -1
- package/dist/navigation/helpers/traverse-examples.js +22 -1
- package/dist/navigation/helpers/traverse-paths.d.ts +1 -1
- package/dist/navigation/helpers/traverse-schemas.d.ts +1 -1
- package/dist/navigation/helpers/traverse-tags.d.ts +1 -1
- package/dist/navigation/helpers/traverse-webhooks.d.ts +1 -1
- package/dist/navigation/helpers/update-order-ids.d.ts +2 -2
- package/dist/navigation/index.d.ts +1 -0
- package/dist/navigation/index.d.ts.map +1 -1
- package/dist/navigation/index.js +1 -0
- package/dist/navigation/types.d.ts +1 -1
- package/dist/persistence/index.d.ts.map +1 -1
- package/dist/persistence/index.js +10 -10
- package/dist/persistence/indexdb.d.ts.map +1 -1
- package/dist/persistence/indexdb.js +7 -5
- package/dist/persistence/migrations/v2-team-to-local.d.ts.map +1 -1
- package/dist/persistence/migrations/v2-team-to-local.js +3 -4
- package/dist/plugins/bundler/index.d.ts +5 -2
- package/dist/plugins/bundler/index.d.ts.map +1 -1
- package/dist/plugins/bundler/index.js +24 -26
- package/dist/request-example/builder/body/build-request-body.d.ts +2 -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 +41 -5
- package/dist/request-example/builder/body/encode-multipart-body.d.ts +9 -0
- package/dist/request-example/builder/body/encode-multipart-body.d.ts.map +1 -0
- package/dist/request-example/builder/body/encode-multipart-body.js +29 -0
- package/dist/request-example/builder/body/get-request-body-example.d.ts +1 -1
- package/dist/request-example/builder/body/get-selected-body-content-type.d.ts +1 -1
- package/dist/request-example/builder/body/schema-value-coercion.d.ts +1 -1
- package/dist/request-example/builder/body/schema-value-coercion.js +1 -1
- package/dist/request-example/builder/body/serialize-form-property.d.ts +1 -1
- package/dist/request-example/builder/body/serialize-multipart-array.d.ts +16 -0
- package/dist/request-example/builder/body/serialize-multipart-array.d.ts.map +1 -0
- package/dist/request-example/builder/body/serialize-multipart-array.js +37 -0
- package/dist/request-example/builder/build-request.d.ts.map +1 -1
- package/dist/request-example/builder/build-request.js +12 -7
- package/dist/request-example/builder/header/build-request-parameters.d.ts +1 -1
- package/dist/request-example/builder/header/build-request-parameters.d.ts.map +1 -1
- package/dist/request-example/builder/header/build-request-parameters.js +7 -1
- package/dist/request-example/builder/header/de-serialize-parameter.d.ts +1 -1
- package/dist/request-example/builder/header/de-serialize-parameter.d.ts.map +1 -1
- package/dist/request-example/builder/header/de-serialize-parameter.js +2 -1
- package/dist/request-example/builder/header/is-param-disabled.d.ts +1 -1
- package/dist/request-example/builder/header/serialize-parameter.d.ts.map +1 -1
- package/dist/request-example/builder/header/serialize-parameter.js +13 -14
- package/dist/request-example/builder/helpers/get-example-from-schema.d.ts +9 -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 +255 -20
- package/dist/request-example/builder/helpers/get-example.d.ts +1 -1
- package/dist/request-example/builder/helpers/get-example.js +2 -2
- package/dist/request-example/builder/helpers/get-resolved-url.d.ts +1 -1
- package/dist/request-example/builder/helpers/get-server-variables.d.ts +1 -1
- package/dist/request-example/builder/index.d.ts +1 -0
- package/dist/request-example/builder/index.d.ts.map +1 -1
- package/dist/request-example/builder/index.js +1 -0
- package/dist/request-example/builder/request-factory.d.ts +2 -2
- package/dist/request-example/builder/security/broker-scheme-types.d.ts.map +1 -1
- package/dist/request-example/builder/security/broker-scheme-types.js +2 -2
- package/dist/request-example/builder/security/build-request-security.d.ts.map +1 -1
- package/dist/request-example/builder/security/build-request-security.js +3 -4
- package/dist/request-example/builder/security/secret-types.d.ts +13 -4
- package/dist/request-example/builder/security/secret-types.d.ts.map +1 -1
- package/dist/request-example/context/get-request-example-context.d.ts +3 -3
- package/dist/request-example/context/get-request-example-context.js +1 -1
- package/dist/request-example/context/headers.d.ts +1 -1
- package/dist/request-example/context/headers.js +1 -1
- package/dist/request-example/context/helpers/combine-params.d.ts +1 -1
- package/dist/request-example/context/security/extract-security-scheme-secrets.d.ts +16 -3
- 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 +21 -19
- package/dist/request-example/context/security/get-security-requirements.d.ts +2 -2
- package/dist/request-example/context/security/get-security-schemes.d.ts +1 -1
- package/dist/request-example/context/security/get-selected-security.d.ts +1 -1
- package/dist/request-example/context/security/is-auth-optional.d.ts +1 -1
- package/dist/request-example/context/security/merge-security.d.ts +3 -3
- package/dist/request-example/context/security/merge-security.d.ts.map +1 -1
- package/dist/request-example/context/security/merge-security.js +40 -11
- package/dist/request-example/context/servers.d.ts +2 -2
- package/dist/request-example/functions.d.ts.map +1 -1
- package/dist/request-example/index.d.ts +1 -1
- package/dist/request-example/index.d.ts.map +1 -1
- package/dist/request-example/index.js +1 -1
- package/dist/resolve.d.ts +1 -1
- package/dist/resolve.js +1 -1
- package/dist/schemas/navigation.d.ts +4 -4
- package/dist/schemas/navigation.js +1 -1
- package/dist/schemas/reference-config/index.d.ts +92 -4
- package/dist/schemas/reference-config/index.d.ts.map +1 -1
- package/dist/schemas/reference-config/settings.d.ts +93 -5
- package/dist/schemas/reference-config/settings.d.ts.map +1 -1
- package/dist/schemas/reference-config/settings.js +1 -1
- package/dist/schemas/type-guards.d.ts +1 -1
- package/dist/schemas/v3.1/openapi/index.d.ts.map +1 -1
- package/dist/schemas/v3.1/openapi/index.js +11 -1
- package/dist/schemas/v3.1/strict/openapi-document.d.ts +210 -0
- package/dist/schemas/v3.1/strict/openapi-document.d.ts.map +1 -1
- package/dist/schemas/v3.1/strict/security-scheme.d.ts +13 -1
- package/dist/schemas/v3.1/strict/security-scheme.d.ts.map +1 -1
- package/dist/schemas/v3.1/strict/security-scheme.js +11 -1
- package/dist/schemas/v3.2/openapi/index.d.ts +2 -0
- package/dist/schemas/v3.2/openapi/index.d.ts.map +1 -1
- package/dist/schemas/v3.2/openapi/index.js +13 -1
- package/dist/schemas/v3.2/strict/oauth-flow.d.ts +23 -1
- package/dist/schemas/v3.2/strict/oauth-flow.d.ts.map +1 -1
- package/dist/schemas/v3.2/strict/oauth-flow.js +6 -1
- package/dist/schemas/v3.2/strict/oauthflows.d.ts +20 -0
- package/dist/schemas/v3.2/strict/oauthflows.d.ts.map +1 -1
- package/dist/schemas/v3.2/strict/openapi-document.d.ts +1439 -141
- package/dist/schemas/v3.2/strict/openapi-document.d.ts.map +1 -1
- package/dist/schemas/v3.2/strict/openapi-document.js +2 -1
- package/dist/schemas/v3.2/strict/security-scheme.d.ts +29 -6
- package/dist/schemas/v3.2/strict/security-scheme.d.ts.map +1 -1
- package/dist/schemas/v3.2/strict/security-scheme.js +16 -3
- package/dist/schemas/workspace-specification/index.d.ts +1 -1
- package/dist/schemas/workspace.d.ts +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +23 -27
- package/package.json +8 -8
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { HTTP_METHODS } from '@scalar/helpers/http/http-methods';
|
|
7
7
|
import { isObject } from '@scalar/helpers/object/is-object';
|
|
8
|
+
import { isSchemaPath } from '@scalar/helpers/openapi/is-schema-path';
|
|
9
|
+
import { resolveReferencePath } from '@scalar/json-magic/bundle';
|
|
8
10
|
import { isLocalRef } from '../../helpers/general.js';
|
|
9
11
|
import { syncParametersForPathChange, } from '../../mutators/operation/helpers/sync-path-parameters.js';
|
|
10
12
|
import { getResolvedRef } from '../../plugins/bundler/helpers.js';
|
|
@@ -49,15 +51,18 @@ export const externalValueResolver = () => {
|
|
|
49
51
|
if (typeof externalValue !== 'string') {
|
|
50
52
|
return;
|
|
51
53
|
}
|
|
52
|
-
|
|
54
|
+
// `externalValue` may be relative (for example `/examples/pet.json`). Resolve it against the
|
|
55
|
+
// origin of the document it lives in so it becomes an absolute URL a loader can fetch.
|
|
56
|
+
const resolvedValue = resolveReferencePath(context.origin, externalValue);
|
|
57
|
+
const loader = context.loaders.find((it) => it.validate(resolvedValue));
|
|
53
58
|
// We can not process the external value
|
|
54
59
|
if (!loader) {
|
|
55
60
|
return;
|
|
56
61
|
}
|
|
57
|
-
if (!cache.has(
|
|
58
|
-
cache.set(
|
|
62
|
+
if (!cache.has(resolvedValue)) {
|
|
63
|
+
cache.set(resolvedValue, loader.exec(resolvedValue));
|
|
59
64
|
}
|
|
60
|
-
const result = await cache.get(
|
|
65
|
+
const result = await cache.get(resolvedValue);
|
|
61
66
|
// If fetch is successful, assign the data to the node's 'value' property
|
|
62
67
|
if (result?.ok) {
|
|
63
68
|
node['value'] = result.data;
|
|
@@ -199,35 +204,28 @@ export const normalizeAuthSchemes = () => {
|
|
|
199
204
|
};
|
|
200
205
|
/**
|
|
201
206
|
* Lifecycle plugin to normalize $ref nodes:
|
|
202
|
-
* Ensures that for any
|
|
207
|
+
* Ensures that for any OpenAPI Reference Object containing a $ref, only $ref,
|
|
203
208
|
* summary, description, and $status properties are preserved.
|
|
204
209
|
* This keeps $ref references clean and predictable for downstream consumers.
|
|
210
|
+
*
|
|
211
|
+
* Schema Objects are deliberately skipped: in JSON Schema 2020-12 a $ref may
|
|
212
|
+
* carry sibling keywords, so their siblings must not be stripped.
|
|
205
213
|
*/
|
|
206
214
|
export const normalizeRefs = () => {
|
|
207
215
|
return {
|
|
208
216
|
type: 'lifecycle',
|
|
209
217
|
onBeforeNodeProcess: (node, context) => {
|
|
210
|
-
const { path } = context;
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
//
|
|
220
|
-
const keepProperties = new Set([
|
|
221
|
-
'$ref',
|
|
222
|
-
'summary',
|
|
223
|
-
'description',
|
|
224
|
-
'$status',
|
|
225
|
-
'$id',
|
|
226
|
-
'$anchor',
|
|
227
|
-
'$dynamicAnchor',
|
|
228
|
-
'$dynamicRef',
|
|
229
|
-
'$defs',
|
|
230
|
-
]);
|
|
218
|
+
const { path, referencedFromPath } = context;
|
|
219
|
+
const isSchema = isSchemaPath(path) || isSchemaPath(referencedFromPath);
|
|
220
|
+
// Normalization only applies to OpenAPI Reference Objects, where a `$ref` may sit next to nothing but
|
|
221
|
+
// `summary` and `description`. Schema Objects are left untouched: in JSON Schema 2020-12 a `$ref` may
|
|
222
|
+
// legally carry sibling keywords — for example a `$defs`/`$dynamicAnchor` binding that specializes a
|
|
223
|
+
// generic template (the `Paginated<T>` pattern) — and such schemas appear inline, in reusable schemas,
|
|
224
|
+
// and in raw external schema documents. Stripping those siblings would discard the binding and leave
|
|
225
|
+
// `$dynamicRef` resolving to the template's empty fallback. See https://github.com/scalar/scalar/issues/9414.
|
|
226
|
+
if (typeof node['$ref'] === 'string' && !isSchema) {
|
|
227
|
+
// Remove any other properties from the node and only keep the '$ref', 'summary', 'description' and '$status'
|
|
228
|
+
const keepProperties = new Set(['$ref', 'summary', 'description', '$status']);
|
|
231
229
|
Object.keys(node).forEach((key) => {
|
|
232
230
|
if (!keepProperties.has(key)) {
|
|
233
231
|
delete node[key];
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import type { RequestBodyObject } from '@scalar/workspace-store/schemas/v3.
|
|
1
|
+
import type { RequestBodyObject } from '@scalar/workspace-store/schemas/v3.2/strict/request-body';
|
|
2
2
|
type FormData = {
|
|
3
3
|
mode: 'formdata';
|
|
4
4
|
value: ({
|
|
5
5
|
type: 'text';
|
|
6
6
|
key: string;
|
|
7
7
|
value: string;
|
|
8
|
+
contentType?: string;
|
|
8
9
|
} | {
|
|
9
10
|
type: 'file';
|
|
10
11
|
key: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-request-body.d.ts","sourceRoot":"","sources":["../../../../src/request-example/builder/body/build-request-body.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0DAA0D,CAAA;
|
|
1
|
+
{"version":3,"file":"build-request-body.d.ts","sourceRoot":"","sources":["../../../../src/request-example/builder/body/build-request-body.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0DAA0D,CAAA;AASjG,KAAK,QAAQ,GAAG;IACd,IAAI,EAAE,UAAU,CAAA;IAChB,KAAK,EAAE,CACH;QACE,IAAI,EAAE,MAAM,CAAA;QACZ,GAAG,EAAE,MAAM,CAAA;QACX,KAAK,EAAE,MAAM,CAAA;QACb,WAAW,CAAC,EAAE,MAAM,CAAA;KACrB,GACD;QACE,IAAI,EAAE,MAAM,CAAA;QACZ,GAAG,EAAE,MAAM,CAAA;QACX,KAAK,EAAE,IAAI,CAAA;QACX,WAAW,CAAC,EAAE,MAAM,CAAA;KACrB,GACD;QACE,IAAI,EAAE,MAAM,CAAA;QACZ,GAAG,EAAE,MAAM,CAAA;QACX,KAAK,EAAE,IAAI,CAAA;QACX,WAAW,CAAC,EAAE,MAAM,CAAA;KACrB,CACJ,EAAE,CAAA;CACJ,CAAA;AAwBD,KAAK,UAAU,GAAG;IAChB,IAAI,EAAE,YAAY,CAAA;IAClB,KAAK,EAAE;QACL,GAAG,EAAE,MAAM,CAAA;QACX,KAAK,EAAE,MAAM,CAAA;KACd,EAAE,CAAA;CACJ,CAAA;AAED,KAAK,GAAG,GAAG;IACT,IAAI,EAAE,KAAK,CAAA;IACX,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAA;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAAA;AAED,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,UAAU,GAAG,GAAG,CAAA;AAKrD;;GAEG;AACH,eAAO,MAAM,gBAAgB,GAC3B,aAAa,iBAAiB,GAAG,SAAS;AAC1C,qCAAqC;AACrC,oBAAuB;AACvB,sEAAsE;AACtE,kCAAkC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KACvD,WAAW,GAAG,IAuUhB,CAAA"}
|
|
@@ -3,11 +3,32 @@ import { isObject } from '@scalar/helpers/object/is-object';
|
|
|
3
3
|
import { setValueAtPath } from '@scalar/helpers/object/set-value-at-path';
|
|
4
4
|
import { getResolvedRef, mergeSiblingReferences } from '@scalar/workspace-store/helpers/get-resolved-ref';
|
|
5
5
|
import { unpackProxyObject } from '@scalar/workspace-store/helpers/unpack-proxy';
|
|
6
|
-
import { isObjectSchema } from '@scalar/workspace-store/schemas/v3.
|
|
6
|
+
import { isObjectSchema } from '@scalar/workspace-store/schemas/v3.2/strict/type-guards';
|
|
7
7
|
import { getExampleFromBody } from './get-request-body-example.js';
|
|
8
8
|
import { getSelectedBodyContentType } from './get-selected-body-content-type.js';
|
|
9
9
|
import { buildDottedNestedRowPredicate, coerceLeafValueToSchemaType, resolveLeafSchema } from './schema-value-coercion.js';
|
|
10
10
|
import { serializeFormPropertyWithEncoding } from './serialize-form-property.js';
|
|
11
|
+
import { serializeMultipartArray } from './serialize-multipart-array.js';
|
|
12
|
+
/** Preserve per-item media types while keeping uploaded file bytes and names intact. */
|
|
13
|
+
const toMultipartPart = (part) => {
|
|
14
|
+
if (part.value instanceof File) {
|
|
15
|
+
const file = part.value;
|
|
16
|
+
return {
|
|
17
|
+
type: 'file',
|
|
18
|
+
key: part.key,
|
|
19
|
+
value: part.contentType && part.contentType !== file.type
|
|
20
|
+
? new File([file], file.name, { type: part.contentType, lastModified: file.lastModified })
|
|
21
|
+
: file,
|
|
22
|
+
contentType: part.contentType,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
type: 'text',
|
|
27
|
+
key: part.key,
|
|
28
|
+
value: part.value,
|
|
29
|
+
...(part.contentType ? { contentType: part.contentType } : {}),
|
|
30
|
+
};
|
|
31
|
+
};
|
|
11
32
|
const getMultipartEncodingContentType = (requestBody, bodyContentType, fieldName) => requestBody.content[bodyContentType]?.encoding?.[fieldName]?.contentType;
|
|
12
33
|
/**
|
|
13
34
|
* Create the fetch request body
|
|
@@ -103,6 +124,16 @@ requestBodyCompositionSelection) => {
|
|
|
103
124
|
return;
|
|
104
125
|
}
|
|
105
126
|
const partEncoding = requestBody.content[bodyContentType]?.encoding?.[name];
|
|
127
|
+
if (result.mode === 'formdata') {
|
|
128
|
+
// Older saved form rows store JSON text. Only restore arrays declared by the schema.
|
|
129
|
+
const schema = resolveLeafSchema(multipartSchema, [name]);
|
|
130
|
+
const restored = coerceLeafValueToSchemaType(value, schema);
|
|
131
|
+
const arrayParts = serializeMultipartArray(name, Array.isArray(restored) ? restored : value, partEncoding);
|
|
132
|
+
if (arrayParts) {
|
|
133
|
+
result.value.push(...arrayParts.map(toMultipartPart));
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
106
137
|
// When the encoding sets style/explode, serialize objects/arrays RFC6570-style
|
|
107
138
|
// (bracket or exploded notation) instead of JSON, so the wire request matches the
|
|
108
139
|
// generated code snippet.
|
|
@@ -139,9 +170,9 @@ requestBodyCompositionSelection) => {
|
|
|
139
170
|
const serializedValue = typeof value === 'object' && value !== null ? JSON.stringify(unpackProxyObject(value)) : String(value);
|
|
140
171
|
if (result.mode === 'formdata' && partContentType) {
|
|
141
172
|
return result.value.push({
|
|
142
|
-
type: '
|
|
173
|
+
type: 'text',
|
|
143
174
|
key: name,
|
|
144
|
-
value:
|
|
175
|
+
value: serializedValue,
|
|
145
176
|
contentType: partContentType,
|
|
146
177
|
});
|
|
147
178
|
}
|
|
@@ -203,6 +234,11 @@ requestBodyCompositionSelection) => {
|
|
|
203
234
|
continue;
|
|
204
235
|
}
|
|
205
236
|
const partEncoding = requestBody.content[bodyContentType]?.encoding?.[key];
|
|
237
|
+
const arrayParts = serializeMultipartArray(key, value, partEncoding);
|
|
238
|
+
if (arrayParts) {
|
|
239
|
+
result.value.push(...arrayParts.map(toMultipartPart));
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
206
242
|
// Encoding style/explode turns objects into bracket or exploded notation instead of
|
|
207
243
|
// the default single JSON part.
|
|
208
244
|
const styleParts = serializeFormPropertyWithEncoding(key, value, partEncoding);
|
|
@@ -232,9 +268,9 @@ requestBodyCompositionSelection) => {
|
|
|
232
268
|
const serializedValue = typeof value === 'object' && value !== null ? JSON.stringify(unpackProxyObject(value)) : String(value);
|
|
233
269
|
if (partContentType) {
|
|
234
270
|
result.value.push({
|
|
235
|
-
type: '
|
|
271
|
+
type: 'text',
|
|
236
272
|
key,
|
|
237
|
-
value:
|
|
273
|
+
value: serializedValue,
|
|
238
274
|
contentType: partContentType,
|
|
239
275
|
});
|
|
240
276
|
continue;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { RequestBody } from './build-request-body.js';
|
|
2
|
+
/**
|
|
3
|
+
* Encode typed text fields without turning them into file uploads.
|
|
4
|
+
* Blob parts retain binary bytes and keep request construction synchronous.
|
|
5
|
+
*/
|
|
6
|
+
export declare const encodeMultipartBody: (parts: Extract<RequestBody, {
|
|
7
|
+
mode: "formdata";
|
|
8
|
+
}>["value"]) => Blob;
|
|
9
|
+
//# sourceMappingURL=encode-multipart-body.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encode-multipart-body.d.ts","sourceRoot":"","sources":["../../../../src/request-example/builder/body/encode-multipart-body.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAUvD;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAAI,OAAO,OAAO,CAAC,WAAW,EAAE;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,CAAC,CAAC,OAAO,CAAC,KAAG,IAqBhG,CAAA"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/** Escape disposition parameters using the same percent escapes as browser form submissions. */
|
|
2
|
+
const escapeParameter = (value) => value
|
|
3
|
+
.replace(/\r\n|\r|\n/g, '\r\n')
|
|
4
|
+
.replace(/\r/g, '%0D')
|
|
5
|
+
.replace(/\n/g, '%0A')
|
|
6
|
+
.replace(/"/g, '%22');
|
|
7
|
+
/**
|
|
8
|
+
* Encode typed text fields without turning them into file uploads.
|
|
9
|
+
* Blob parts retain binary bytes and keep request construction synchronous.
|
|
10
|
+
*/
|
|
11
|
+
export const encodeMultipartBody = (parts) => {
|
|
12
|
+
// getRandomValues also works on HTTP playgrounds, where randomUUID is unavailable.
|
|
13
|
+
const random = crypto.getRandomValues(new Uint8Array(24));
|
|
14
|
+
const boundary = `----scalar-${Array.from(random, (byte) => byte.toString(16).padStart(2, '0')).join('')}`;
|
|
15
|
+
const chunks = parts.flatMap((part) => {
|
|
16
|
+
const filename = part.type === 'file' ? part.value.name : part.type === 'blob' ? 'blob' : undefined;
|
|
17
|
+
const contentType = part.contentType ?? (part.type === 'text' ? undefined : part.value.type || 'application/octet-stream');
|
|
18
|
+
// A media type comes from the API description and must never inject part headers.
|
|
19
|
+
if (contentType && /[\r\n\0]/.test(contentType)) {
|
|
20
|
+
throw new Error('Invalid multipart content type');
|
|
21
|
+
}
|
|
22
|
+
const disposition = `Content-Disposition: form-data; name="${escapeParameter(part.key)}"${filename === undefined ? '' : `; filename="${escapeParameter(filename)}"`}`;
|
|
23
|
+
const headers = `--${boundary}\r\n${disposition}\r\n${contentType ? `Content-Type: ${contentType}\r\n` : ''}\r\n`;
|
|
24
|
+
// Match native FormData line endings for ordinary text; explicitly typed data keeps its bytes.
|
|
25
|
+
const value = part.type === 'text' && !part.contentType ? part.value.replace(/\r\n|\r|\n/g, '\r\n') : part.value;
|
|
26
|
+
return [headers, value, '\r\n'];
|
|
27
|
+
});
|
|
28
|
+
return new Blob([...chunks, `--${boundary}--\r\n`], { type: `multipart/form-data; boundary=${boundary}` });
|
|
29
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ExampleObject, RequestBodyObject } from '@scalar/workspace-store/schemas/v3.
|
|
1
|
+
import type { ExampleObject, RequestBodyObject } from '@scalar/workspace-store/schemas/v3.2/strict/openapi-document';
|
|
2
2
|
/**
|
|
3
3
|
* Generate a write-mode example directly from a request body's schema, ignoring any stored example.
|
|
4
4
|
*
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { RequestBodyObject } from '@scalar/workspace-store/schemas/v3.
|
|
1
|
+
import type { RequestBodyObject } from '@scalar/workspace-store/schemas/v3.2/strict/request-body';
|
|
2
2
|
/**
|
|
3
3
|
* Returns the selected body content type for the given request body and exampleKey.
|
|
4
4
|
* Priority:
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { SchemaObject } from '@scalar/workspace-store/schemas/v3.
|
|
1
|
+
import type { SchemaObject } from '@scalar/workspace-store/schemas/v3.2/strict/openapi-document';
|
|
2
2
|
/**
|
|
3
3
|
* Walk an object schema along a dotted-row path and return the resolved leaf schema,
|
|
4
4
|
* or undefined when any segment is not a declared object property.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getResolvedRef, mergeSiblingReferences } from '@scalar/workspace-store/helpers/get-resolved-ref';
|
|
2
|
-
import { isObjectSchema } from '@scalar/workspace-store/schemas/v3.
|
|
2
|
+
import { isObjectSchema } from '@scalar/workspace-store/schemas/v3.2/strict/type-guards';
|
|
3
3
|
/** Normalize a schema's `type` (string | string[] | absent) into a plain string array. */
|
|
4
4
|
const normalizeSchemaTypes = (schema) => {
|
|
5
5
|
const type = 'type' in schema ? schema.type : undefined;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { EncodingObject } from '@scalar/workspace-store/schemas/v3.
|
|
1
|
+
import type { EncodingObject } from '@scalar/workspace-store/schemas/v3.2/strict/openapi-document';
|
|
2
2
|
/** A single serialized form field, ready to become a multipart part or a urlencoded pair. */
|
|
3
3
|
export type SerializedFormProperty = {
|
|
4
4
|
key: string;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { EncodingObject } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document';
|
|
2
|
+
/** A multipart array item shared by the request builder and code snippets. */
|
|
3
|
+
export type MultipartArrayPart = {
|
|
4
|
+
key: string;
|
|
5
|
+
value: string | File;
|
|
6
|
+
contentType?: string;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Named multipart arrays produce one part per item, using the same property name.
|
|
10
|
+
* Encoding applies to each item, including its content type. Without an explicit
|
|
11
|
+
* style, nested arrays remain individual JSON values instead of expanding again.
|
|
12
|
+
*
|
|
13
|
+
* @see https://spec.openapis.org/oas/v3.2.0.html#encoding-by-name
|
|
14
|
+
*/
|
|
15
|
+
export declare const serializeMultipartArray: (key: string, value: unknown, encoding?: EncodingObject) => MultipartArrayPart[] | null;
|
|
16
|
+
//# sourceMappingURL=serialize-multipart-array.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serialize-multipart-array.d.ts","sourceRoot":"","sources":["../../../../src/request-example/builder/body/serialize-multipart-array.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8DAA8D,CAAA;AAIlG,8EAA8E;AAC9E,MAAM,MAAM,kBAAkB,GAAG;IAC/B,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,GAClC,KAAK,MAAM,EACX,OAAO,OAAO,EACd,WAAW,cAAc,KACxB,kBAAkB,EAAE,GAAG,IA+BzB,CAAA"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { parseMimeType } from '@scalar/helpers/http/mime-type';
|
|
2
|
+
import { unpackProxyObject } from '@scalar/workspace-store/helpers/unpack-proxy';
|
|
3
|
+
import { serializeFormPropertyWithEncoding } from './serialize-form-property.js';
|
|
4
|
+
/**
|
|
5
|
+
* Named multipart arrays produce one part per item, using the same property name.
|
|
6
|
+
* Encoding applies to each item, including its content type. Without an explicit
|
|
7
|
+
* style, nested arrays remain individual JSON values instead of expanding again.
|
|
8
|
+
*
|
|
9
|
+
* @see https://spec.openapis.org/oas/v3.2.0.html#encoding-by-name
|
|
10
|
+
*/
|
|
11
|
+
export const serializeMultipartArray = (key, value, encoding) => {
|
|
12
|
+
if (!Array.isArray(value)) {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
const hasStyle = encoding?.style !== undefined || encoding?.explode !== undefined || encoding?.allowReserved !== undefined;
|
|
16
|
+
const contentType = hasStyle ? undefined : encoding?.contentType;
|
|
17
|
+
return value.flatMap((item) => {
|
|
18
|
+
const parts = serializeFormPropertyWithEncoding(key, item, encoding);
|
|
19
|
+
if (parts) {
|
|
20
|
+
return parts;
|
|
21
|
+
}
|
|
22
|
+
if (item instanceof File) {
|
|
23
|
+
return [{ key, value: unpackProxyObject(item), ...(contentType ? { contentType } : {}) }];
|
|
24
|
+
}
|
|
25
|
+
const structured = typeof item === 'object' && item !== null;
|
|
26
|
+
const itemContentType = contentType ?? (!hasStyle && structured ? 'application/json' : undefined);
|
|
27
|
+
const subtype = itemContentType ? parseMimeType(itemContentType).subtype : undefined;
|
|
28
|
+
const isJson = subtype === 'json' || subtype?.endsWith('+json');
|
|
29
|
+
return [
|
|
30
|
+
{
|
|
31
|
+
key,
|
|
32
|
+
value: structured || isJson ? JSON.stringify(unpackProxyObject(item)) : String(item),
|
|
33
|
+
...(itemContentType ? { contentType: itemContentType } : {}),
|
|
34
|
+
},
|
|
35
|
+
];
|
|
36
|
+
});
|
|
37
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-request.d.ts","sourceRoot":"","sources":["../../../src/request-example/builder/build-request.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,MAAM,EAAW,MAAM,8BAA8B,CAAA;
|
|
1
|
+
{"version":3,"file":"build-request.d.ts","sourceRoot":"","sources":["../../../src/request-example/builder/build-request.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,MAAM,EAAW,MAAM,8BAA8B,CAAA;AAQnE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2CAA2C,CAAA;AAC/E,OAAO,EACL,KAAK,6BAA6B,EAEnC,MAAM,uDAAuD,CAAA;AAK9D;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;AAuClD;;;;;;;GAOG;AACH,eAAO,MAAM,2BAA2B,GACtC,SAAS,cAAc,EACvB,cAAc,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACpC,iBAAiB;IAAE,6BAA6B,CAAC,EAAE,OAAO,CAAA;CAAE,KAC3D,MAyBF,CAAA;AAED;;;;;KAKK;AACL,MAAM,MAAM,gBAAgB,GAAG;IAC7B,kGAAkG;IAClG,cAAc,EAAE,cAAc,CAAA;IAC9B,2BAA2B;IAC3B,UAAU,EAAE,eAAe,CAAA;IAC3B,0DAA0D;IAC1D,YAAY,EAAE,OAAO,CAAA;CACtB,CAAA;AAED,wGAAwG;AACxG,eAAO,MAAM,oBAAoB,EAAG,sBAA+B,CAAA;AAEnE,MAAM,MAAM,uBAAuB,GAAG,6BAA6B,GAAG,OAAO,oBAAoB,CAAA;AAEjG,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,gBAAgB,EAAE,uBAAuB,CAAC,CAAA;AAElF,eAAO,MAAM,YAAY,GACvB,SAAS,cAAc,EACvB,SAAS;IACP,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACpC;;;OAGG;IACH,6BAA6B,CAAC,EAAE,OAAO,CAAA;CACxC,KACA,kBAMF,CAAA"}
|
|
@@ -4,6 +4,7 @@ import { err, ok } from '@scalar/helpers/types/result';
|
|
|
4
4
|
import { safeRun } from '@scalar/helpers/types/safe-run';
|
|
5
5
|
import { redirectToProxy, shouldUseProxy } from '@scalar/helpers/url/redirect-to-proxy';
|
|
6
6
|
import { encode as encodeBase64 } from 'js-base64';
|
|
7
|
+
import { encodeMultipartBody } from '../../request-example/builder/body/encode-multipart-body.js';
|
|
7
8
|
import { buildRequestCookieHeader } from '../../request-example/builder/header/build-request-cookie-header.js';
|
|
8
9
|
import { applyAllowReservedToUrl } from '../../request-example/builder/helpers/apply-allow-reserved-to-url.js';
|
|
9
10
|
import { resolveRequestFactoryUrl, } from '../../request-example/builder/resolve-request-factory-url.js';
|
|
@@ -93,14 +94,18 @@ const buildRequestInner = (request, options) => {
|
|
|
93
94
|
return request.body.value;
|
|
94
95
|
}
|
|
95
96
|
if (request.body?.mode === 'formdata') {
|
|
97
|
+
const parts = request.body.value.map((item) => ({
|
|
98
|
+
...item,
|
|
99
|
+
key: replaceEnvVariables(item.key, replace),
|
|
100
|
+
}));
|
|
101
|
+
const resolvedParts = parts.map((item) => item.type === 'text' ? { ...item, value: replaceEnvVariables(item.value, replace) } : item);
|
|
102
|
+
if (request.body.value.some((item) => item.type === 'text' && item.contentType)) {
|
|
103
|
+
const encoded = encodeMultipartBody(resolvedParts);
|
|
104
|
+
headers.set('content-type', encoded.type);
|
|
105
|
+
return encoded;
|
|
106
|
+
}
|
|
96
107
|
const form = new FormData();
|
|
97
|
-
|
|
98
|
-
if (item.type === 'text') {
|
|
99
|
-
form.append(replaceEnvVariables(item.key, replace), replaceEnvVariables(item.value, replace));
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
form.append(replaceEnvVariables(item.key, replace), item.value);
|
|
103
|
-
});
|
|
108
|
+
resolvedParts.forEach((item) => form.append(item.key, item.value));
|
|
104
109
|
return form;
|
|
105
110
|
}
|
|
106
111
|
if (request.body?.mode === 'urlencoded') {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type XScalarCookie } from '@scalar/workspace-store/schemas/extensions/general/x-scalar-cookies';
|
|
2
|
-
import type { ParameterObject, ReferenceType } from '@scalar/workspace-store/schemas/v3.
|
|
2
|
+
import type { ParameterObject, ReferenceType } from '@scalar/workspace-store/schemas/v3.2/strict/openapi-document';
|
|
3
3
|
/**
|
|
4
4
|
* Converts the parameters into a set of headers, cookies and url params while
|
|
5
5
|
* replacing environment variables and extracting example values. Also builds up a record of the path
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-request-parameters.d.ts","sourceRoot":"","sources":["../../../../src/request-example/builder/header/build-request-parameters.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,aAAa,EAEnB,MAAM,qEAAqE,CAAA;AAE5E,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,8DAA8D,CAAA;AAoBlH;;;;;;;;;GASG;AACH,eAAO,MAAM,sBAAsB;AACjC,qBAAqB;AACrB,aAAY,aAAa,CAAC,eAAe,CAAC,EAAO;AACjD,qCAAqC;AACrC,cAAa,MAAkB,KAC9B;IACD,OAAO,EAAE,aAAa,EAAE,CAAA;IACxB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/B,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACrC,4BAA4B,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IACzC,SAAS,EAAE,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"build-request-parameters.d.ts","sourceRoot":"","sources":["../../../../src/request-example/builder/header/build-request-parameters.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,aAAa,EAEnB,MAAM,qEAAqE,CAAA;AAE5E,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,8DAA8D,CAAA;AAoBlH;;;;;;;;;GASG;AACH,eAAO,MAAM,sBAAsB;AACjC,qBAAqB;AACrB,aAAY,aAAa,CAAC,eAAe,CAAC,EAAO;AACjD,qCAAqC;AACrC,cAAa,MAAkB,KAC9B;IACD,OAAO,EAAE,aAAa,EAAE,CAAA;IACxB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/B,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACrC,4BAA4B,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IACzC,SAAS,EAAE,eAAe,CAAA;CA6F3B,CAAA"}
|
|
@@ -38,6 +38,8 @@ exampleName = 'default') => {
|
|
|
38
38
|
// Second pass: process all parameters
|
|
39
39
|
for (const referencedParam of parameters) {
|
|
40
40
|
const param = getResolvedRef(referencedParam);
|
|
41
|
+
if (!param)
|
|
42
|
+
continue;
|
|
41
43
|
const example = getExample(param, exampleName, undefined);
|
|
42
44
|
// Skip disabled examples
|
|
43
45
|
if (!example || isParamDisabled(param, example)) {
|
|
@@ -80,7 +82,11 @@ exampleName = 'default') => {
|
|
|
80
82
|
result.pathVariables[paramName] = String(serialized);
|
|
81
83
|
break;
|
|
82
84
|
}
|
|
83
|
-
|
|
85
|
+
// The 3.2 `querystring` location represents the whole query string. Handle it like a
|
|
86
|
+
// regular query parameter so schema-based values still expand into the query string
|
|
87
|
+
// instead of being silently dropped.
|
|
88
|
+
case 'query':
|
|
89
|
+
case 'querystring': {
|
|
84
90
|
processQueryParameter(param, paramName, deSerializedValue, result.urlParams, result.allowReservedQueryParameters);
|
|
85
91
|
break;
|
|
86
92
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ParameterObject, ParameterWithSchemaObject } from '@scalar/workspace-store/schemas/v3.
|
|
1
|
+
import type { ParameterObject, ParameterWithSchemaObject } from '@scalar/workspace-store/schemas/v3.2/strict/openapi-document';
|
|
2
2
|
/**
|
|
3
3
|
* Coerces a parameter example from the UI (always a string from CodeInput) into a value
|
|
4
4
|
* request building can serialize. Only structured types are parsed; primitives stay as strings.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"de-serialize-parameter.d.ts","sourceRoot":"","sources":["../../../../src/request-example/builder/header/de-serialize-parameter.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"de-serialize-parameter.d.ts","sourceRoot":"","sources":["../../../../src/request-example/builder/header/de-serialize-parameter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,eAAe,EACf,yBAAyB,EAC1B,MAAM,8DAA8D,CAAA;AAErE;;;GAGG;AACH,eAAO,MAAM,oBAAoB,GAAI,SAAS,OAAO,EAAE,OAAO,eAAe,QAS5E,CAAA;AA0DD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,sBAAsB,GAAI,SAAS,OAAO,EAAE,QAAQ,yBAAyB,CAAC,QAAQ,CAAC,QA6BnG,CAAA"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isObjectLike } from '@scalar/helpers/object/is-object';
|
|
1
2
|
import { getResolvedRef } from '@scalar/workspace-store/helpers/get-resolved-ref';
|
|
2
3
|
/**
|
|
3
4
|
* Coerces a parameter example from the UI (always a string from CodeInput) into a value
|
|
@@ -39,7 +40,7 @@ const structuredSchemaTypes = new Set(['array', 'object']);
|
|
|
39
40
|
*/
|
|
40
41
|
const getStructuredType = (schema) => {
|
|
41
42
|
const resolved = getResolvedRef(schema);
|
|
42
|
-
if (!resolved
|
|
43
|
+
if (!isObjectLike(resolved)) {
|
|
43
44
|
return undefined;
|
|
44
45
|
}
|
|
45
46
|
if ('type' in resolved && resolved.type) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ExampleObject, ParameterObject } from '@scalar/workspace-store/schemas/v3.
|
|
1
|
+
import type { ExampleObject, ParameterObject } from '@scalar/workspace-store/schemas/v3.2/strict/openapi-document';
|
|
2
2
|
/**
|
|
3
3
|
* Determines if a parameter is disabled
|
|
4
4
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serialize-parameter.d.ts","sourceRoot":"","sources":["../../../../src/request-example/builder/header/serialize-parameter.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"serialize-parameter.d.ts","sourceRoot":"","sources":["../../../../src/request-example/builder/header/serialize-parameter.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AAEH;;;;;;;;GAQG;AACH,eAAO,MAAM,qBAAqB,GAAI,OAAO,OAAO,EAAE,aAAa,MAAM,KAAG,MAa3E,CAAA;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,oBAAoB,GAAI,OAAO,OAAO,EAAE,SAAS,OAAO,KAAG,OAqBvE,CAAA;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,kBAAkB,GAC7B,OAAO,OAAO,EACd,SAAS,OAAO,KACf,OAAO,GAAG,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CA4BjD,CAAA;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,4BAA4B,GACvC,OAAO,OAAO,EACd,SAAS,OAAO,KACf,OAAO,GAAG,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CA2CjD,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B,GAAI,OAAO,OAAO,KAAG,MAe7D,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,2BAA2B,GAAI,OAAO,OAAO,KAAG,MAa5D,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,wBAAwB,GAAI,WAAW,MAAM,EAAE,OAAO,OAAO,KAAG,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAoChH,CAAA"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isObjectLike } from '@scalar/helpers/object/is-object';
|
|
1
2
|
/**
|
|
2
3
|
* Shared parameter serialization utilities for OpenAPI style values.
|
|
3
4
|
* Used by both build-request-parameters and process-parameters.
|
|
@@ -19,7 +20,7 @@ export const serializeContentValue = (value, contentType) => {
|
|
|
19
20
|
return value;
|
|
20
21
|
}
|
|
21
22
|
// Handle JSON content types
|
|
22
|
-
if (contentType.includes('json') || (
|
|
23
|
+
if (contentType.includes('json') || (isObjectLike(value) && !Array.isArray(value))) {
|
|
23
24
|
return JSON.stringify(value);
|
|
24
25
|
}
|
|
25
26
|
// Default: convert to string
|
|
@@ -45,7 +46,7 @@ export const serializeSimpleStyle = (value, explode) => {
|
|
|
45
46
|
return value.join(',');
|
|
46
47
|
}
|
|
47
48
|
// Handle objects
|
|
48
|
-
if (
|
|
49
|
+
if (isObjectLike(value)) {
|
|
49
50
|
const entries = Object.entries(value);
|
|
50
51
|
if (explode) {
|
|
51
52
|
// Simple explode object: R=100,G=200,B=150
|
|
@@ -81,14 +82,14 @@ export const serializeFormStyle = (value, explode) => {
|
|
|
81
82
|
return value.join(',');
|
|
82
83
|
}
|
|
83
84
|
// Handle objects with explode
|
|
84
|
-
if (
|
|
85
|
+
if (isObjectLike(value) && explode) {
|
|
85
86
|
return Object.entries(value).map(([k, v]) => ({
|
|
86
87
|
key: k,
|
|
87
88
|
value: v,
|
|
88
89
|
}));
|
|
89
90
|
}
|
|
90
91
|
// Handle objects without explode
|
|
91
|
-
if (
|
|
92
|
+
if (isObjectLike(value)) {
|
|
92
93
|
return Object.entries(value)
|
|
93
94
|
.map(([k, v]) => `${k},${v}`)
|
|
94
95
|
.join(',');
|
|
@@ -121,19 +122,19 @@ export const serializeFormStyleForCookies = (value, explode) => {
|
|
|
121
122
|
return value.map((v) => (v === null ? 'null' : String(v))).join(',');
|
|
122
123
|
}
|
|
123
124
|
// Handle objects with explode
|
|
124
|
-
if (
|
|
125
|
+
if (isObjectLike(value) && explode) {
|
|
125
126
|
return Object.entries(value).map(([k, v]) => ({
|
|
126
127
|
key: k,
|
|
127
128
|
value: v,
|
|
128
129
|
}));
|
|
129
130
|
}
|
|
130
131
|
// Handle objects without explode - recursively flatten nested objects
|
|
131
|
-
if (
|
|
132
|
+
if (isObjectLike(value)) {
|
|
132
133
|
const flattenObject = (obj) => {
|
|
133
134
|
const result = [];
|
|
134
135
|
for (const [key, val] of Object.entries(obj)) {
|
|
135
136
|
// Recursively flatten nested objects
|
|
136
|
-
if (
|
|
137
|
+
if (isObjectLike(val) && !Array.isArray(val)) {
|
|
137
138
|
result.push(key, ...flattenObject(val));
|
|
138
139
|
}
|
|
139
140
|
// Handle primitive values
|
|
@@ -161,7 +162,7 @@ export const serializeSpaceDelimitedStyle = (value) => {
|
|
|
161
162
|
return value.join(' ');
|
|
162
163
|
}
|
|
163
164
|
// Handle objects
|
|
164
|
-
if (
|
|
165
|
+
if (isObjectLike(value)) {
|
|
165
166
|
return Object.entries(value)
|
|
166
167
|
.map(([k, v]) => `${k} ${v}`)
|
|
167
168
|
.join(' ');
|
|
@@ -182,10 +183,8 @@ export const serializePipeDelimitedStyle = (value) => {
|
|
|
182
183
|
return value.join('|');
|
|
183
184
|
}
|
|
184
185
|
// Handle objects
|
|
185
|
-
if (
|
|
186
|
-
return Object.entries(value)
|
|
187
|
-
.flat()
|
|
188
|
-
.join('|');
|
|
186
|
+
if (isObjectLike(value)) {
|
|
187
|
+
return Object.entries(value).flat().join('|');
|
|
189
188
|
}
|
|
190
189
|
// Handle primitives (shouldn't happen for pipeDelimited)
|
|
191
190
|
return String(value);
|
|
@@ -213,7 +212,7 @@ export const serializeDeepObjectStyle = (paramName, value) => {
|
|
|
213
212
|
append(`${fullKey}[]`, item);
|
|
214
213
|
}
|
|
215
214
|
}
|
|
216
|
-
else if (
|
|
215
|
+
else if (isObjectLike(val)) {
|
|
217
216
|
flatten(val, fullKey);
|
|
218
217
|
}
|
|
219
218
|
else {
|
|
@@ -228,7 +227,7 @@ export const serializeDeepObjectStyle = (paramName, value) => {
|
|
|
228
227
|
append(`${prefix}[${key}]`, val);
|
|
229
228
|
}
|
|
230
229
|
};
|
|
231
|
-
if (
|
|
230
|
+
if (isObjectLike(value) && !Array.isArray(value)) {
|
|
232
231
|
flatten(value, paramName);
|
|
233
232
|
}
|
|
234
233
|
return result;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type DynamicScope } from '../../../helpers/dynamic-ref.js';
|
|
2
|
-
import type { SchemaObject } from '../../../schemas/v3.
|
|
2
|
+
import type { SchemaObject } from '../../../schemas/v3.2/strict/openapi-document.js';
|
|
3
3
|
type GetExampleFromSchemaOptions = {
|
|
4
4
|
/** Fallback string for empty string values. */
|
|
5
5
|
emptyString?: string;
|
|
@@ -11,6 +11,14 @@ type GetExampleFromSchemaOptions = {
|
|
|
11
11
|
variables?: Record<string, unknown>;
|
|
12
12
|
/** Whether to omit empty and optional properties. */
|
|
13
13
|
omitEmptyAndOptionalProperties?: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Whether to keep schemas annotated `deprecated: true`.
|
|
16
|
+
*
|
|
17
|
+
* `deprecated` says a field is discouraged, not that it is absent from the wire, so a caller
|
|
18
|
+
* that must produce a value satisfying the schema — a mock server response, for instance —
|
|
19
|
+
* sets this. Defaults to omitting, which is what a request-body form-filler wants.
|
|
20
|
+
*/
|
|
21
|
+
includeDeprecated?: boolean;
|
|
14
22
|
/** Selected oneOf/anyOf variants keyed by schema path. */
|
|
15
23
|
compositionSelection?: Record<string, number>;
|
|
16
24
|
};
|
|
@@ -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":"AAGA,OAAO,EAAE,KAAK,YAAY,EAAqD,MAAM,uBAAuB,CAAA;AAG5G,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wCAAwC,CAAA;AA+wB1E,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;;;;;;OAMG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,0DAA0D;IAC1D,oBAAoB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC9C,CAAA;AA+ND;;;;;;;;;;;;;;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,OAmNF,CAAA"}
|