@scalar/workspace-store 0.63.0 → 0.65.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/CHANGELOG.md +110 -0
  2. package/README.md +123 -0
  3. package/dist/client.d.ts +28 -0
  4. package/dist/client.d.ts.map +1 -1
  5. package/dist/client.js +320 -144
  6. package/dist/entities/auth/schema.d.ts +236 -0
  7. package/dist/entities/auth/schema.d.ts.map +1 -1
  8. package/dist/entities/auth/schema.js +3 -1
  9. package/dist/helpers/chunk-index.d.ts +113 -0
  10. package/dist/helpers/chunk-index.d.ts.map +1 -0
  11. package/dist/helpers/chunk-index.js +152 -0
  12. package/dist/helpers/external-examples.d.ts +19 -0
  13. package/dist/helpers/external-examples.d.ts.map +1 -0
  14. package/dist/helpers/external-examples.js +51 -0
  15. package/dist/helpers/for-each-path-item-operation.js +4 -4
  16. package/dist/helpers/get-example-value.d.ts +15 -0
  17. package/dist/helpers/get-example-value.d.ts.map +1 -0
  18. package/dist/helpers/get-example-value.js +28 -0
  19. package/dist/helpers/get-resolved-ref.d.ts.map +1 -1
  20. package/dist/helpers/get-resolved-ref.js +12 -1
  21. package/dist/helpers/normalize-boolean-schemas.d.ts +10 -0
  22. package/dist/helpers/normalize-boolean-schemas.d.ts.map +1 -0
  23. package/dist/helpers/normalize-boolean-schemas.js +193 -0
  24. package/dist/helpers/operation-examples.d.ts +6 -0
  25. package/dist/helpers/operation-examples.d.ts.map +1 -0
  26. package/dist/helpers/operation-examples.js +48 -0
  27. package/dist/helpers/serialize-stream-example.d.ts +8 -0
  28. package/dist/helpers/serialize-stream-example.d.ts.map +1 -0
  29. package/dist/helpers/serialize-stream-example.js +52 -0
  30. package/dist/helpers/use-external-examples.d.ts +15 -0
  31. package/dist/helpers/use-external-examples.d.ts.map +1 -0
  32. package/dist/helpers/use-external-examples.js +62 -0
  33. package/dist/mutators/index.d.ts +3 -3
  34. package/dist/mutators/operation/body.d.ts.map +1 -1
  35. package/dist/mutators/operation/body.js +9 -2
  36. package/dist/mutators/operation/parameters.d.ts.map +1 -1
  37. package/dist/mutators/operation/parameters.js +28 -9
  38. package/dist/plugins/bundler/index.d.ts +6 -2
  39. package/dist/plugins/bundler/index.d.ts.map +1 -1
  40. package/dist/plugins/bundler/index.js +20 -4
  41. package/dist/plugins/bundler/openapi-document.d.ts +6 -0
  42. package/dist/plugins/bundler/openapi-document.d.ts.map +1 -0
  43. package/dist/plugins/bundler/openapi-document.js +57 -0
  44. package/dist/request-example/builder/body/build-multipart.d.ts +29 -0
  45. package/dist/request-example/builder/body/build-multipart.d.ts.map +1 -0
  46. package/dist/request-example/builder/body/build-multipart.js +191 -0
  47. package/dist/request-example/builder/body/build-request-body.d.ts +6 -1
  48. package/dist/request-example/builder/body/build-request-body.d.ts.map +1 -1
  49. package/dist/request-example/builder/body/build-request-body.js +80 -23
  50. package/dist/request-example/builder/body/encode-multipart-body.d.ts +8 -8
  51. package/dist/request-example/builder/body/encode-multipart-body.d.ts.map +1 -1
  52. package/dist/request-example/builder/body/encode-multipart-body.js +56 -18
  53. package/dist/request-example/builder/body/get-request-body-example.d.ts.map +1 -1
  54. package/dist/request-example/builder/body/get-request-body-example.js +20 -6
  55. package/dist/request-example/builder/body/multipart-limits.d.ts +3 -0
  56. package/dist/request-example/builder/body/multipart-limits.d.ts.map +1 -0
  57. package/dist/request-example/builder/body/multipart-limits.js +2 -0
  58. package/dist/request-example/builder/body/serialize-form-property.d.ts +2 -0
  59. package/dist/request-example/builder/body/serialize-form-property.d.ts.map +1 -1
  60. package/dist/request-example/builder/body/serialize-form-property.js +3 -2
  61. package/dist/request-example/builder/body/serialize-multipart-array.d.ts +1 -1
  62. package/dist/request-example/builder/build-request.js +5 -0
  63. package/dist/request-example/builder/header/build-request-parameters.d.ts.map +1 -1
  64. package/dist/request-example/builder/header/build-request-parameters.js +5 -1
  65. package/dist/request-example/builder/header/is-param-disabled.d.ts +2 -2
  66. package/dist/request-example/builder/header/is-param-disabled.d.ts.map +1 -1
  67. package/dist/request-example/builder/header/is-param-disabled.js +5 -4
  68. package/dist/request-example/builder/header/serialize-parameter.d.ts +11 -0
  69. package/dist/request-example/builder/header/serialize-parameter.d.ts.map +1 -1
  70. package/dist/request-example/builder/header/serialize-parameter.js +22 -0
  71. package/dist/request-example/builder/helpers/get-example-from-schema.d.ts.map +1 -1
  72. package/dist/request-example/builder/helpers/get-example-from-schema.js +42 -3
  73. package/dist/request-example/builder/helpers/get-example.d.ts +2 -0
  74. package/dist/request-example/builder/helpers/get-example.d.ts.map +1 -1
  75. package/dist/request-example/builder/helpers/get-example.js +14 -9
  76. package/dist/request-example/builder/index.d.ts +2 -2
  77. package/dist/request-example/builder/index.d.ts.map +1 -1
  78. package/dist/request-example/builder/index.js +1 -1
  79. package/dist/request-example/builder/security/secret-types.d.ts +4 -1
  80. package/dist/request-example/builder/security/secret-types.d.ts.map +1 -1
  81. package/dist/request-example/context/headers.d.ts.map +1 -1
  82. package/dist/request-example/context/headers.js +3 -4
  83. package/dist/request-example/context/security/extract-security-scheme-secrets.d.ts.map +1 -1
  84. package/dist/request-example/context/security/extract-security-scheme-secrets.js +15 -0
  85. package/dist/request-example/index.d.ts +5 -2
  86. package/dist/request-example/index.d.ts.map +1 -1
  87. package/dist/request-example/index.js +4 -1
  88. package/dist/request-example/xml/serialize-xml-part.d.ts +9 -0
  89. package/dist/request-example/xml/serialize-xml-part.d.ts.map +1 -0
  90. package/dist/request-example/xml/serialize-xml-part.js +12 -0
  91. package/dist/schemas/extensions.d.ts +9 -0
  92. package/dist/schemas/extensions.d.ts.map +1 -1
  93. package/dist/schemas/extensions.js +9 -0
  94. package/dist/schemas/reference-config/index.d.ts +1 -0
  95. package/dist/schemas/reference-config/index.d.ts.map +1 -1
  96. package/dist/schemas/reference-config/settings.d.ts +1 -0
  97. package/dist/schemas/reference-config/settings.d.ts.map +1 -1
  98. package/dist/schemas/v3.1/strict/oauthflows.d.ts +26 -0
  99. package/dist/schemas/v3.1/strict/oauthflows.d.ts.map +1 -1
  100. package/dist/schemas/v3.1/strict/oauthflows.js +3 -0
  101. package/dist/schemas/v3.1/strict/openapi-document.d.ts +812 -7
  102. package/dist/schemas/v3.1/strict/openapi-document.d.ts.map +1 -1
  103. package/dist/schemas/v3.2/openapi/index.d.ts +5 -0
  104. package/dist/schemas/v3.2/openapi/index.d.ts.map +1 -1
  105. package/dist/schemas/v3.2/openapi/index.js +46 -12
  106. package/dist/schemas/v3.2/strict/openapi-document.d.ts +37 -0
  107. package/dist/schemas/v3.2/strict/openapi-document.d.ts.map +1 -1
  108. package/dist/schemas/v3.2/strict/openapi-document.js +8 -0
  109. package/dist/server.d.ts +21 -1
  110. package/dist/server.d.ts.map +1 -1
  111. package/dist/server.js +60 -34
  112. package/package.json +19 -9
  113. package/dist/schemas/v3.1/openapi/index.d.ts +0 -149
  114. package/dist/schemas/v3.1/openapi/index.d.ts.map +0 -1
  115. package/dist/schemas/v3.1/openapi/index.js +0 -732
  116. package/dist/schemas/v3.1/openapi/reference.d.ts +0 -4
  117. package/dist/schemas/v3.1/openapi/reference.d.ts.map +0 -1
  118. package/dist/schemas/v3.1/openapi/reference.js +0 -29
