@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.
Files changed (193) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/README.md +6 -0
  3. package/dist/channel-example/build-connection-url.d.ts.map +1 -1
  4. package/dist/channel-example/build-connection-url.js +3 -3
  5. package/dist/channel-example/dedupe-requirements.d.ts +1 -1
  6. package/dist/channel-example/get-async-api-protocols.js +2 -2
  7. package/dist/channel-example/get-asyncapi-security-requirements.d.ts +1 -1
  8. package/dist/channel-example/get-channel-connection-security.d.ts +1 -1
  9. package/dist/channel-example/get-channel-operations.d.ts.map +1 -1
  10. package/dist/channel-example/get-channel-operations.js +4 -1
  11. package/dist/channel-example/get-channel-parameters.d.ts.map +1 -1
  12. package/dist/channel-example/get-channel-parameters.js +3 -1
  13. package/dist/channel-example/resolve-channel.d.ts.map +1 -1
  14. package/dist/channel-example/resolve-channel.js +2 -0
  15. package/dist/channel-example/resolve-operation-channel.d.ts.map +1 -1
  16. package/dist/channel-example/resolve-operation-channel.js +4 -0
  17. package/dist/channel-example/resolve-operation-with-traits.js +2 -2
  18. package/dist/channel-example/servers.d.ts.map +1 -1
  19. package/dist/channel-example/servers.js +3 -1
  20. package/dist/channel-example/types.d.ts +1 -1
  21. package/dist/client.d.ts +1 -1
  22. package/dist/client.js +3 -3
  23. package/dist/entities/auth/schema.d.ts +460 -20
  24. package/dist/entities/auth/schema.d.ts.map +1 -1
  25. package/dist/entities/auth/schema.js +2 -2
  26. package/dist/events/definitions/auth.d.ts +2 -2
  27. package/dist/events/definitions/document.d.ts +1 -1
  28. package/dist/events/definitions/operation.d.ts +3 -2
  29. package/dist/events/definitions/operation.d.ts.map +1 -1
  30. package/dist/events/definitions/server.d.ts +1 -1
  31. package/dist/events/old-definitions.d.ts +1 -1
  32. package/dist/helpers/create-chunk-writer.d.ts +6 -0
  33. package/dist/helpers/create-chunk-writer.d.ts.map +1 -0
  34. package/dist/helpers/create-chunk-writer.js +44 -0
  35. package/dist/helpers/dynamic-ref.d.ts +13 -2
  36. package/dist/helpers/dynamic-ref.d.ts.map +1 -1
  37. package/dist/helpers/dynamic-ref.js +20 -7
  38. package/dist/helpers/encode-chunk-name.d.ts +3 -0
  39. package/dist/helpers/encode-chunk-name.d.ts.map +1 -0
  40. package/dist/helpers/encode-chunk-name.js +9 -0
  41. package/dist/helpers/for-each-path-item-operation.d.ts +2 -2
  42. package/dist/helpers/get-first-server.d.ts +1 -1
  43. package/dist/helpers/get-resolved-ref.d.ts +6 -1
  44. package/dist/helpers/get-resolved-ref.d.ts.map +1 -1
  45. package/dist/helpers/get-resolved-ref.js +3 -10
  46. package/dist/helpers/is-non-optional-security-requirement.d.ts +1 -1
  47. package/dist/helpers/merge-object.d.ts +2 -2
  48. package/dist/helpers/merge-object.d.ts.map +1 -1
  49. package/dist/helpers/merge-object.js +2 -5
  50. package/dist/mutators/auth.d.ts +1 -1
  51. package/dist/mutators/auth.d.ts.map +1 -1
  52. package/dist/mutators/auth.js +9 -4
  53. package/dist/mutators/index.d.ts +10 -10
  54. package/dist/mutators/operation/body.js +2 -2
  55. package/dist/mutators/operation/helpers/fetch-request-to-har.d.ts.map +1 -1
  56. package/dist/mutators/operation/helpers/fetch-request-to-har.js +12 -2
  57. package/dist/mutators/operation/helpers/har-to-operation.d.ts +1 -1
  58. package/dist/mutators/operation/helpers/har-to-operation.d.ts.map +1 -1
  59. package/dist/mutators/operation/helpers/har-to-operation.js +9 -5
  60. package/dist/mutators/operation/helpers/sync-path-parameters.d.ts +2 -2
  61. package/dist/mutators/operation/history.js +2 -2
  62. package/dist/mutators/operation/operation.d.ts.map +1 -1
  63. package/dist/mutators/operation/operation.js +4 -0
  64. package/dist/mutators/operation/parameters.js +1 -1
  65. package/dist/mutators/server.d.ts +3 -3
  66. package/dist/mutators/server.js +1 -1
  67. package/dist/mutators/tag.d.ts.map +1 -1
  68. package/dist/mutators/tag.js +4 -0
  69. package/dist/navigation/helpers/get-openapi-object.d.ts +1 -1
  70. package/dist/navigation/helpers/traverse-asyncapi-document.d.ts.map +1 -1
  71. package/dist/navigation/helpers/traverse-asyncapi-document.js +2 -2
  72. package/dist/navigation/helpers/traverse-description.d.ts +1 -1
  73. package/dist/navigation/helpers/traverse-document.d.ts +1 -1
  74. package/dist/navigation/helpers/traverse-examples.d.ts +12 -1
  75. package/dist/navigation/helpers/traverse-examples.d.ts.map +1 -1
  76. package/dist/navigation/helpers/traverse-examples.js +22 -1
  77. package/dist/navigation/helpers/traverse-paths.d.ts +1 -1
  78. package/dist/navigation/helpers/traverse-schemas.d.ts +1 -1
  79. package/dist/navigation/helpers/traverse-tags.d.ts +1 -1
  80. package/dist/navigation/helpers/traverse-webhooks.d.ts +1 -1
  81. package/dist/navigation/helpers/update-order-ids.d.ts +2 -2
  82. package/dist/navigation/index.d.ts +1 -0
  83. package/dist/navigation/index.d.ts.map +1 -1
  84. package/dist/navigation/index.js +1 -0
  85. package/dist/navigation/types.d.ts +1 -1
  86. package/dist/persistence/index.d.ts.map +1 -1
  87. package/dist/persistence/index.js +10 -10
  88. package/dist/persistence/indexdb.d.ts.map +1 -1
  89. package/dist/persistence/indexdb.js +7 -5
  90. package/dist/persistence/migrations/v2-team-to-local.d.ts.map +1 -1
  91. package/dist/persistence/migrations/v2-team-to-local.js +3 -4
  92. package/dist/plugins/bundler/index.d.ts +5 -2
  93. package/dist/plugins/bundler/index.d.ts.map +1 -1
  94. package/dist/plugins/bundler/index.js +24 -26
  95. package/dist/request-example/builder/body/build-request-body.d.ts +2 -1
  96. package/dist/request-example/builder/body/build-request-body.d.ts.map +1 -1
  97. package/dist/request-example/builder/body/build-request-body.js +41 -5
  98. package/dist/request-example/builder/body/encode-multipart-body.d.ts +9 -0
  99. package/dist/request-example/builder/body/encode-multipart-body.d.ts.map +1 -0
  100. package/dist/request-example/builder/body/encode-multipart-body.js +29 -0
  101. package/dist/request-example/builder/body/get-request-body-example.d.ts +1 -1
  102. package/dist/request-example/builder/body/get-selected-body-content-type.d.ts +1 -1
  103. package/dist/request-example/builder/body/schema-value-coercion.d.ts +1 -1
  104. package/dist/request-example/builder/body/schema-value-coercion.js +1 -1
  105. package/dist/request-example/builder/body/serialize-form-property.d.ts +1 -1
  106. package/dist/request-example/builder/body/serialize-multipart-array.d.ts +16 -0
  107. package/dist/request-example/builder/body/serialize-multipart-array.d.ts.map +1 -0
  108. package/dist/request-example/builder/body/serialize-multipart-array.js +37 -0
  109. package/dist/request-example/builder/build-request.d.ts.map +1 -1
  110. package/dist/request-example/builder/build-request.js +12 -7
  111. package/dist/request-example/builder/header/build-request-parameters.d.ts +1 -1
  112. package/dist/request-example/builder/header/build-request-parameters.d.ts.map +1 -1
  113. package/dist/request-example/builder/header/build-request-parameters.js +7 -1
  114. package/dist/request-example/builder/header/de-serialize-parameter.d.ts +1 -1
  115. package/dist/request-example/builder/header/de-serialize-parameter.d.ts.map +1 -1
  116. package/dist/request-example/builder/header/de-serialize-parameter.js +2 -1
  117. package/dist/request-example/builder/header/is-param-disabled.d.ts +1 -1
  118. package/dist/request-example/builder/header/serialize-parameter.d.ts.map +1 -1
  119. package/dist/request-example/builder/header/serialize-parameter.js +13 -14
  120. package/dist/request-example/builder/helpers/get-example-from-schema.d.ts +9 -1
  121. package/dist/request-example/builder/helpers/get-example-from-schema.d.ts.map +1 -1
  122. package/dist/request-example/builder/helpers/get-example-from-schema.js +255 -20
  123. package/dist/request-example/builder/helpers/get-example.d.ts +1 -1
  124. package/dist/request-example/builder/helpers/get-example.js +2 -2
  125. package/dist/request-example/builder/helpers/get-resolved-url.d.ts +1 -1
  126. package/dist/request-example/builder/helpers/get-server-variables.d.ts +1 -1
  127. package/dist/request-example/builder/index.d.ts +1 -0
  128. package/dist/request-example/builder/index.d.ts.map +1 -1
  129. package/dist/request-example/builder/index.js +1 -0
  130. package/dist/request-example/builder/request-factory.d.ts +2 -2
  131. package/dist/request-example/builder/security/broker-scheme-types.d.ts.map +1 -1
  132. package/dist/request-example/builder/security/broker-scheme-types.js +2 -2
  133. package/dist/request-example/builder/security/build-request-security.d.ts.map +1 -1
  134. package/dist/request-example/builder/security/build-request-security.js +3 -4
  135. package/dist/request-example/builder/security/secret-types.d.ts +13 -4
  136. package/dist/request-example/builder/security/secret-types.d.ts.map +1 -1
  137. package/dist/request-example/context/get-request-example-context.d.ts +3 -3
  138. package/dist/request-example/context/get-request-example-context.js +1 -1
  139. package/dist/request-example/context/headers.d.ts +1 -1
  140. package/dist/request-example/context/headers.js +1 -1
  141. package/dist/request-example/context/helpers/combine-params.d.ts +1 -1
  142. package/dist/request-example/context/security/extract-security-scheme-secrets.d.ts +16 -3
  143. package/dist/request-example/context/security/extract-security-scheme-secrets.d.ts.map +1 -1
  144. package/dist/request-example/context/security/extract-security-scheme-secrets.js +21 -19
  145. package/dist/request-example/context/security/get-security-requirements.d.ts +2 -2
  146. package/dist/request-example/context/security/get-security-schemes.d.ts +1 -1
  147. package/dist/request-example/context/security/get-selected-security.d.ts +1 -1
  148. package/dist/request-example/context/security/is-auth-optional.d.ts +1 -1
  149. package/dist/request-example/context/security/merge-security.d.ts +3 -3
  150. package/dist/request-example/context/security/merge-security.d.ts.map +1 -1
  151. package/dist/request-example/context/security/merge-security.js +40 -11
  152. package/dist/request-example/context/servers.d.ts +2 -2
  153. package/dist/request-example/functions.d.ts.map +1 -1
  154. package/dist/request-example/index.d.ts +1 -1
  155. package/dist/request-example/index.d.ts.map +1 -1
  156. package/dist/request-example/index.js +1 -1
  157. package/dist/resolve.d.ts +1 -1
  158. package/dist/resolve.js +1 -1
  159. package/dist/schemas/navigation.d.ts +4 -4
  160. package/dist/schemas/navigation.js +1 -1
  161. package/dist/schemas/reference-config/index.d.ts +92 -4
  162. package/dist/schemas/reference-config/index.d.ts.map +1 -1
  163. package/dist/schemas/reference-config/settings.d.ts +93 -5
  164. package/dist/schemas/reference-config/settings.d.ts.map +1 -1
  165. package/dist/schemas/reference-config/settings.js +1 -1
  166. package/dist/schemas/type-guards.d.ts +1 -1
  167. package/dist/schemas/v3.1/openapi/index.d.ts.map +1 -1
  168. package/dist/schemas/v3.1/openapi/index.js +11 -1
  169. package/dist/schemas/v3.1/strict/openapi-document.d.ts +210 -0
  170. package/dist/schemas/v3.1/strict/openapi-document.d.ts.map +1 -1
  171. package/dist/schemas/v3.1/strict/security-scheme.d.ts +13 -1
  172. package/dist/schemas/v3.1/strict/security-scheme.d.ts.map +1 -1
  173. package/dist/schemas/v3.1/strict/security-scheme.js +11 -1
  174. package/dist/schemas/v3.2/openapi/index.d.ts +2 -0
  175. package/dist/schemas/v3.2/openapi/index.d.ts.map +1 -1
  176. package/dist/schemas/v3.2/openapi/index.js +13 -1
  177. package/dist/schemas/v3.2/strict/oauth-flow.d.ts +23 -1
  178. package/dist/schemas/v3.2/strict/oauth-flow.d.ts.map +1 -1
  179. package/dist/schemas/v3.2/strict/oauth-flow.js +6 -1
  180. package/dist/schemas/v3.2/strict/oauthflows.d.ts +20 -0
  181. package/dist/schemas/v3.2/strict/oauthflows.d.ts.map +1 -1
  182. package/dist/schemas/v3.2/strict/openapi-document.d.ts +1439 -141
  183. package/dist/schemas/v3.2/strict/openapi-document.d.ts.map +1 -1
  184. package/dist/schemas/v3.2/strict/openapi-document.js +2 -1
  185. package/dist/schemas/v3.2/strict/security-scheme.d.ts +29 -6
  186. package/dist/schemas/v3.2/strict/security-scheme.d.ts.map +1 -1
  187. package/dist/schemas/v3.2/strict/security-scheme.js +16 -3
  188. package/dist/schemas/workspace-specification/index.d.ts +1 -1
  189. package/dist/schemas/workspace.d.ts +1 -1
  190. package/dist/server.d.ts +1 -1
  191. package/dist/server.d.ts.map +1 -1
  192. package/dist/server.js +23 -27
  193. 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
