@scalar/workspace-store 0.64.0 → 0.66.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 +121 -0
- package/README.md +45 -10
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +109 -10
- package/dist/entities/auth/schema.d.ts +351 -20
- package/dist/entities/auth/schema.d.ts.map +1 -1
- package/dist/entities/auth/schema.js +3 -1
- package/dist/events/definitions/auth.d.ts +1 -2
- package/dist/events/definitions/auth.d.ts.map +1 -1
- package/dist/events/definitions/operation.d.ts +3 -4
- package/dist/events/definitions/operation.d.ts.map +1 -1
- package/dist/events/definitions/server.d.ts +1 -2
- package/dist/events/definitions/server.d.ts.map +1 -1
- package/dist/events/definitions/ui.d.ts +3 -4
- package/dist/events/definitions/ui.d.ts.map +1 -1
- package/dist/events/old-definitions.d.ts +1 -2
- package/dist/events/old-definitions.d.ts.map +1 -1
- package/dist/helpers/chunk-index.d.ts +20 -2
- package/dist/helpers/chunk-index.d.ts.map +1 -1
- package/dist/helpers/chunk-index.js +14 -1
- package/dist/helpers/external-examples.d.ts +2 -0
- package/dist/helpers/external-examples.d.ts.map +1 -1
- package/dist/helpers/external-examples.js +1 -0
- package/dist/helpers/for-each-path-item-operation.d.ts +6 -5
- package/dist/helpers/for-each-path-item-operation.d.ts.map +1 -1
- package/dist/helpers/for-each-path-item-operation.js +40 -14
- package/dist/helpers/get-example-value.d.ts +15 -0
- package/dist/helpers/get-example-value.d.ts.map +1 -0
- package/dist/helpers/get-example-value.js +28 -0
- package/dist/helpers/get-parameter-example.d.ts +14 -0
- package/dist/helpers/get-parameter-example.d.ts.map +1 -0
- package/dist/helpers/get-parameter-example.js +19 -0
- package/dist/helpers/get-resolved-ref.d.ts.map +1 -1
- package/dist/helpers/get-resolved-ref.js +12 -1
- package/dist/helpers/normalize-boolean-schemas.d.ts +10 -0
- package/dist/helpers/normalize-boolean-schemas.d.ts.map +1 -0
- package/dist/helpers/normalize-boolean-schemas.js +193 -0
- package/dist/helpers/operation-examples.d.ts.map +1 -1
- package/dist/helpers/operation-examples.js +5 -2
- package/dist/helpers/querystring-parameter.d.ts +21 -0
- package/dist/helpers/querystring-parameter.d.ts.map +1 -0
- package/dist/helpers/querystring-parameter.js +108 -0
- package/dist/helpers/serialize-stream-example.d.ts +8 -0
- package/dist/helpers/serialize-stream-example.d.ts.map +1 -0
- package/dist/helpers/serialize-stream-example.js +52 -0
- package/dist/helpers/use-external-examples.d.ts.map +1 -1
- package/dist/helpers/use-external-examples.js +8 -1
- package/dist/mutators/index.d.ts +3 -3
- package/dist/mutators/operation/body.d.ts.map +1 -1
- package/dist/mutators/operation/body.js +9 -2
- package/dist/mutators/operation/operation.d.ts.map +1 -1
- package/dist/mutators/operation/operation.js +4 -7
- package/dist/mutators/operation/parameters.d.ts.map +1 -1
- package/dist/mutators/operation/parameters.js +43 -3
- package/dist/navigation/get-navigation-options.d.ts.map +1 -1
- package/dist/navigation/get-navigation-options.js +19 -4
- package/dist/navigation/helpers/traverse-paths.d.ts.map +1 -1
- package/dist/navigation/helpers/traverse-paths.js +2 -2
- package/dist/navigation/helpers/traverse-webhooks.d.ts.map +1 -1
- package/dist/navigation/helpers/traverse-webhooks.js +2 -2
- package/dist/navigation/helpers/update-order-ids.d.ts +1 -2
- package/dist/navigation/helpers/update-order-ids.d.ts.map +1 -1
- package/dist/plugins/bundler/index.d.ts +1 -0
- package/dist/plugins/bundler/index.d.ts.map +1 -1
- package/dist/plugins/bundler/index.js +11 -3
- package/dist/plugins/bundler/openapi-document.d.ts +6 -0
- package/dist/plugins/bundler/openapi-document.d.ts.map +1 -0
- package/dist/plugins/bundler/openapi-document.js +57 -0
- package/dist/request-example/builder/body/build-multipart.d.ts +29 -0
- package/dist/request-example/builder/body/build-multipart.d.ts.map +1 -0
- package/dist/request-example/builder/body/build-multipart.js +191 -0
- package/dist/request-example/builder/body/build-request-body.d.ts +6 -1
- package/dist/request-example/builder/body/build-request-body.d.ts.map +1 -1
- package/dist/request-example/builder/body/build-request-body.js +80 -23
- package/dist/request-example/builder/body/encode-multipart-body.d.ts +8 -8
- package/dist/request-example/builder/body/encode-multipart-body.d.ts.map +1 -1
- package/dist/request-example/builder/body/encode-multipart-body.js +56 -18
- package/dist/request-example/builder/body/get-request-body-example.d.ts.map +1 -1
- package/dist/request-example/builder/body/get-request-body-example.js +20 -6
- package/dist/request-example/builder/body/multipart-limits.d.ts +3 -0
- package/dist/request-example/builder/body/multipart-limits.d.ts.map +1 -0
- package/dist/request-example/builder/body/multipart-limits.js +2 -0
- package/dist/request-example/builder/body/serialize-form-property.d.ts +2 -0
- package/dist/request-example/builder/body/serialize-form-property.d.ts.map +1 -1
- package/dist/request-example/builder/body/serialize-form-property.js +3 -2
- package/dist/request-example/builder/body/serialize-multipart-array.d.ts +1 -1
- package/dist/request-example/builder/build-request.d.ts.map +1 -1
- package/dist/request-example/builder/build-request.js +7 -1
- package/dist/request-example/builder/header/build-request-parameters.d.ts +2 -0
- package/dist/request-example/builder/header/build-request-parameters.d.ts.map +1 -1
- package/dist/request-example/builder/header/build-request-parameters.js +54 -11
- package/dist/request-example/builder/header/is-param-disabled.d.ts.map +1 -1
- package/dist/request-example/builder/header/is-param-disabled.js +3 -1
- package/dist/request-example/builder/header/serialize-parameter.d.ts +11 -0
- package/dist/request-example/builder/header/serialize-parameter.d.ts.map +1 -1
- package/dist/request-example/builder/header/serialize-parameter.js +22 -0
- package/dist/request-example/builder/helpers/get-example-from-schema.d.ts.map +1 -1
- package/dist/request-example/builder/helpers/get-example-from-schema.js +42 -3
- package/dist/request-example/builder/helpers/get-example.d.ts.map +1 -1
- package/dist/request-example/builder/helpers/get-example.js +5 -2
- package/dist/request-example/builder/index.d.ts +2 -2
- package/dist/request-example/builder/index.d.ts.map +1 -1
- package/dist/request-example/builder/index.js +1 -1
- package/dist/request-example/builder/request-factory.d.ts +7 -0
- package/dist/request-example/builder/request-factory.d.ts.map +1 -1
- package/dist/request-example/builder/request-factory.js +10 -1
- package/dist/request-example/builder/resolve-request-factory-url.d.ts.map +1 -1
- package/dist/request-example/builder/resolve-request-factory-url.js +18 -2
- package/dist/request-example/builder/security/secret-types.d.ts +4 -1
- package/dist/request-example/builder/security/secret-types.d.ts.map +1 -1
- package/dist/request-example/context/headers.d.ts +1 -2
- package/dist/request-example/context/headers.d.ts.map +1 -1
- package/dist/request-example/context/security/extract-security-scheme-secrets.d.ts.map +1 -1
- package/dist/request-example/context/security/extract-security-scheme-secrets.js +15 -0
- package/dist/request-example/index.d.ts +5 -2
- package/dist/request-example/index.d.ts.map +1 -1
- package/dist/request-example/index.js +4 -1
- package/dist/request-example/types.d.ts +1 -2
- package/dist/request-example/types.d.ts.map +1 -1
- package/dist/request-example/xml/serialize-xml-part.d.ts +9 -0
- package/dist/request-example/xml/serialize-xml-part.d.ts.map +1 -0
- package/dist/request-example/xml/serialize-xml-part.js +12 -0
- package/dist/schemas/extensions/operation/x-code-samples.d.ts +22 -0
- package/dist/schemas/extensions/operation/x-code-samples.d.ts.map +1 -1
- package/dist/schemas/extensions/operation/x-code-samples.js +4 -0
- package/dist/schemas/extensions.d.ts +9 -0
- package/dist/schemas/extensions.d.ts.map +1 -1
- package/dist/schemas/extensions.js +9 -0
- package/dist/schemas/navigation.d.ts +40 -34
- package/dist/schemas/navigation.d.ts.map +1 -1
- package/dist/schemas/navigation.js +2 -3
- package/dist/schemas/reference-config/index.d.ts +24 -4
- package/dist/schemas/reference-config/index.d.ts.map +1 -1
- package/dist/schemas/reference-config/settings.d.ts +24 -4
- package/dist/schemas/reference-config/settings.d.ts.map +1 -1
- package/dist/schemas/v3.1/strict/oauthflows.d.ts +26 -0
- package/dist/schemas/v3.1/strict/oauthflows.d.ts.map +1 -1
- package/dist/schemas/v3.1/strict/oauthflows.js +3 -0
- package/dist/schemas/v3.1/strict/openapi-document.d.ts +1582 -147
- package/dist/schemas/v3.1/strict/openapi-document.d.ts.map +1 -1
- package/dist/schemas/v3.1/strict/operation.d.ts +8 -0
- package/dist/schemas/v3.1/strict/operation.d.ts.map +1 -1
- package/dist/schemas/v3.1/strict/path-item.d.ts +19 -0
- package/dist/schemas/v3.1/strict/path-item.d.ts.map +1 -1
- package/dist/schemas/v3.1/strict/path-item.js +5 -0
- package/dist/schemas/v3.2/openapi/index.d.ts +5 -0
- package/dist/schemas/v3.2/openapi/index.d.ts.map +1 -1
- package/dist/schemas/v3.2/openapi/index.js +48 -12
- package/dist/schemas/v3.2/openapi/reference.d.ts.map +1 -1
- package/dist/schemas/v3.2/openapi/reference.js +11 -3
- package/dist/schemas/v3.2/strict/openapi-document.d.ts +842 -140
- package/dist/schemas/v3.2/strict/openapi-document.d.ts.map +1 -1
- package/dist/schemas/v3.2/strict/openapi-document.js +6 -14
- package/dist/schemas/v3.2/strict/operation.d.ts +8 -0
- package/dist/schemas/v3.2/strict/operation.d.ts.map +1 -1
- package/dist/schemas/v3.2/strict/parameter.d.ts +14 -0
- package/dist/schemas/v3.2/strict/parameter.d.ts.map +1 -1
- package/dist/schemas/v3.2/strict/parameter.js +2 -0
- package/dist/server.d.ts +10 -6
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +67 -45
- package/package.json +19 -9
- package/dist/schemas/v3.1/openapi/index.d.ts +0 -149
- package/dist/schemas/v3.1/openapi/index.d.ts.map +0 -1
- package/dist/schemas/v3.1/openapi/index.js +0 -732
- package/dist/schemas/v3.1/openapi/reference.d.ts +0 -4
- package/dist/schemas/v3.1/openapi/reference.d.ts.map +0 -1
- package/dist/schemas/v3.1/openapi/reference.js +0 -29
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,126 @@
|
|
|
1
1
|
# @scalar/workspace-store
|
|
2
2
|
|
|
3
|
+
## 0.66.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#10189](https://github.com/scalar/scalar/pull/10189): Support OpenAPI 3.2 `in: querystring` parameters, including content-based serialization, editing the entire query string, schema rendering, and generated request URLs.
|
|
8
|
+
|
|
9
|
+
Non-form whole-query content, including JSON delimiters, is percent-encoded in request URLs and code samples. Use an example with `serializedValue` on the parameter itself for URI-ready query content that must retain its existing encoding.
|
|
10
|
+
|
|
11
|
+
Preserve the encoding of named query values when they coexist with whole-query content in generated code samples, while encoding query authentication values once.
|
|
12
|
+
|
|
13
|
+
Explain why the whole-query editor disables adding named parameters. Existing named parameters follow the whole-query value, preserving duplicate keys for the server to interpret.
|
|
14
|
+
|
|
15
|
+
- [#10186](https://github.com/scalar/scalar/pull/10186): Support OpenAPI 3.2 additionalOperations in operation storage, navigation, documentation, callbacks, and the API client. Preserve custom HTTP method spelling when displaying and sending requests and generating code samples.
|
|
16
|
+
|
|
17
|
+
Traversed operation and webhook methods now use the exported `OperationMethod` type, which accepts custom strings while retaining known-method editor completion. Consumers must handle unknown methods; this open type cannot provide exhaustive checking over the fixed HTTP method set. Unknown method presentation uses `colorClass` and `colorVar`, matching known methods. Preserve uppercase and mixed-case additional operation names consistently.
|
|
18
|
+
|
|
19
|
+
- [#10310](https://github.com/scalar/scalar/pull/10310): Connect SDK code samples to named request body examples using optional example and contentType fields. Keep the example switcher available for static samples and use the selected request example in API client snippets. Display unavailable linked samples as a localized status message in all supported languages.
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- [#10186](https://github.com/scalar/scalar/pull/10186): Preserve authored method variants in request data and navigation links. Generate custom-method requests with generic client APIs, and explain when RestSharp cannot represent a method.
|
|
24
|
+
- [#10186](https://github.com/scalar/scalar/pull/10186): Include the current document-defined custom method in the request method picker and preserve its spelling when selected.
|
|
25
|
+
|
|
26
|
+
Keep QUERY operation chunk names aligned with their references when additional operations are supported.
|
|
27
|
+
|
|
28
|
+
- [#10186](https://github.com/scalar/scalar/pull/10186): Preserve request bodies for extension HTTP methods such as QUERY and PROPFIND in the browser client.
|
|
29
|
+
- [#10322](https://github.com/scalar/scalar/pull/10322): Use OpenAPI 3.2 dataValue and serializedValue examples for named parameters in the editor, outgoing requests, and code samples. Preserve already serialized values without encoding them twice.
|
|
30
|
+
|
|
31
|
+
Optional parameters with `dataValue` or `serializedValue` examples are now enabled by default, matching legacy `value` examples. Explicitly disabled examples remain disabled.
|
|
32
|
+
|
|
33
|
+
Parameter-level `serializedValue` examples remain editable as raw wire text, including parameter names and percent encoding (for example, `term=hello` rather than `hello`). Media-level cookie examples are percent-encoded when sent, matching generated snippets. Generating snippets no longer modifies the input cookies.
|
|
34
|
+
|
|
35
|
+
- [#10319](https://github.com/scalar/scalar/pull/10319): Update the OpenAPI version badge when the document version changes during live editing.
|
|
36
|
+
- [#10315](https://github.com/scalar/scalar/pull/10315): Stop following `$ref-value` chains at the first reference that loops back, so a document whose references point at each other (or at themselves) no longer overflows the stack while it loads.
|
|
37
|
+
|
|
38
|
+
## 0.65.0
|
|
39
|
+
|
|
40
|
+
### Minor Changes
|
|
41
|
+
|
|
42
|
+
- [#10177](https://github.com/scalar/scalar/pull/10177): Use OpenAPI 3.2 schemas throughout workspace-store consumers, stories, tests, and type generation. Update the app editor to offer OpenAPI 3.2 validation and completion while continuing to accept existing 3.1 documents.
|
|
43
|
+
|
|
44
|
+
Preserve OpenAPI 3.2 fields in the loose workspace schema, including tag hierarchy, streaming media types, nested encoding, additional operations, and OAuth device authorization.
|
|
45
|
+
|
|
46
|
+
The editor intentionally offers the 3.2 field set to documents declaring 3.1 as well; it does not flag 3.2-only fields solely because the declared version is 3.1. This does not certify conformance to the declared version or automatically update it. Before using 3.2-only fields, migrate and explicitly declare OpenAPI 3.2, and verify support in other validators and generators. Remove the unused 3.1 loose-schema generator to prevent schema drift.
|
|
47
|
+
|
|
48
|
+
Migration: the OpenAPI 3.1 loose-schema generator (`@scalar/workspace-store/schemas/v3.1/openapi`, published through the wildcard as `@scalar/workspace-store/schemas/v3.1/openapi/index`) and its `@scalar/workspace-store/schemas/v3.1/openapi/reference` helpers have been removed. Import the generator from `@scalar/workspace-store/schemas/v3.2/openapi/index` and the reference helpers from `@scalar/workspace-store/schemas/v3.2/openapi/reference` instead. The `./schemas/*` wildcard and the 3.1 strict-schema exports remain available; the explicit 3.2 strict-schema exports are additive. Locally generated types now use the `OpenAPIV3_2` namespace instead of `OpenAPIV3_1`.
|
|
49
|
+
|
|
50
|
+
Inline the editor path-extension reference so Monaco retains the leading-slash path pattern and does not report valid paths as unknown properties.
|
|
51
|
+
|
|
52
|
+
Document ingestion continues to upgrade only to OpenAPI 3.1, so existing inline XML bodies without `xml.name` remain loadable. This schema migration does not opt consumers into the stricter OpenAPI 3.2 XML upgrade.
|
|
53
|
+
|
|
54
|
+
- [#10191](https://github.com/scalar/scalar/pull/10191): Support OpenAPI 3.2 OAuth device authorization with verification codes, cancellable token polling, stored credentials, and OAuth metadata discovery. Add mock device authorization and approval endpoints with pending, denial, expiry, and polling backoff responses.
|
|
55
|
+
|
|
56
|
+
Use consistent form-encoded Basic credentials and environment substitution across OAuth token and refresh flows. Allow HTTP metadata and verification links on local development hosts and reserved test domains, coerce discovery fields consistently, and report device-code expiry clearly.
|
|
57
|
+
|
|
58
|
+
- [#10208](https://github.com/scalar/scalar/pull/10208): Share OpenAPI 3.2 example-value selection across request bodies, response examples, and code snippets. Preserve serialized payloads verbatim, serialize structured JSON strings correctly, retain falsy values, and replace original example sources after body edits. Keep dataValue and serializedValue during document ingestion.
|
|
59
|
+
|
|
60
|
+
Editing a request body, including form fields, discards its authored `externalValue` URL and replaces it with the edited inline value in the workspace and exported API description. Rendering or focusing a form field preserves the external source.
|
|
61
|
+
|
|
62
|
+
Form editors prefer structured `dataValue` when both example fields exist, while raw editors, requests, and code snippets preserve `serializedValue` as wire text. Structured examples now affect generated request payloads and snippets; XML remains raw-only in the request editor.
|
|
63
|
+
|
|
64
|
+
- [#10178](https://github.com/scalar/scalar/pull/10178): Support OpenAPI 3.2 streaming item schemas in the workspace store, request body examples, and API reference schema views. Frame generated and structured examples as JSON Lines, JSON Sequence, or server-sent events while preserving explicit wire-format strings.
|
|
65
|
+
|
|
66
|
+
Preserve generated falsy request examples (`0`, `false`, and empty strings) for non-streaming bodies as well.
|
|
67
|
+
|
|
68
|
+
Use cURL `--data-binary` for supported streaming media types, making framed body handling explicit. Authored arrays and objects are framed as stream records; authored wire-format strings remain unchanged. SSE records with no valid fields are safely omitted with one console warning per serialization call reporting the omitted count, including when all records are omitted.
|
|
69
|
+
|
|
70
|
+
### Patch Changes
|
|
71
|
+
|
|
72
|
+
- [#10298](https://github.com/scalar/scalar/pull/10298): Keep the navigation header inline in a compact document, so `x-scalar-navigation.name`, `title` and the other fields stay readable by plain property access and auth, history and the client modal keep working. Only the children travel in the navigation chunk, and `resolve(['x-scalar-navigation'])` loads them onto the document in place. This replaces the 0.64.0 compact wire form, which sent the whole navigation as a chunk reference.
|
|
73
|
+
|
|
74
|
+
Keep pending navigation loads separate when a workspace is reloaded or a document is replaced, so the current document receives its children and stale requests do not publish changes.
|
|
75
|
+
|
|
76
|
+
- [#10251](https://github.com/scalar/scalar/pull/10251): Preserve chained path-item references with non-enumerable links.
|
|
77
|
+
|
|
78
|
+
Remove the HTML output APIs `createHtmlFromOpenApi` and `renderer.renderHtml` from `@scalar/openapi-to-markdown`. Use `createMarkdownFromOpenApi` or `renderer.render` and convert the resulting Markdown with an application-provided renderer when HTML is needed.
|
|
79
|
+
|
|
80
|
+
- [#10203](https://github.com/scalar/scalar/pull/10203): Add a picker for generated response examples with anyOf or oneOf schema variants.
|
|
81
|
+
|
|
82
|
+
Apply union selections to primitive and array examples in the shared generator without reusing the selection for nested unions.
|
|
83
|
+
|
|
84
|
+
The shared generator change also affects request examples, snippets, mock responses, and AsyncAPI payloads: root primitive/array unions now generate their chosen branch before type inference from sibling properties or items. For example, a string schema with `oneOf: [{ const: "first" }, { const: "second" }]` now generates `"first"` by default, and selecting the second branch generates `"second"`. Keywords for unrelated types do not force object/array generation. Root selections are consumed once; nested unions retain their own default or path-specific choice.
|
|
85
|
+
|
|
86
|
+
Do not show a response variant picker for an empty enum, which permits no valid alternatives.
|
|
87
|
+
|
|
88
|
+
Preserve the generated branch shape in mock HTTP responses instead of re-wrapping selected primitive values as arrays based on root sibling `items`. Explicit authored examples retain the existing array normalization.
|
|
89
|
+
|
|
90
|
+
- [#10201](https://github.com/scalar/scalar/pull/10201): Support positional and nested multipart request encoding with prefixEncoding, itemEncoding, and nested encoding objects. Keep generated code snippets in sync with multipart request bodies.
|
|
91
|
+
|
|
92
|
+
Reject ambiguous named positional items and multipart nesting beyond eight levels. Use a stable fallback root for XML parts.
|
|
93
|
+
|
|
94
|
+
Document multipart content-type defaults and wildcard selection policies. Route structured XML parts through a shared adapter while retaining legacy root-name behavior.
|
|
95
|
+
|
|
96
|
+
Regenerate multipart boundaries that collide with resolved text or nested delimiters, keeping binary payload bytes intact.
|
|
97
|
+
|
|
98
|
+
- [#10272](https://github.com/scalar/scalar/pull/10272): Preserve components named `__proto__` when generating sparse server documents.
|
|
99
|
+
- [#10303](https://github.com/scalar/scalar/pull/10303): Preserve parameter edits when another parameter changes, including parameters displaying downloaded examples. Keep downloaded values out of the document until explicitly edited, and use examples and defaults from resolved schema references when building requests.
|
|
100
|
+
- [#10172](https://github.com/scalar/scalar/pull/10172): Preserve boolean schema semantics during client and server ingestion by normalizing true and false schemas to equivalent object schemas before coercion. Keep boolean examples, annotations, and additionalProperties values unchanged.
|
|
101
|
+
|
|
102
|
+
Server normalization now copies only changed schema containers and their ancestors, preserving caller-owned values and sharing unchanged bundled data. Iterative normalization supports deep schema graphs without adding a recursive clone at server ingestion. Opaque example/default/enum/const values remain literal, including in external resources named like OpenAPI map fields.
|
|
103
|
+
|
|
104
|
+
Internal schema markers remain available through backing-data APIs such as `getRaw`, but are omitted from public proxy serialization, rendered schema fields, and saved JSON/YAML API-description exports.
|
|
105
|
+
|
|
106
|
+
After saving, normalized schema positions export `true` as `{}` and `false` as `{ not: {} }`. Validation semantics are unchanged, but the saved representation can differ from the authored text. Boolean `additionalProperties` stays literal `true` or `false`, including after saving and exporting. Original, unsaved exports retain their authored boolean schemas. JSON and YAML exports share the existing save/edit cleanup boundary for internal markers.
|
|
107
|
+
|
|
108
|
+
- [#10198](https://github.com/scalar/scalar/pull/10198): Support OpenAPI 3.2 cookie serialization with semicolon-separated entries and no percent-encoding in requests and code examples.
|
|
109
|
+
|
|
110
|
+
Browser XHR and jQuery code examples now set explicit Cookie header values through `document.cookie` and enable credentialed requests, including when no structured HAR cookies are supplied. Run the cookie setup on the request origin. Requests without cookie-style parameters retain structured HAR cookies alongside explicit Cookie headers.
|
|
111
|
+
|
|
112
|
+
Warn once per parameter name in the developer console when cookie-style parameters declare invalid `explode: false`, then use the expanded fallback consistently for requests and snippets. Browser cookie setup cannot assign cookies to an unrelated API domain; credentialed cross-origin responses require the appropriate CORS configuration and eligible stored cookies.
|
|
113
|
+
|
|
114
|
+
- [#10206](https://github.com/scalar/scalar/pull/10206): Add generic document identity hooks for bundling and an explicit root URI option for reference proxies. Honor OpenAPI 3.2 `$self` through an OpenAPI plugin in workspace-store, including external documents and partial bundles, and enable it in OpenAPI bundling callers.
|
|
115
|
+
|
|
116
|
+
URI resolution now honors root-relative and protocol-relative URLs, query/fragment references, and trailing-slash directory bases for all bundler consumers. Absolute non-HTTP identifiers remain unchanged instead of becoming filesystem paths; loader support is unchanged. Relative HTTP references retain query strings and fragments and are emitted only when they round-trip to the original URL.
|
|
117
|
+
|
|
118
|
+
Preserve authored reference spellings through serialized partial bundles and editable exports, while keeping older OpenAPI resolution and configured loader restrictions unchanged.
|
|
119
|
+
|
|
120
|
+
Keep references matching authored root schema identifiers intact so schema labels and anchors retain their existing behavior.
|
|
121
|
+
|
|
122
|
+
- [#10279](https://github.com/scalar/scalar/pull/10279): Write workspace chunks to the requested absolute output directory, including Windows drives and network shares.
|
|
123
|
+
|
|
3
124
|
## 0.64.0
|
|
4
125
|
|
|
5
126
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -203,11 +203,12 @@ references.
|
|
|
203
203
|
|
|
204
204
|
`compact: true` changes how that document is spelled on the wire, and nothing else:
|
|
205
205
|
|
|
206
|
-
- `x-scalar-navigation`
|
|
207
|
-
`chunks/<document>/navigation.json` in `static` mode
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
`
|
|
206
|
+
- `x-scalar-navigation` keeps its document entry — `name`, `title`, `icon` and the rest — and leaves
|
|
207
|
+
only its children in a chunk, written to `chunks/<document>/navigation.json` in `static` mode and
|
|
208
|
+
served by `get('#/<document>/navigation')` in `ssr` mode. `children` is an empty array until
|
|
209
|
+
`store.resolve(['x-scalar-navigation'])` loads them onto the document in place, and
|
|
210
|
+
`x-scalar-navigation-chunk` says where they are until it does. The navigation is never a reference,
|
|
211
|
+
so every reader takes it by plain property access whether or not the document was sent compact.
|
|
211
212
|
- The per-node references under `components` and `paths` are replaced by one `x-scalar-chunk-index`
|
|
212
213
|
extension listing what exists, plus a template per kind saying how a reference to it is spelled.
|
|
213
214
|
The two sections are omitted; anything in them that was never externalized (a path item's
|
|
@@ -226,13 +227,19 @@ const store = await createServerWorkspaceStore({
|
|
|
226
227
|
{
|
|
227
228
|
"openapi": "3.1.0",
|
|
228
229
|
"info": { "title": "Petstore", "version": "1.0.0" },
|
|
229
|
-
"x-scalar-navigation": {
|
|
230
|
+
"x-scalar-navigation": {
|
|
231
|
+
"id": "petstore",
|
|
232
|
+
"type": "document",
|
|
233
|
+
"title": "Petstore",
|
|
234
|
+
"name": "petstore",
|
|
235
|
+
"children": []
|
|
236
|
+
},
|
|
237
|
+
"x-scalar-navigation-chunk": "./chunks/petstore/navigation.json#",
|
|
230
238
|
"x-scalar-chunk-index": {
|
|
231
239
|
"mode": "static",
|
|
232
240
|
"refs": {
|
|
233
241
|
"components": "./chunks/petstore/components/{type}/{name}.json#",
|
|
234
|
-
"operations": "./chunks/petstore/operations/{path}/{method}.json#"
|
|
235
|
-
"navigation": "./chunks/petstore/navigation.json#"
|
|
242
|
+
"operations": "./chunks/petstore/operations/{path}/{method}.json#"
|
|
236
243
|
},
|
|
237
244
|
"components": { "schemas": ["Pet", "Error"] },
|
|
238
245
|
// `0` marks an operation that was externalized; every other key is kept as it was
|
|
@@ -244,8 +251,11 @@ const store = await createServerWorkspaceStore({
|
|
|
244
251
|
The client store expands the index back into the same references as it ingests the document — through
|
|
245
252
|
`addDocument`, `importWorkspaceFromSpecification`, `replaceDocument`, `revertDocumentChanges` or
|
|
246
253
|
`loadWorkspace` — and drops the extension, so what it holds in memory is exactly what a non-compact
|
|
247
|
-
server store would have produced, with the navigation
|
|
248
|
-
bundler and anything enumerating `paths` or `components` see the shape they always
|
|
254
|
+
server store would have produced, with the unloaded navigation children the one difference.
|
|
255
|
+
`resolve()`, the bundler and anything enumerating `paths` or `components` see the shape they always
|
|
256
|
+
have. The navigation chunk is loaded once: concurrent resolves share the request, a later one makes
|
|
257
|
+
none, and a workspace exported before the children were loaded can still load them after
|
|
258
|
+
`loadWorkspace` puts it in another store.
|
|
249
259
|
|
|
250
260
|
`getResolvedDocument()` is unaffected and still carries the whole document and its navigation, and so
|
|
251
261
|
are AsyncAPI documents, which are never externalized.
|
|
@@ -574,3 +584,28 @@ await result.applyChanges({ resolvedDocument: newDocument })
|
|
|
574
584
|
```
|
|
575
585
|
|
|
576
586
|
After `applyChanges` returns, the merged document becomes both the new active document and the new saved baseline, so a subsequent `revertDocumentChanges` rolls back to the post-rebase state rather than the pre-rebase original.
|
|
587
|
+
|
|
588
|
+
## OpenAPI document identity
|
|
589
|
+
|
|
590
|
+
The store honors `$self` when resolving relative references in an OpenAPI 3.2 description. Relative identities resolve against the document source URL. External documents keep their own identities, including across partial bundles.
|
|
591
|
+
|
|
592
|
+
Other OpenAPI bundling callers can opt in with the same plugin:
|
|
593
|
+
|
|
594
|
+
```ts
|
|
595
|
+
import { bundle } from '@scalar/json-magic/bundle'
|
|
596
|
+
import { fetchUrls } from '@scalar/json-magic/bundle/plugins/browser'
|
|
597
|
+
import { createMagicProxy } from '@scalar/json-magic/magic-proxy'
|
|
598
|
+
import { openApiDocument, resolveOpenApiDocument } from '@scalar/workspace-store/plugins/bundler'
|
|
599
|
+
|
|
600
|
+
const document = await bundle('https://example.com/openapi.json', {
|
|
601
|
+
plugins: [fetchUrls(), openApiDocument()],
|
|
602
|
+
treeShake: false,
|
|
603
|
+
})
|
|
604
|
+
const resolved = createMagicProxy(document, {
|
|
605
|
+
documentUri: resolveOpenApiDocument(document, '/')?.baseUri,
|
|
606
|
+
})
|
|
607
|
+
```
|
|
608
|
+
|
|
609
|
+
The plugin interprets `$self` only on complete OpenAPI documents. Example payloads and API server URLs are unchanged.
|
|
610
|
+
|
|
611
|
+
Authored reference spellings (including `./` and fragments) are retained across partial bundles and restored by `getEditableDocument`. Loader permissions still apply to the resolved location: `$self` does not enable a loader or widen its file or network access.
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,YAAY,EAAU,MAAM,2BAA2B,CAAA;AAErE,OAAO,EAAE,KAAK,UAAU,EAAe,KAAK,EAAE,MAAM,yBAAyB,CAAA;AAQ7E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAI5C,OAAO,EAAE,KAAK,SAAS,EAAmB,MAAM,iBAAiB,CAAA;AACjE,OAAO,EAAE,KAAK,YAAY,EAAsB,MAAM,oBAAoB,CAAA;AAK1E,OAAO,EAAE,KAAK,uBAAuB,EAAiC,MAAM,6BAA6B,CAAA;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,YAAY,EAAU,MAAM,2BAA2B,CAAA;AAErE,OAAO,EAAE,KAAK,UAAU,EAAe,KAAK,EAAE,MAAM,yBAAyB,CAAA;AAQ7E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAI5C,OAAO,EAAE,KAAK,SAAS,EAAmB,MAAM,iBAAiB,CAAA;AACjE,OAAO,EAAE,KAAK,YAAY,EAAsB,MAAM,oBAAoB,CAAA;AAK1E,OAAO,EAAE,KAAK,uBAAuB,EAAiC,MAAM,6BAA6B,CAAA;AASzG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAA;AAc5E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAA;AAKrE,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,wCAAwC,CAAA;AAC/C,OAAO,KAAK,EACV,sBAAsB,EACtB,SAAS,EACT,iBAAiB,EACjB,qBAAqB,EACrB,mBAAmB,EACnB,aAAa,EACd,MAAM,qBAAqB,CAAA;AAC5B,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAA;AAC/E,OAAO,KAAK,EAAE,eAAe,EAA6B,MAAM,oBAAoB,CAAA;AAgBpF;;;GAGG;AACH,KAAK,0BAA0B,GAAG;IAChC,wEAAwE;IACxE,IAAI,CAAC,EAAE,qBAAqB,CAAA;IAC5B,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAA;IACZ,iCAAiC;IACjC,SAAS,CAAC,EAAE,WAAW,CAAC,eAAe,CAAC,CAAA;IACxC,wIAAwI;IACxI,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,GAAG,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;CAC5F,CAAA;AAED;;;GAGG;AACH,MAAM,MAAM,MAAM,GAAG;IACnB,6CAA6C;IAC7C,GAAG,EAAE,MAAM,CAAA;CACZ,GAAG,0BAA0B,CAAA;AAE9B;;;GAGG;AACH,MAAM,MAAM,OAAO,GAAG;IACpB,+DAA+D;IAC/D,IAAI,EAAE,MAAM,CAAA;CACb,GAAG,0BAA0B,CAAA;AAE9B,iGAAiG;AACjG,MAAM,MAAM,SAAS,GAAG;IACtB,mEAAmE;IACnE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAClC,GAAG,0BAA0B,CAAA;AAE9B;;;;GAIG;AACH,MAAM,MAAM,sBAAsB,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,CAAA;AAsEjE;;;GAGG;AACH,KAAK,cAAc,GAAG;IACpB,gFAAgF;IAChF,IAAI,CAAC,EAAE,aAAa,CAAA;IACpB,8CAA8C;IAC9C,KAAK,CAAC,EAAE,sBAAsB,CAAC,OAAO,CAAC,CAAA;IACvC;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,iEAAiE;IACjE,OAAO,CAAC,EAAE,eAAe,EAAE,CAAA;IAC3B,8FAA8F;IAC9F,UAAU,CAAC,EAAE,YAAY,CAAA;IACzB;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB,CAAA;AAED;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,mFAAmF;IACnF,gBAAgB,EAAE,CAAC,YAAY,CAAC,EAAE,MAAM,KAAK,uBAAuB,CAAA;IAEpE;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAA;IAC9B;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;IACxB;;OAEG;IACH,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAA;IAC7B;;;;;;;OAOG;IACH,MAAM,CAAC,CAAC,SAAS,MAAM,aAAa,GAAG,MAAM,mBAAmB,EAC9D,GAAG,EAAE,CAAC,EACN,KAAK,EAAE,CAAC,aAAa,GAAG,mBAAmB,CAAC,CAAC,CAAC,CAAC,GAC9C,IAAI,CAAA;IACP;;;;;;;;;;;OAWG;IACH,cAAc,CAAC,CAAC,SAAS,MAAM,sBAAsB,EACnD,IAAI,EAAE,QAAQ,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,EAC9B,GAAG,EAAE,CAAC,EACN,KAAK,EAAE,sBAAsB,CAAC,CAAC,CAAC,GAC/B,OAAO,CAAA;IACV;;;;;;;;;;;;;;;OAeG;IACH,eAAe,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACpF;;;;;;;;;;OAUG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IACzC;;;;;;;;;;;;;;;;OAgBG;IACH,WAAW,CAAC,KAAK,EAAE,sBAAsB,EAAE,iBAAiB,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IACnG;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1C;;;;;;;;;;;;;;;;;;OAkBG;IACH,cAAc,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAAA;IACnG;;;;;;;;;;;;;;;;;OAiBG;IACH,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAAA;IACnF;;;;;OAKG;IACH,mBAAmB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAA;IAC5E;;;;;;;OAOG;IACH,mBAAmB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;IACzE;;;;;;;;;;;;;;;OAeG;IACH,uBAAuB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;IAC7E;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACH,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IACpD;;;;;OAKG;IACH,YAAY,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAA;IAC/C;;;;;;;;;;;;;;;;;OAiBG;IACH,qBAAqB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1D;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,6BAA6B,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAA;IAC5D;;;;;;;;;OASG;IACH,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1C;;;;;;;;;;OAUG;IACH,eAAe,IAAI,iBAAiB,CAAA;IACpC;;;;;;;OAOG;IACH,aAAa,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAAA;IAC7C;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,gCAAgC,CAAC,aAAa,EAAE,sBAAsB,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAA;IAC3F;;;;;;;;;;;;;;;;;;;OAmBG;IACH,cAAc,EAAE,CAAC,KAAK,EAAE,sBAAsB,KAAK,OAAO,CACtD;QACE,EAAE,EAAE,KAAK,CAAA;QACT,IAAI,EAAE,iBAAiB,GAAG,cAAc,GAAG,qBAAqB,CAAA;QAChE,OAAO,EAAE,MAAM,CAAA;KAChB,GACD;QACE,EAAE,EAAE,IAAI,CAAA;QACR,OAAO,EAAE,UAAU,CAAC,OAAO,KAAK,CAAC,CAAC,OAAO,CAAC,CAAA;QAC1C,SAAS,EAAE,UAAU,CAAC,OAAO,KAAK,CAAC,CAAC,WAAW,CAAC,CAAA;QAChD,YAAY,EAAE,CACZ,iBAAiB,EACb;YACE,iBAAiB,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,CAAA;SACzC,GACD;YACE,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;SAC1C,KACF,OAAO,CAAC,IAAI,CAAC,CAAA;KACnB,CACJ,CAAA;CACF,CAAA;AAyDD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,oBAAoB,GAAI,iBAAiB,cAAc,KAAG,cA2tCtE,CAAA;AAGD,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAA"}
|
package/dist/client.js
CHANGED
|
@@ -16,18 +16,20 @@ import { reactive } from 'vue';
|
|
|
16
16
|
import YAML from 'yaml';
|
|
17
17
|
import { createAuthStore } from './entities/auth/index.js';
|
|
18
18
|
import { createHistoryStore } from './entities/history/index.js';
|
|
19
|
-
import { expandChunkIndex } from './helpers/chunk-index.js';
|
|
19
|
+
import { chunkReference, expandChunkIndex } from './helpers/chunk-index.js';
|
|
20
20
|
import { deepClone } from './helpers/deep-clone.js';
|
|
21
21
|
import { createDetectChangesProxy } from './helpers/detect-changes-proxy.js';
|
|
22
22
|
import { bumpDocumentRevision } from './helpers/document-revision.js';
|
|
23
23
|
import { createExternalExampleResolver } from './helpers/external-examples.js';
|
|
24
24
|
import { safeAssign } from './helpers/general.js';
|
|
25
25
|
import { getFetch } from './helpers/get-fetch.js';
|
|
26
|
+
import { getResolvedRef } from './helpers/get-resolved-ref.js';
|
|
26
27
|
import { mergeObjects } from './helpers/merge-object.js';
|
|
28
|
+
import { normalizeBooleanSchemas } from './helpers/normalize-boolean-schemas.js';
|
|
27
29
|
import { createOverridesProxy } from './helpers/overrides-proxy.js';
|
|
28
30
|
import { unpackProxyObject } from './helpers/unpack-proxy.js';
|
|
29
31
|
import { createNavigation, traverseAsyncApiDocument } from './navigation/index.js';
|
|
30
|
-
import { externalValueResolver, loadingStatus, normalizeAuthSchemes, normalizeRefs, refsEverywhere, removeExtraScalarKeys, restoreOriginalRefs, syncPathParameters, } from './plugins/bundler/index.js';
|
|
32
|
+
import { externalValueResolver, loadingStatus, normalizeAuthSchemes, normalizeRefs, openApiDocument, refsEverywhere, removeExtraScalarKeys, resolveOpenApiDocument, restoreOriginalRefs, syncPathParameters, } from './plugins/bundler/index.js';
|
|
31
33
|
import { extensions } from './schemas/extensions.js';
|
|
32
34
|
import { isAsyncApiDocument, isOpenApiDocument } from './schemas/type-guards.js';
|
|
33
35
|
import { generateSchema } from './schemas/v3.2/openapi/index.js';
|
|
@@ -131,8 +133,10 @@ const purgeInternalDocumentKeys = (input) => {
|
|
|
131
133
|
// Bundler metadata fields added temporarily during document processing
|
|
132
134
|
'x-ext',
|
|
133
135
|
'x-ext-urls',
|
|
136
|
+
'x-scalar-original-refs',
|
|
134
137
|
// Scalar internal/external metadata fields
|
|
135
138
|
'x-scalar-navigation',
|
|
139
|
+
'x-scalar-navigation-chunk',
|
|
136
140
|
'x-scalar-is-dirty',
|
|
137
141
|
'x-original-oas-version',
|
|
138
142
|
'x-scalar-original-document-hash',
|
|
@@ -551,10 +555,10 @@ export const createWorkspaceStore = (workspaceProps) => {
|
|
|
551
555
|
const strictDocument = createMagicProxy({
|
|
552
556
|
...inputDocument,
|
|
553
557
|
...meta,
|
|
554
|
-
'x-original-oas-version':
|
|
558
|
+
'x-original-oas-version': clonedRawInputDocument.openapi ?? clonedRawInputDocument.swagger,
|
|
555
559
|
'x-scalar-original-document-hash': input.documentHash,
|
|
556
560
|
'x-scalar-original-source-url': input.documentSource,
|
|
557
|
-
}, { showInternal: true });
|
|
561
|
+
}, { showInternal: true, documentUri: resolveOpenApiDocument(inputDocument, input.documentSource ?? '/')?.baseUri });
|
|
558
562
|
// If the document navigation is not already present, bundle the entire document to resolve all references.
|
|
559
563
|
// This typically applies when the document is not preprocessed by the server and needs local reference resolution.
|
|
560
564
|
// We need to bundle document first before we validate, so we can also validate the external references
|
|
@@ -563,6 +567,7 @@ export const createWorkspaceStore = (workspaceProps) => {
|
|
|
563
567
|
treeShake: false,
|
|
564
568
|
plugins: [
|
|
565
569
|
...loaders,
|
|
570
|
+
openApiDocument(),
|
|
566
571
|
normalizeRefs(),
|
|
567
572
|
externalValueResolver({ lazy: true }),
|
|
568
573
|
refsEverywhere(),
|
|
@@ -573,7 +578,7 @@ export const createWorkspaceStore = (workspaceProps) => {
|
|
|
573
578
|
origin: input.documentSource, // use the document origin (if provided) as the base URL for resolution
|
|
574
579
|
}));
|
|
575
580
|
// We coerce the values only when the document is not preprocessed by the server-side-store
|
|
576
|
-
const coerced = withMeasurementSync('coerceValue', () => coerce(openapiSchema, deepClone(strictDocument)));
|
|
581
|
+
const coerced = withMeasurementSync('coerceValue', () => coerce(openapiSchema, normalizeBooleanSchemas(deepClone(strictDocument))));
|
|
577
582
|
withMeasurementSync('mergeObjects', () => mergeObjects(strictDocument, coerced));
|
|
578
583
|
}
|
|
579
584
|
const isValid = Value.Check(OpenAPIDocumentSchemaStrict, strictDocument);
|
|
@@ -596,7 +601,9 @@ export const createWorkspaceStore = (workspaceProps) => {
|
|
|
596
601
|
// We create a new proxy here in order to hide internal properties after validation and processing
|
|
597
602
|
// This ensures that the workspace document only exposes the intended OpenAPI properties and extensions
|
|
598
603
|
const documentOverrides = unpackProxyObject(overrides[name]);
|
|
599
|
-
const magicDocument = createMagicProxy(getRaw(strictDocument)
|
|
604
|
+
const magicDocument = createMagicProxy(getRaw(strictDocument), {
|
|
605
|
+
documentUri: resolveOpenApiDocument(getRaw(strictDocument), input.documentSource ?? '/')?.baseUri,
|
|
606
|
+
});
|
|
600
607
|
workspace.documents[name] = needsOverridesProxy(documentOverrides)
|
|
601
608
|
? createOverridesProxy(magicDocument, { overrides: documentOverrides })
|
|
602
609
|
: magicDocument;
|
|
@@ -692,9 +699,11 @@ export const createWorkspaceStore = (workspaceProps) => {
|
|
|
692
699
|
// If the document does not exist, return null
|
|
693
700
|
return null;
|
|
694
701
|
}
|
|
695
|
-
//
|
|
702
|
+
// This is the shared cleanup boundary for editing and saving. Both JSON and YAML
|
|
703
|
+
// exports read the cleaned saved baseline, so serializers need no marker filtering.
|
|
704
|
+
// Reverse all external references and restore original $refs.
|
|
696
705
|
const original = (await bundle(deepClone(rawDocument), {
|
|
697
|
-
plugins: [restoreOriginalRefs(), removeExtraScalarKeys()],
|
|
706
|
+
plugins: [openApiDocument(), restoreOriginalRefs(), removeExtraScalarKeys()],
|
|
698
707
|
treeShake: false,
|
|
699
708
|
urlMap: true,
|
|
700
709
|
}));
|
|
@@ -730,6 +739,86 @@ export const createWorkspaceStore = (workspaceProps) => {
|
|
|
730
739
|
document[extensions.document.navigation] = navigation;
|
|
731
740
|
return true;
|
|
732
741
|
};
|
|
742
|
+
/**
|
|
743
|
+
* Fetches the chunk a compact document keeps its navigation children in.
|
|
744
|
+
*
|
|
745
|
+
* The reference is bundled on an object of its own rather than in the document, so nothing of it
|
|
746
|
+
* is left behind: the chunk lands in that object's `x-ext` and is dropped along with it, and the
|
|
747
|
+
* navigation is never a reference, not even while the request is in flight. Navigation has one
|
|
748
|
+
* owner, so the children go on the document as they are and there is nothing for a shared `x-ext`
|
|
749
|
+
* entry to save.
|
|
750
|
+
*
|
|
751
|
+
* `depth: 0` stops the bundler at the reference itself, which is as far as a navigation chunk
|
|
752
|
+
* goes: its entries address the document through their own `ref` strings and carry no `$ref`.
|
|
753
|
+
*
|
|
754
|
+
* The chunk is handed back unwrapped: what it holds goes on the document, and a magic proxy there
|
|
755
|
+
* would enumerate a virtual `$ref-value` and stop the document being structured-cloned into
|
|
756
|
+
* storage. Unwrapping one level is enough, because the proxy wraps lazily.
|
|
757
|
+
*
|
|
758
|
+
* @returns The navigation the chunk holds, or `undefined` when it could not be loaded — the
|
|
759
|
+
* bundler reports that failure the same way it reports an unreachable component chunk.
|
|
760
|
+
*/
|
|
761
|
+
const fetchNavigationChunk = async (documentName, ref, origin) => {
|
|
762
|
+
const holder = createMagicProxy(chunkReference(ref));
|
|
763
|
+
await bundle(getRaw(holder), {
|
|
764
|
+
plugins: [
|
|
765
|
+
fetchUrls({
|
|
766
|
+
fetch: extraDocumentConfigurations[documentName]?.fetch ?? workspaceProps?.fetch,
|
|
767
|
+
limit: EXTERNAL_FETCH_CONCURRENCY_LIMIT,
|
|
768
|
+
}),
|
|
769
|
+
...(workspaceProps?.fileLoader ? [workspaceProps.fileLoader] : []),
|
|
770
|
+
],
|
|
771
|
+
treeShake: false,
|
|
772
|
+
origin,
|
|
773
|
+
depth: 0,
|
|
774
|
+
urlMap: true,
|
|
775
|
+
});
|
|
776
|
+
return getRaw(getResolvedRef(holder));
|
|
777
|
+
};
|
|
778
|
+
/** Share concurrent requests only within the same document instance, including after a workspace reload. */
|
|
779
|
+
const navigationChildrenLoads = new WeakMap();
|
|
780
|
+
/**
|
|
781
|
+
* Loads a compact document's navigation children and assigns them onto its navigation in place.
|
|
782
|
+
*
|
|
783
|
+
* Only a compact document carries `x-scalar-navigation-chunk`, and only until its children are
|
|
784
|
+
* loaded, so the key answers both "is there anything to load" and "has it already happened". It
|
|
785
|
+
* travels with the document, which is what lets a workspace exported before the children were
|
|
786
|
+
* loaded still load them once it has been imported into another store. A failed load leaves the
|
|
787
|
+
* key in place, so asking again retries.
|
|
788
|
+
*/
|
|
789
|
+
const loadNavigationChildren = async (documentName) => {
|
|
790
|
+
const document = workspace.documents[documentName];
|
|
791
|
+
if (!isOpenApiDocument(document)) {
|
|
792
|
+
return;
|
|
793
|
+
}
|
|
794
|
+
const ref = document[extensions.document.navigationChunk];
|
|
795
|
+
const navigation = document[extensions.document.navigation];
|
|
796
|
+
if (ref === undefined || navigation === undefined) {
|
|
797
|
+
return;
|
|
798
|
+
}
|
|
799
|
+
const pending = navigationChildrenLoads.get(document);
|
|
800
|
+
if (pending) {
|
|
801
|
+
return pending;
|
|
802
|
+
}
|
|
803
|
+
const load = (async () => {
|
|
804
|
+
const chunk = await fetchNavigationChunk(documentName, ref, document['x-scalar-original-source-url']);
|
|
805
|
+
// A replaced or deleted document must not publish changes from a stale request.
|
|
806
|
+
if (chunk === undefined || workspace.documents[documentName] !== document) {
|
|
807
|
+
return;
|
|
808
|
+
}
|
|
809
|
+
// Assigned through the store's document, so the write is observed: a Vue effect reading the
|
|
810
|
+
// children re-runs, and the workspace plugins see the document change.
|
|
811
|
+
navigation.children = chunk.children ?? [];
|
|
812
|
+
delete document[extensions.document.navigationChunk];
|
|
813
|
+
})();
|
|
814
|
+
navigationChildrenLoads.set(document, load);
|
|
815
|
+
try {
|
|
816
|
+
await load;
|
|
817
|
+
}
|
|
818
|
+
finally {
|
|
819
|
+
navigationChildrenLoads.delete(document);
|
|
820
|
+
}
|
|
821
|
+
};
|
|
733
822
|
// Cache to track visited nodes during reference resolution to prevent bundling the same subtree multiple times
|
|
734
823
|
// This is needed because we are doing partial bundle operations
|
|
735
824
|
const visitedNodesCache = new Set();
|
|
@@ -801,8 +890,15 @@ export const createWorkspaceStore = (workspaceProps) => {
|
|
|
801
890
|
initialize: false,
|
|
802
891
|
});
|
|
803
892
|
},
|
|
804
|
-
resolve: (path) => {
|
|
893
|
+
resolve: async (path) => {
|
|
805
894
|
const activeDocument = workspace.activeDocument;
|
|
895
|
+
// The navigation is never a reference: a compact document externalizes its children alone, and
|
|
896
|
+
// loading them is all there is to resolve here. Everything a navigation entry points at, it
|
|
897
|
+
// points at with a `ref` string of its own, so the bundler has nothing left to follow.
|
|
898
|
+
if (path[0] === extensions.document.navigation) {
|
|
899
|
+
await loadNavigationChildren(getActiveDocumentName());
|
|
900
|
+
return getValueAtPath(activeDocument, path);
|
|
901
|
+
}
|
|
806
902
|
const target = getValueAtPath(activeDocument, path);
|
|
807
903
|
if (!isObject(target)) {
|
|
808
904
|
console.error(`Invalid path provided for resolution. Path: [${path.join(', ')}]. Found value of type: ${typeof target}. Expected an object.`);
|
|
@@ -820,6 +916,7 @@ export const createWorkspaceStore = (workspaceProps) => {
|
|
|
820
916
|
origin: activeDocument?.['x-scalar-original-source-url'],
|
|
821
917
|
treeShake: false,
|
|
822
918
|
plugins: [
|
|
919
|
+
openApiDocument(),
|
|
823
920
|
fetchUrls({
|
|
824
921
|
fetch: extraDocumentConfigurations[getActiveDocumentName()]?.fetch ?? workspaceProps?.fetch,
|
|
825
922
|
limit: EXTERNAL_FETCH_CONCURRENCY_LIMIT,
|
|
@@ -929,7 +1026,9 @@ export const createWorkspaceStore = (workspaceProps) => {
|
|
|
929
1026
|
safeAssign(workspace.documents, Object.fromEntries(Object.entries(input.documents).map(([name, doc]) => {
|
|
930
1027
|
// Hydration only rewraps: an exported document has already been upgraded, bundled, coerced
|
|
931
1028
|
// and given its navigation, so nothing here re-processes it.
|
|
932
|
-
const magicDocument = createMagicProxy(doc
|
|
1029
|
+
const magicDocument = createMagicProxy(doc, {
|
|
1030
|
+
documentUri: resolveOpenApiDocument(doc, doc['x-scalar-original-source-url'] ?? '/')?.baseUri,
|
|
1031
|
+
});
|
|
933
1032
|
const documentOverrides = input.overrides[name];
|
|
934
1033
|
return [
|
|
935
1034
|
name,
|