@@ -0,0 +1,52 @@
1
+ import { getStreamFormat } from '@scalar/helpers/http/is-streaming-content-type';
2
+ import { isObject } from '@scalar/helpers/object/is-object';
3
+ /**
4
+ * Frame generated values and authored structured examples as sequential content.
5
+ * Callers bypass this helper for authored strings that already contain wire framing.
6
+ * SSE objects with no valid fields are omitted with one warning per call; an empty
7
+ * input sequence is valid and does not produce a warning.
8
+ */
9
+ export const serializeStreamExample = (value, contentType, singleItem) => {
10
+ if (value === undefined) {
11
+ return undefined;
12
+ }
13
+ const format = getStreamFormat(contentType);
14
+ const items = singleItem ? [value] : Array.isArray(value) ? value : [value];
15
+ if (format === 'json-lines') {
16
+ return items.map((item) => `${JSON.stringify(item)}\n`).join('');
17
+ }
18
+ if (format === 'json-seq') {
19
+ return items.map((item) => `\u001e${JSON.stringify(item)}\n`).join('');
20
+ }
21
+ if (format === 'sse') {
22
+ const frames = items.map((item) => {
23
+ if (!isObject(item)) {
24
+ return `data: ${JSON.stringify(item)}\n\n`;
25
+ }
26
+ const fields = ['event', 'id', 'retry', 'data'].flatMap((field) => {
27
+ const fieldValue = item[field];
28
+ if (field === 'retry') {
29
+ return typeof fieldValue === 'number' && Number.isInteger(fieldValue) && fieldValue >= 0
30
+ ? [`retry: ${fieldValue}`]
31
+ : [];
32
+ }
33
+ if (field === 'data' && fieldValue !== undefined) {
34
+ const data = typeof fieldValue === 'string' ? fieldValue : JSON.stringify(fieldValue);
35
+ return data.split(/\r\n|\r|\n/).map((line) => `data: ${line}`);
36
+ }
37
+ if (typeof fieldValue !== 'string' || (field === 'id' && fieldValue.includes('\0'))) {
38
+ return [];
39
+ }
40
+ const lines = fieldValue.split(/\r\n|\r|\n/);
41
+ return lines.length === 1 ? [`${field}: ${fieldValue}`] : [];
42
+ });
43
+ return fields.length ? `${fields.join('\n')}\n\n` : '';
44
+ });
45
+ const omitted = frames.filter((frame) => frame === '').length;
46
+ if (omitted > 0) {
47
+ console.warn(`Skipped ${omitted} SSE example item(s) with no valid event, id, retry, or data fields.`);
48
+ }
49
+ return frames.join('');
50
+ }
51
+ return undefined;
52
+ };
@@ -0,0 +1,15 @@
1
+ import { type ComponentPublicInstance, type ComputedRef, type InjectionKey, type Ref } from 'vue';
2
+ import { type ExternalExampleResolver } from '../helpers/external-examples.js';
3
+ import type { ExampleObject } from '../schemas/v3.2/strict/openapi-document.js';
4
+ /** Supply the current document's resolver so consumers share downloads and invalidation. */
5
+ export declare const EXTERNAL_EXAMPLES: InjectionKey<() => ExternalExampleResolver>;
6
+ /** Observe current visibility, rather than mounting, to avoid fetching every operation on a long page. */
7
+ export declare const useExampleVisibility: (target: Ref<Element | ComponentPublicInstance | null>) => Ref<boolean>;
8
+ /** Resolve only the selected examples and expose immutable views of their downloaded values. */
9
+ export declare const useExternalExamples: (examples: () => (ExampleObject | undefined)[], enabled?: () => boolean, resolver?: () => ExternalExampleResolver) => {
10
+ pending: ComputedRef<boolean>;
11
+ failed: ComputedRef<boolean>;
12
+ resolve: (example: ExampleObject | undefined) => ExampleObject | undefined;
13
+ retry: () => Promise<void>;
14
+ };
15
+ //# sourceMappingURL=use-external-examples.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-external-examples.d.ts","sourceRoot":"","sources":["../../src/helpers/use-external-examples.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,uBAAuB,EAC5B,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,GAAG,EAOT,MAAM,KAAK,CAAA;AAEZ,OAAO,EAAE,KAAK,uBAAuB,EAAiC,MAAM,6BAA6B,CAAA;AACzG,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAA;AAE3E,4FAA4F;AAC5F,eAAO,MAAM,iBAAiB,EAAE,YAAY,CAAC,MAAM,uBAAuB,CAA+B,CAAA;AAEzG,0GAA0G;AAC1G,eAAO,MAAM,oBAAoB,GAAI,QAAQ,GAAG,CAAC,OAAO,GAAG,uBAAuB,GAAG,IAAI,CAAC,KAAG,GAAG,CAAC,OAAO,CAuBvG,CAAA;AAED,gGAAgG;AAChG,eAAO,MAAM,mBAAmB,GAC9B,UAAU,MAAM,CAAC,aAAa,GAAG,SAAS,CAAC,EAAE,EAC7C,UAAS,MAAM,OAAoB,EACnC,WAAW,MAAM,uBAAuB,KACvC;IACD,OAAO,EAAE,WAAW,CAAC,OAAO,CAAC,CAAA;IAC7B,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,CAAA;IAC5B,OAAO,EAAE,CAAC,OAAO,EAAE,aAAa,GAAG,SAAS,KAAK,aAAa,GAAG,SAAS,CAAA;IAC1E,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAsC3B,CAAA"}
@@ -0,0 +1,62 @@
1
+ import { computed, inject, onScopeDispose, ref, watch, watchEffect, } from 'vue';
2
+ import { createExternalExampleResolver } from '../helpers/external-examples.js';
3
+ /** Supply the current document's resolver so consumers share downloads and invalidation. */
4
+ export const EXTERNAL_EXAMPLES = Symbol('external-examples');
5
+ /** Observe current visibility, rather than mounting, to avoid fetching every operation on a long page. */
6
+ export const useExampleVisibility = (target) => {
7
+ const visible = ref(false);
8
+ let observer;
9
+ watch(target, (element) => {
10
+ observer?.disconnect();
11
+ visible.value = false;
12
+ const node = element && ('$el' in element ? element.$el : element);
13
+ if (typeof Element === 'undefined' || !(node instanceof Element))
14
+ return;
15
+ if (typeof IntersectionObserver === 'undefined') {
16
+ visible.value = true;
17
+ return;
18
+ }
19
+ observer = new IntersectionObserver(([entry]) => {
20
+ visible.value = entry?.isIntersecting ?? false;
21
+ });
22
+ observer.observe(node);
23
+ }, { flush: 'post' });
24
+ onScopeDispose(() => observer?.disconnect());
25
+ return visible;
26
+ };
27
+ /** Resolve only the selected examples and expose immutable views of their downloaded values. */
28
+ export const useExternalExamples = (examples, enabled = () => true, resolver) => {
29
+ const fallback = createExternalExampleResolver();
30
+ const getResolver = resolver ?? inject(EXTERNAL_EXAMPLES, () => fallback);
31
+ const states = computed(() => examples()
32
+ .filter((example) => example !== undefined && example.value === undefined && !!example.externalValue)
33
+ .map((example) => getResolver()(example)));
34
+ watchEffect(() => {
35
+ if (!enabled())
36
+ return;
37
+ for (const state of states.value) {
38
+ if (state.status === 'idle')
39
+ void state.load();
40
+ }
41
+ });
42
+ return {
43
+ pending: computed(() => states.value.some((state) => state.status !== 'loaded')),
44
+ failed: computed(() => states.value.some((state) => state.status === 'error')),
45
+ resolve: (example) => {
46
+ if (!example || example.value !== undefined || !example.externalValue)
47
+ return example;
48
+ const state = getResolver()(example);
49
+ if (state.status !== 'loaded')
50
+ return example;
51
+ // A 3.2 example can pair structured data with external wire text. Keep both in the
52
+ // resolved view so raw consumers display the download and form editors retain the data.
53
+ if (example.dataValue !== undefined && state.serializedValue !== undefined) {
54
+ return { ...example, serializedValue: state.serializedValue };
55
+ }
56
+ return { ...example, value: state.value };
57
+ },
58
+ retry: async () => {
59
+ await Promise.all(states.value.map((state) => state.load()));
60
+ },
61
+ };
62
+ };
@@ -12,8 +12,8 @@ export declare function generateClientMutators(store: WorkspaceStore | null): {
12
12
  workspace: () => {
13
13
  cookie: {
14
14
  upsertCookie: (payload: {
15
- payload: Partial<import("../schemas/extensions/general/x-scalar-cookies.js").XScalarCookie>;
16
15
  index?: number | undefined;
16
+ payload: Partial<import("../schemas/extensions/general/x-scalar-cookies.js").XScalarCookie>;
17
17
  }) => import("../schemas/extensions/general/x-scalar-cookies.js").XScalarCookie | undefined;
18
18
  deleteCookie: (payload: {
19
19
  index: number;
@@ -77,8 +77,8 @@ export declare function generateClientMutators(store: WorkspaceStore | null): {
77
77
  };
78
78
  cookie: {
79
79
  upsertCookie: (payload: {
80
- payload: Partial<import("../schemas/extensions/general/x-scalar-cookies.js").XScalarCookie>;
81
80
  index?: number | undefined;
81
+ payload: Partial<import("../schemas/extensions/general/x-scalar-cookies.js").XScalarCookie>;
82
82
  }) => import("../schemas/extensions/general/x-scalar-cookies.js").XScalarCookie | undefined;
83
83
  deleteCookie: (payload: {
84
84
  index: number;
@@ -168,8 +168,8 @@ export declare function generateClientMutators(store: WorkspaceStore | null): {
168
168
  };
169
169
  cookie: {
170
170
  upsertCookie: (payload: {
171
- payload: Partial<import("../schemas/extensions/general/x-scalar-cookies.js").XScalarCookie>;
172
171
  index?: number | undefined;
172
+ payload: Partial<import("../schemas/extensions/general/x-scalar-cookies.js").XScalarCookie>;
173
173
  }) => import("../schemas/extensions/general/x-scalar-cookies.js").XScalarCookie | undefined;
174
174
  deleteCookie: (payload: {
175
175
  index: number;
@@ -1 +1 @@
1
- {"version":3,"file":"body.d.ts","sourceRoot":"","sources":["../../../src/mutators/operation/body.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAA;AAIrE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAoClD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,qCAAqC,GAChD,UAAU,iBAAiB,GAAG,IAAI,EAClC,mBAAmB,eAAe,CAAC,0CAA0C,CAAC,SAwB/E,CAAA;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,iCAAiC,GAC5C,UAAU,iBAAiB,GAAG,IAAI,EAClC,gCAAgC,eAAe,CAAC,oCAAoC,CAAC,SAStF,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,mCAAmC,GAC9C,UAAU,iBAAiB,GAAG,IAAI,EAClC,gCAAgC,eAAe,CAAC,wCAAwC,CAAC,SAS1F,CAAA"}
1
+ {"version":3,"file":"body.d.ts","sourceRoot":"","sources":["../../../src/mutators/operation/body.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAA;AAIrE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AA4ClD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,qCAAqC,GAChD,UAAU,iBAAiB,GAAG,IAAI,EAClC,mBAAmB,eAAe,CAAC,0CAA0C,CAAC,SAwB/E,CAAA;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,iCAAiC,GAC5C,UAAU,iBAAiB,GAAG,IAAI,EAClC,gCAAgC,eAAe,CAAC,oCAAoC,CAAC,SAStF,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,mCAAmC,GAC9C,UAAU,iBAAiB,GAAG,IAAI,EAClC,gCAAgC,eAAe,CAAC,wCAAwC,CAAC,SAS1F,CAAA"}
@@ -2,6 +2,13 @@ import { getPathItemOperation } from '../../helpers/for-each-path-item-operation
2
2
  import { getResolvedRef } from '../../helpers/get-resolved-ref.js';
3
3
  import { unpackProxyObject } from '../../helpers/unpack-proxy.js';
4
4
  import { isOpenApiDocument } from '../../schemas/type-guards.js';
5
+ /** An edit replaces the authored source so the old serialized/data value cannot win. */
6
+ const replaceExampleValue = (example, value) => {
7
+ delete example.serializedValue;
8
+ delete example.dataValue;
9
+ delete example.externalValue;
10
+ example.value = value;
11
+ };
5
12
  /** Ensure the json that we need exists up to the example object in the request body */
6
13
  const findOrCreateRequestBodyExample = (document, contentType, meta) => {
7
14
  if (!isOpenApiDocument(document)) {
@@ -81,7 +88,7 @@ export const updateOperationRequestBodyExample = (document, { meta, payload, con
81
88
  console.error('Example not found', meta.exampleKey);
82
89
  return;
83
90
  }
84
- example.value = payload;
91
+ replaceExampleValue(example, payload);
85
92
  };
86
93
  /**
87
94
  * Stores the form data for the request body example
@@ -94,5 +101,5 @@ export const updateOperationRequestBodyFormValue = (document, { meta, payload, c
94
101
  console.error('Example not found', meta.exampleKey);
95
102
  return;
96
103
  }
97
- example.value = unpackProxyObject(payload, { depth: 3 });
104
+ replaceExampleValue(example, unpackProxyObject(payload, { depth: 3 }));
98
105
  };
@@ -1 +1 @@
1
- {"version":3,"file":"parameters.d.ts","sourceRoot":"","sources":["../../../src/mutators/operation/parameters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAA;AAIrE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAmClD;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,wBAAwB,GACnC,UAAU,iBAAiB,GAAG,IAAI,EAClC,4CAA4C,eAAe,CAAC,4BAA4B,CAAC,SAuD1F,CAAA;AAED;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,8BAA8B,GACzC,UAAU,iBAAiB,GAAG,IAAI,EAClC,uCAAuC,eAAe,CAAC,mCAAmC,CAAC,SA8C5F,CAAA;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,wBAAwB,GACnC,UAAU,iBAAiB,GAAG,IAAI,EAClC,6BAA6B,eAAe,CAAC,4BAA4B,CAAC,SAkC3E,CAAA;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,4BAA4B,GACvC,UAAU,iBAAiB,GAAG,IAAI,EAClC,gBAAgB,eAAe,CAAC,iCAAiC,CAAC,SAanE,CAAA"}
1
+ {"version":3,"file":"parameters.d.ts","sourceRoot":"","sources":["../../../src/mutators/operation/parameters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAA;AAIrE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAmClD;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,wBAAwB,GACnC,UAAU,iBAAiB,GAAG,IAAI,EAClC,4CAA4C,eAAe,CAAC,4BAA4B,CAAC,SAuE1F,CAAA;AAED;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,8BAA8B,GACzC,UAAU,iBAAiB,GAAG,IAAI,EAClC,uCAAuC,eAAe,CAAC,mCAAmC,CAAC,SA8C5F,CAAA;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,wBAAwB,GACnC,UAAU,iBAAiB,GAAG,IAAI,EAClC,6BAA6B,eAAe,CAAC,4BAA4B,CAAC,SAkC3E,CAAA;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,4BAA4B,GACvC,UAAU,iBAAiB,GAAG,IAAI,EAClC,gBAAgB,eAAe,CAAC,iCAAiC,CAAC,SAanE,CAAA"}
@@ -2,6 +2,7 @@ import { getPathItemOperation } from '../../helpers/for-each-path-item-operation
2
2
  import { getResolvedRef } from '../../helpers/get-resolved-ref.js';
3
3
  import { unpackProxyObject } from '../../helpers/unpack-proxy.js';
4
4
  import { isOpenApiDocument } from '../../schemas/type-guards.js';
5
+ import { isContentTypeParameterObject } from '../../schemas/v3.2/strict/type-guards.js';
5
6
  const getPathItemsForParameterMutation = (pathItemRef) => {
6
7
  if (!pathItemRef || typeof pathItemRef !== 'object') {
7
8
  return [];
@@ -40,23 +41,41 @@ const getPathItemsForParameterMutation = (pathItemRef) => {
40
41
  export const upsertOperationParameter = (document, { meta, type, payload, originalParameter }) => {
41
42
  // We are editing an existing parameter
42
43
  if (originalParameter) {
43
- // To support content-type parameters in the API client, we just assume an
44
- // examples property can be set.
45
44
  const param = originalParameter;
45
+ const target = isContentTypeParameterObject(param) ? Object.values(param.content ?? {})[0] : param;
46
+ if (!target) {
47
+ return;
48
+ }
49
+ if (target !== param) {
50
+ // Keep authored examples and migrate edits saved by older clients. Those edits
51
+ // already take precedence when reading, so they must also win during migration.
52
+ target.examples = {
53
+ ...(target.example !== undefined ? { default: { value: target.example } } : {}),
54
+ ...target.examples,
55
+ ...('example' in param && param.example !== undefined ? { default: { value: param.example } } : {}),
56
+ ...('examples' in param ? param.examples : {}),
57
+ };
58
+ // A media type cannot carry both the singular example and the examples map.
59
+ delete target.example;
60
+ if ('examples' in param) {
61
+ delete param.examples;
62
+ }
63
+ if ('example' in param) {
64
+ delete param.example;
65
+ }
66
+ }
46
67
  // Only update the name when the payload carries a non-empty value — an
47
68
  // empty name in the payload means the key input blurred before rendering
48
69
  // its initial value and should not overwrite the existing parameter name.
49
70
  if (payload.name || !param.name) {
50
71
  param.name = payload.name;
51
72
  }
52
- if (!param.examples) {
53
- param.examples = {};
54
- }
55
- // Create the example if it doesn't exist
56
- if (!param.examples[meta.exampleKey]) {
57
- param.examples[meta.exampleKey] = {};
73
+ target.examples ??= {};
74
+ target.examples[meta.exampleKey] ??= {};
75
+ const example = getResolvedRef(target.examples[meta.exampleKey]);
76
+ if (!example) {
77
+ return;
58
78
  }
59
- const example = getResolvedRef(param.examples[meta.exampleKey]);
60
79
  // Update the example value and disabled state
61
80
  example.value = payload.value;
62
81
  example['x-disabled'] = payload.isDisabled;
@@ -20,9 +20,12 @@ export declare const loadingStatus: () => LifecyclePlugin;
20
20
  *
21
21
  * This is useful for inlining external content (like examples or schemas) into the OpenAPI document during bundling.
22
22
  *
23
- * @param node - The node being processed, which may contain an 'externalValue' property.
23
+ * In lazy mode, preserve the absolute URL for on-demand client resolution without fetching a payload.
24
+ * The default eager mode remains available to existing bundler consumers.
24
25
  */
25
- export declare const externalValueResolver: () => LifecyclePlugin;
26
+ export declare const externalValueResolver: (options?: {
27
+ lazy?: boolean;
28
+ }) => LifecyclePlugin;
26
29
  /**
27
30
  * Lifecycle plugin to resolve $ref on any object, including non-standard locations like the info object.
28
31
  *
@@ -114,4 +117,5 @@ export declare const syncPathParameters: () => LifecyclePlugin;
114
117
  * These keys are used for internal purposes and are not needed in the final bundled document.
115
118
  */
116
119
  export declare const removeExtraScalarKeys: () => LifecyclePlugin;
120
+ export { openApiDocument, resolveOpenApiDocument } from './openapi-document.js';
117
121
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/bundler/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAAE,KAAK,eAAe,EAAwB,MAAM,2BAA2B,CAAA;AAStF;;;;;GAKG;AACH,eAAO,MAAM,aAAa,QAAO,eAahC,CAAA;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,qBAAqB,QAAO,eAmCxC,CAAA;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,QAAO,eAwCjC,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,mBAAmB,QAAO,eAuBtC,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,oBAAoB,QAAO,eAuBvC,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,aAAa,QAAO,eAyBhC,CAAA;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,kBAAkB,QAAO,eAkFrC,CAAA;AAKD;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,QAAO,eAaxC,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/bundler/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAAE,KAAK,eAAe,EAAwB,MAAM,2BAA2B,CAAA;AAStF;;;;;GAKG;AACH,eAAO,MAAM,aAAa,QAAO,eAahC,CAAA;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,qBAAqB,GAAI,UAAU;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,KAAG,eA2CpE,CAAA;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,QAAO,eAwCjC,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,mBAAmB,QAAO,eA6BtC,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,oBAAoB,QAAO,eAuBvC,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,aAAa,QAAO,eAyBhC,CAAA;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,kBAAkB,QAAO,eAkFrC,CAAA;AAKD;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,QAAO,eAaxC,CAAA;AAED,OAAO,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA"}
@@ -39,21 +39,30 @@ export const loadingStatus = () => {
39
39
  *
40
40
  * This is useful for inlining external content (like examples or schemas) into the OpenAPI document during bundling.
41
41
  *
42
- * @param node - The node being processed, which may contain an 'externalValue' property.
42
+ * In lazy mode, preserve the absolute URL for on-demand client resolution without fetching a payload.
43
+ * The default eager mode remains available to existing bundler consumers.
43
44
  */
44
- export const externalValueResolver = () => {
45
+ export const externalValueResolver = (options) => {
45
46
  return {
46
47
  type: 'lifecycle',
47
48
  onAfterNodeProcess: async (node, context) => {
48
49
  const externalValue = node['externalValue'];
49
50
  const cache = context.resolutionCache;
50
51
  // Only process if 'externalValue' is a string
51
- if (typeof externalValue !== 'string') {
52
+ if (typeof externalValue !== 'string' || node['value'] !== undefined) {
52
53
  return;
53
54
  }
54
55
  // `externalValue` may be relative (for example `/examples/pet.json`). Resolve it against the
55
56
  // origin of the document it lives in so it becomes an absolute URL a loader can fetch.
56
57
  const resolvedValue = resolveReferencePath(context.origin, externalValue);
58
+ if (options?.lazy) {
59
+ const path = context.path.at(-2) === 'examples' ? context.path : (context.referencedFromPath ?? context.path);
60
+ if (path.at(-2) !== 'examples' || isSchemaPath(path))
61
+ return;
62
+ // Preserve the referenced document origin before bundling loses that context.
63
+ node['externalValue'] = resolvedValue;
64
+ return;
65
+ }
57
66
  const loader = context.loaders.find((it) => it.validate(resolvedValue));
58
67
  // We can not process the external value
59
68
  if (!loader) {
@@ -140,9 +149,15 @@ export const refsEverywhere = () => {
140
149
  export const restoreOriginalRefs = () => {
141
150
  return {
142
151
  type: 'lifecycle',
143
- onBeforeNodeProcess: (node, context) => {
152
+ onAfterNodeProcess: (node, context) => {
144
153
  const ref = node['$ref'];
145
154
  const root = context.rootNode;
155
+ const authoredRefs = root['x-scalar-original-refs'];
156
+ const authored = isObject(authoredRefs) ? authoredRefs[JSON.stringify(context.path)] : undefined;
157
+ if (isObject(authored) && typeof authored.original === 'string' && authored.rewritten === ref) {
158
+ node['$ref'] = authored.original;
159
+ return;
160
+ }
146
161
  const extUrls = root['x-ext-urls'];
147
162
  // Only process if $ref is a string and x-ext-urls is a valid object
148
163
  if (typeof ref !== 'string' || typeof extUrls !== 'object' || extUrls === null || !isLocalRef(ref)) {
@@ -325,3 +340,4 @@ export const removeExtraScalarKeys = () => {
325
340
  },
326
341
  };
327
342
  };
343
+ export { openApiDocument, resolveOpenApiDocument } from './openapi-document.js';
@@ -0,0 +1,6 @@
1
+ import { type DocumentResolver, type LifecyclePlugin } from '@scalar/json-magic/bundle';
2
+ /** Resolves an OpenAPI document's declared identity against its retrieval location. */
3
+ export declare const resolveOpenApiDocument: DocumentResolver;
4
+ /** Honors `$self` for complete OpenAPI documents, including external and cached documents. */
5
+ export declare const openApiDocument: () => LifecyclePlugin;
6
+ //# sourceMappingURL=openapi-document.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openapi-document.d.ts","sourceRoot":"","sources":["../../../src/plugins/bundler/openapi-document.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,eAAe,EAAwB,MAAM,2BAA2B,CAAA;AAE7G,uFAAuF;AACvF,eAAO,MAAM,sBAAsB,EAAE,gBAcpC,CAAA;AAED,8FAA8F;AAC9F,eAAO,MAAM,eAAe,QAAO,eAsClC,CAAA"}
@@ -0,0 +1,57 @@
1
+ import { isObject } from '@scalar/helpers/object/is-object';
2
+ import { resolveReferencePath } from '@scalar/json-magic/bundle';
3
+ /** Resolves an OpenAPI document's declared identity against its retrieval location. */
4
+ export const resolveOpenApiDocument = (document, retrievalUri) => {
5
+ if (!isObject(document) ||
6
+ typeof document.openapi !== 'string' ||
7
+ !/^3\.2\.\d+$/.test(document.openapi) ||
8
+ typeof document.$self !== 'string') {
9
+ return undefined;
10
+ }
11
+ const self = resolveReferencePath(retrievalUri, document.$self);
12
+ // RFC 3986 requires a fragment-free base, while the declared identity can retain its fragment.
13
+ const fragmentIndex = self.indexOf('#');
14
+ const baseUri = fragmentIndex === -1 ? self : self.slice(0, fragmentIndex);
15
+ return { baseUri, metadata: { openapi: document.openapi, $self: self } };
16
+ };
17
+ /** Honors `$self` for complete OpenAPI documents, including external and cached documents. */
18
+ export const openApiDocument = () => {
19
+ const authoredRefs = new WeakMap();
20
+ const paths = new WeakMap();
21
+ const indexPaths = (value, path) => {
22
+ if (value === null || typeof value !== 'object' || paths.has(value))
23
+ return;
24
+ paths.set(value, path);
25
+ for (const [key, child] of Object.entries(value)) {
26
+ indexPaths(child, [...path, key]);
27
+ }
28
+ };
29
+ return {
30
+ type: 'lifecycle',
31
+ resolveDocument: resolveOpenApiDocument,
32
+ onBeforeNodeProcess: (node, context) => {
33
+ if (typeof node.$ref === 'string' && resolveOpenApiDocument(context.rootNode, context.origin)) {
34
+ // Partial bundles report paths relative to the selected subtree. Index the supplied root
35
+ // so the saved references can also be restored when exporting the entire document.
36
+ indexPaths(context.rootNode, []);
37
+ authoredRefs.set(node, node.$ref);
38
+ }
39
+ },
40
+ onAfterNodeProcess: (node, context) => {
41
+ const authored = authoredRefs.get(node);
42
+ if (authored === undefined || authored === node.$ref) {
43
+ return;
44
+ }
45
+ // A path-based map survives serialization and partial bundles without changing Reference Objects.
46
+ // Keep the first spelling, including fragments and ./, when a later pass rewrites it again.
47
+ const root = context.rootNode;
48
+ const existing = root['x-scalar-original-refs'];
49
+ const mapping = isObject(existing) ? existing : {};
50
+ const key = JSON.stringify(paths.get(node) ?? context.path);
51
+ const previous = mapping[key];
52
+ const original = isObject(previous) && previous.rewritten === authored ? previous.original : authored;
53
+ mapping[key] = { original, rewritten: node.$ref };
54
+ root['x-scalar-original-refs'] = mapping;
55
+ },
56
+ };
57
+ };
@@ -0,0 +1,29 @@
1
+ import type { MediaTypeObject, SchemaObject } from '@scalar/workspace-store/schemas/v3.2/strict/openapi-document';
2
+ /** Multipart parts stay structured until sending so nested text can resolve environment variables. */
3
+ export type MultipartPart = {
4
+ key?: string;
5
+ contentType?: string;
6
+ headers?: Record<string, string>;
7
+ } & ({
8
+ type: 'text';
9
+ value: string;
10
+ } | {
11
+ type: 'file';
12
+ value: File;
13
+ } | {
14
+ type: 'blob';
15
+ value: Blob;
16
+ } | {
17
+ type: 'multipart';
18
+ value: MultipartPart[];
19
+ contentType: string;
20
+ });
21
+ /** Identify ordered multipart independently of the editor's row representation. */
22
+ export declare const isPositionalMultipart: (contentType: string, media: MediaTypeObject) => boolean;
23
+ /** Whether a media type needs ordered or nested multipart serialization. */
24
+ export declare const needsMultipartEncoding: (contentType: string, media: MediaTypeObject) => boolean;
25
+ /** Resolve a positional item's schema independently of the encoding prefix length. */
26
+ export declare const getMultipartItemSchema: (schema: SchemaObject | undefined, index: number, itemSchema?: MediaTypeObject["itemSchema"]) => SchemaObject | undefined;
27
+ /** Build ordered parts, applying prefix encodings independently of schema prefix lengths. */
28
+ export declare const buildMultipart: (value: unknown, contentType: string, encoding?: Pick<MediaTypeObject, "encoding" | "prefixEncoding" | "itemEncoding" | "itemSchema">, schema?: SchemaObject, nesting?: number) => MultipartPart[];
29
+ //# sourceMappingURL=build-multipart.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-multipart.d.ts","sourceRoot":"","sources":["../../../../src/request-example/builder/body/build-multipart.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAEV,eAAe,EACf,YAAY,EACb,MAAM,8DAA8D,CAAA;AAQrE,sGAAsG;AACtG,MAAM,MAAM,aAAa,GAAG;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACjC,GAAG,CACA;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,IAAI,CAAA;CAAE,GAC7B;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,IAAI,CAAA;CAAE,GAC7B;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,aAAa,EAAE,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CACrE,CAAA;AAED,mFAAmF;AACnF,eAAO,MAAM,qBAAqB,GAAI,aAAa,MAAM,EAAE,OAAO,eAAe,KAAG,OASnF,CAAA;AAED,4EAA4E;AAC5E,eAAO,MAAM,sBAAsB,GAAI,aAAa,MAAM,EAAE,OAAO,eAAe,KAAG,OASpF,CAAA;AA4CD,sFAAsF;AACtF,eAAO,MAAM,sBAAsB,GACjC,QAAQ,YAAY,GAAG,SAAS,EAChC,OAAO,MAAM,EACb,aAAa,eAAe,CAAC,YAAY,CAAC,KACzC,YAAY,GAAG,SAMa,CAAA;AAc/B,6FAA6F;AAC7F,eAAO,MAAM,cAAc,GACzB,OAAO,OAAO,EACd,aAAa,MAAM,EACnB,WAAU,IAAI,CAAC,eAAe,EAAE,UAAU,GAAG,gBAAgB,GAAG,cAAc,GAAG,YAAY,CAAM,EACnG,SAAS,YAAY,EACrB,gBAAW,KACV,aAAa,EAkIf,CAAA"}