- const loader = context.loaders.find((it) => it.validate(externalValue));
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(externalValue)) {
58
- cache.set(externalValue, loader.exec(externalValue));
62
+ if (!cache.has(resolvedValue)) {
63
+ cache.set(resolvedValue, loader.exec(resolvedValue));
59
64
  }
60
- const result = await cache.get(externalValue);
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 non-schema object containing a $ref, only $ref,
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
- // If the node is a $ref and we are not on the schema object, we need to normalize the $ref
212
- if (typeof node['$ref'] === 'string' && !(path[0] === 'components' && path[1] === 'schemas')) {
213
- // Remove any other properties from the node and only keep the '$ref', 'summary', 'description' and '$status'.
214
- // The JSON Schema 2020-12 reference keywords are also kept: a schema-position `$ref` may carry a
215
- // `$defs`/`$dynamicAnchor` binding as a sibling to specialize a generic template (the `Paginated<T>`
216
- // pattern). Such a schema can appear inline anywhere a schema is allowed — for example a response's
217
- // `content.<media>.schema` — not only under `components/schemas`. Dropping these siblings here would
218
- // discard the item-type binding, leaving `$dynamicRef` to resolve to the template's empty fallback and
219
- // rendering an empty array. See https://github.com/scalar/scalar/issues/9414.
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/strict/request-body';
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;AAQjG,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;KACd,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;AAED,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,IAwThB,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.1/strict/type-guards';
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: 'blob',
173
+ type: 'text',
143
174
  key: name,
144
- value: new Blob([serializedValue], { type: partContentType }),
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: 'blob',
271
+ type: 'text',
236
272
  key,
237
- value: new Blob([serializedValue], { type: partContentType }),
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/strict/openapi-document';
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/strict/request-body';
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/strict/openapi-document';
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.1/strict/type-guards';
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/strict/openapi-document';
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;AAOnE,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"}
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
- request.body.value.forEach((item) => {
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.1/strict/openapi-document';
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;CAwF3B,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
- case 'query': {
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/strict/openapi-document';
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":"AACA,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
+ {"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 || typeof resolved !== 'object') {
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/strict/openapi-document';
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":"AAAA;;;;;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,MAe5D,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
+ {"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') || (typeof value === 'object' && value !== null && !Array.isArray(value))) {
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 (typeof value === 'object' && value !== null) {
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 (typeof value === 'object' && value !== null && explode) {
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 (typeof value === 'object' && value !== null) {
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 (typeof value === 'object' && value !== null && explode) {
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 (typeof value === 'object' && value !== null) {
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 (typeof val === 'object' && val !== null && !Array.isArray(val)) {
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 (typeof value === 'object' && value !== null) {
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 (typeof value === 'object' && value !== null) {
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 (typeof val === 'object' && val !== null) {
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 (typeof value === 'object' && value !== null && !Array.isArray(value)) {
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.1/strict/openapi-document.js';
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":"AAEA,OAAO,EAAE,KAAK,YAAY,EAAqD,MAAM,uBAAuB,CAAA;AAG5G,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wCAAwC,CAAA;AAitB1E,KAAK,2BAA2B,GAAG;IACjC,+CAA+C;IAC/C,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,4CAA4C;IAC5C,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,uDAAuD;IACvD,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;IACvB,iEAAiE;IACjE,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACnC,qDAAqD;IACrD,8BAA8B,CAAC,EAAE,OAAO,CAAA;IACxC,0DAA0D;IAC1D,oBAAoB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC9C,CAAA;AAeD;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,oBAAoB,GAC/B,QAAQ,YAAY,EACpB,UAAU,2BAA2B,EACrC,iEAOG,OAAO,CAAC;IACT,KAAK,EAAE,MAAM,CAAA;IACb,YAAY,EAAE,YAAY,CAAA;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;IACrB,6EAA6E;IAC7E,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,qGAAqG;IACrG,YAAY,EAAE,YAAY,CAAA;CAC3B,CAAM,KACN,OAwMF,CAAA"}
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"}