@scalar/api-reference 1.50.0 → 1.52.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 +23 -0
- package/dist/browser/standalone.js +209 -207
- package/dist/browser/webpack-stats.json +1 -1
- package/dist/components/ApiReference.vue.d.ts.map +1 -1
- package/dist/components/ApiReference.vue.js +1 -1
- package/dist/components/ApiReference.vue.js.map +1 -1
- package/dist/components/ApiReference.vue.script.js +47 -12
- package/dist/components/ApiReference.vue.script.js.map +1 -1
- package/dist/components/Content/Auth/Auth.vue.d.ts.map +1 -1
- package/dist/components/Content/Auth/Auth.vue.js.map +1 -1
- package/dist/components/Content/Auth/Auth.vue.script.js +2 -13
- package/dist/components/Content/Auth/Auth.vue.script.js.map +1 -1
- package/dist/components/Content/Content.vue.d.ts +1 -0
- package/dist/components/Content/Content.vue.d.ts.map +1 -1
- package/dist/components/Content/Content.vue.js.map +1 -1
- package/dist/components/Content/Content.vue.script.js +6 -5
- package/dist/components/Content/Content.vue.script.js.map +1 -1
- package/dist/features/Operation/components/RequestBody.vue.d.ts.map +1 -1
- package/dist/features/Operation/components/RequestBody.vue.js +1 -1
- package/dist/features/Operation/components/RequestBody.vue.js.map +1 -1
- package/dist/features/Operation/components/RequestBody.vue.script.js +31 -21
- package/dist/features/Operation/components/RequestBody.vue.script.js.map +1 -1
- package/dist/features/Search/helpers/create-fuse-instance.d.ts.map +1 -1
- package/dist/features/Search/helpers/create-fuse-instance.js +4 -0
- package/dist/features/Search/helpers/create-fuse-instance.js.map +1 -1
- package/dist/features/Search/helpers/create-search-index.js +4 -3
- package/dist/features/Search/helpers/create-search-index.js.map +1 -1
- package/dist/features/Search/types.d.ts +2 -2
- package/dist/features/Search/types.d.ts.map +1 -1
- package/dist/helpers/map-config-plugins.d.ts +3 -2
- package/dist/helpers/map-config-plugins.d.ts.map +1 -1
- package/dist/helpers/map-config-plugins.js +13 -9
- package/dist/helpers/map-config-plugins.js.map +1 -1
- package/dist/helpers/openapi.d.ts +6 -14
- package/dist/helpers/openapi.d.ts.map +1 -1
- package/dist/helpers/openapi.js +24 -29
- package/dist/helpers/openapi.js.map +1 -1
- package/dist/helpers/safe-deep-clone.d.ts +17 -0
- package/dist/helpers/safe-deep-clone.d.ts.map +1 -0
- package/dist/helpers/safe-deep-clone.js +25 -0
- package/dist/helpers/safe-deep-clone.js.map +1 -0
- package/dist/helpers/storage.d.ts +5 -5
- package/dist/standalone/lib/html-api.d.ts.map +1 -1
- package/dist/standalone/lib/html-api.js +12 -12
- package/dist/standalone/lib/html-api.js.map +1 -1
- package/dist/style.css +64 -25
- package/package.json +11 -16
- package/dist/components/Content/Auth/helpers/get-default-security.d.ts +0 -18
- package/dist/components/Content/Auth/helpers/get-default-security.d.ts.map +0 -1
- package/dist/components/Content/Auth/helpers/get-default-security.js +0 -64
- package/dist/components/Content/Auth/helpers/get-default-security.js.map +0 -1
- package/dist/ssr.d.ts +0 -22
- package/dist/ssr.d.ts.map +0 -1
- package/dist/ssr.js +0 -7
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { isTypeObject } from "../../../components/Content/Schema/helpers/is-type-object.js";
|
|
2
2
|
import { reduceNamesToObject, sortPropertyNames } from "../../../components/Content/Schema/helpers/sort-property-names.js";
|
|
3
|
+
import { getModelNameFromSchema } from "../../../components/Content/Schema/helpers/schema-name.js";
|
|
3
4
|
import Schema_default from "../../../components/Content/Schema/Schema.vue.js";
|
|
4
5
|
import ContentTypeSelect_default from "./ContentTypeSelect.vue.js";
|
|
5
|
-
import { computed, createCommentVNode, createElementBlock, createElementVNode, createVNode, defineComponent, openBlock, ref, renderSlot, unref } from "vue";
|
|
6
|
+
import { computed, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, openBlock, ref, renderSlot, toDisplayString, unref } from "vue";
|
|
6
7
|
import { ScalarMarkdown } from "@scalar/components";
|
|
7
8
|
import { getResolvedRef } from "@scalar/workspace-store/helpers/get-resolved-ref";
|
|
8
9
|
//#region src/features/Operation/components/RequestBody.vue?vue&type=script&setup=true&lang.ts
|
|
@@ -14,20 +15,25 @@ var _hoisted_1 = {
|
|
|
14
15
|
};
|
|
15
16
|
var _hoisted_2 = { class: "request-body-header" };
|
|
16
17
|
var _hoisted_3 = { class: "request-body-title" };
|
|
17
|
-
var _hoisted_4 = {
|
|
18
|
-
var _hoisted_5 = {
|
|
18
|
+
var _hoisted_4 = {
|
|
19
19
|
key: 0,
|
|
20
|
-
class: "
|
|
20
|
+
class: "text-c-2 text-xs leading-none font-normal",
|
|
21
|
+
"data-testid": "request-body-schema-name"
|
|
21
22
|
};
|
|
23
|
+
var _hoisted_5 = { class: "flex items-center gap-2" };
|
|
22
24
|
var _hoisted_6 = {
|
|
23
25
|
key: 0,
|
|
24
|
-
class: "request-body-
|
|
26
|
+
class: "request-body-required"
|
|
25
27
|
};
|
|
26
28
|
var _hoisted_7 = {
|
|
27
29
|
key: 0,
|
|
28
|
-
class: "request-body-
|
|
30
|
+
class: "request-body-description"
|
|
29
31
|
};
|
|
30
32
|
var _hoisted_8 = {
|
|
33
|
+
key: 0,
|
|
34
|
+
class: "request-body-schema"
|
|
35
|
+
};
|
|
36
|
+
var _hoisted_9 = {
|
|
31
37
|
key: 1,
|
|
32
38
|
class: "request-body-schema"
|
|
33
39
|
};
|
|
@@ -49,7 +55,11 @@ var RequestBody_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ de
|
|
|
49
55
|
if (__props.requestBody?.content) {
|
|
50
56
|
if (availableContentTypes.value[0]) selectedContentType.value = availableContentTypes.value[0];
|
|
51
57
|
}
|
|
52
|
-
|
|
58
|
+
/** Raw schema (possibly with $ref) for the selected content type */
|
|
59
|
+
const rawSchema = computed(() => __props.requestBody?.content?.[selectedContentType.value]?.schema);
|
|
60
|
+
const schema = computed(() => getResolvedRef(rawSchema.value));
|
|
61
|
+
/** When the schema is a $ref, preserve its name so the UI can show the ref name instead of just the type. */
|
|
62
|
+
const schemaModelName = computed(() => (rawSchema.value && getModelNameFromSchema(rawSchema.value)) ?? null);
|
|
53
63
|
/**
|
|
54
64
|
* Splits schema properties into visible and collapsed sections when there are more than 12 properties.
|
|
55
65
|
* Returns null for schemas with fewer properties or non-object schemas.
|
|
@@ -85,16 +95,17 @@ var RequestBody_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ de
|
|
|
85
95
|
const shouldRenderRequestBody = computed(() => Object.keys(__props.requestBody?.content ?? {}).length > 0 || __props.requestBody?.description || __props.requestBody?.required);
|
|
86
96
|
return (_ctx, _cache) => {
|
|
87
97
|
return __props.requestBody && shouldRenderRequestBody.value ? (openBlock(), createElementBlock("div", _hoisted_1, [createElementVNode("div", _hoisted_2, [
|
|
88
|
-
createElementVNode("div", _hoisted_3, [renderSlot(_ctx.$slots, "title", {}, void 0, true)]),
|
|
89
|
-
createElementVNode("div",
|
|
98
|
+
createElementVNode("div", _hoisted_3, [renderSlot(_ctx.$slots, "title", {}, void 0, true), schemaModelName.value ? (openBlock(), createElementBlock("span", _hoisted_4, [_cache[1] || (_cache[1] = createElementVNode("span", { class: "text-c-3 mx-1.5" }, "·", -1)), createTextVNode(toDisplayString(schemaModelName.value), 1)])) : createCommentVNode("", true)]),
|
|
99
|
+
createElementVNode("div", _hoisted_5, [__props.requestBody.required ? (openBlock(), createElementBlock("div", _hoisted_6, " required ")) : createCommentVNode("", true), createVNode(ContentTypeSelect_default, {
|
|
90
100
|
modelValue: selectedContentType.value,
|
|
91
101
|
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => selectedContentType.value = $event),
|
|
92
102
|
content: __props.requestBody.content
|
|
93
103
|
}, null, 8, ["modelValue", "content"])]),
|
|
94
|
-
__props.requestBody.description ? (openBlock(), createElementBlock("div",
|
|
95
|
-
]), partitionedSchema.value ? (openBlock(), createElementBlock("div",
|
|
104
|
+
__props.requestBody.description ? (openBlock(), createElementBlock("div", _hoisted_7, [createVNode(unref(ScalarMarkdown), { value: __props.requestBody.description }, null, 8, ["value"])])) : createCommentVNode("", true)
|
|
105
|
+
]), partitionedSchema.value ? (openBlock(), createElementBlock("div", _hoisted_8, [createVNode(unref(Schema_default), {
|
|
96
106
|
breadcrumb: __props.breadcrumb,
|
|
97
107
|
compact: "",
|
|
108
|
+
compositionPath: ["requestBody"],
|
|
98
109
|
eventBus: __props.eventBus,
|
|
99
110
|
name: "Request Body",
|
|
100
111
|
noncollapsible: "",
|
|
@@ -103,9 +114,8 @@ var RequestBody_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ de
|
|
|
103
114
|
orderRequiredPropertiesFirst: __props.options.orderRequiredPropertiesFirst,
|
|
104
115
|
orderSchemaPropertiesBy: __props.options.orderSchemaPropertiesBy
|
|
105
116
|
},
|
|
106
|
-
|
|
107
|
-
schemaContext: "requestBody"
|
|
108
|
-
schema: partitionedSchema.value.visibleProperties
|
|
117
|
+
schema: partitionedSchema.value.visibleProperties,
|
|
118
|
+
schemaContext: "requestBody"
|
|
109
119
|
}, null, 8, [
|
|
110
120
|
"breadcrumb",
|
|
111
121
|
"eventBus",
|
|
@@ -115,6 +125,7 @@ var RequestBody_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ de
|
|
|
115
125
|
additionalProperties: "",
|
|
116
126
|
breadcrumb: __props.breadcrumb,
|
|
117
127
|
compact: "",
|
|
128
|
+
compositionPath: ["requestBody"],
|
|
118
129
|
eventBus: __props.eventBus,
|
|
119
130
|
name: "Request Body",
|
|
120
131
|
options: {
|
|
@@ -122,17 +133,17 @@ var RequestBody_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ de
|
|
|
122
133
|
orderRequiredPropertiesFirst: __props.options.orderRequiredPropertiesFirst,
|
|
123
134
|
orderSchemaPropertiesBy: __props.options.orderSchemaPropertiesBy
|
|
124
135
|
},
|
|
125
|
-
|
|
126
|
-
schemaContext: "requestBody"
|
|
127
|
-
schema: partitionedSchema.value.collapsedProperties
|
|
136
|
+
schema: partitionedSchema.value.collapsedProperties,
|
|
137
|
+
schemaContext: "requestBody"
|
|
128
138
|
}, null, 8, [
|
|
129
139
|
"breadcrumb",
|
|
130
140
|
"eventBus",
|
|
131
141
|
"options",
|
|
132
142
|
"schema"
|
|
133
|
-
])])) : schema.value ? (openBlock(), createElementBlock("div",
|
|
143
|
+
])])) : schema.value ? (openBlock(), createElementBlock("div", _hoisted_9, [createVNode(unref(Schema_default), {
|
|
134
144
|
breadcrumb: __props.breadcrumb,
|
|
135
145
|
compact: "",
|
|
146
|
+
compositionPath: ["requestBody"],
|
|
136
147
|
eventBus: __props.eventBus,
|
|
137
148
|
hideReadOnly: true,
|
|
138
149
|
name: "Request Body",
|
|
@@ -142,9 +153,8 @@ var RequestBody_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ de
|
|
|
142
153
|
orderRequiredPropertiesFirst: __props.options.orderRequiredPropertiesFirst,
|
|
143
154
|
orderSchemaPropertiesBy: __props.options.orderSchemaPropertiesBy
|
|
144
155
|
},
|
|
145
|
-
|
|
146
|
-
schemaContext: "requestBody"
|
|
147
|
-
schema: schema.value
|
|
156
|
+
schema: schema.value,
|
|
157
|
+
schemaContext: "requestBody"
|
|
148
158
|
}, null, 8, [
|
|
149
159
|
"breadcrumb",
|
|
150
160
|
"eventBus",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RequestBody.vue.script.js","names":[],"sources":["../../../../src/features/Operation/components/RequestBody.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ScalarMarkdown } from '@scalar/components'\nimport type { WorkspaceEventBus } from '@scalar/workspace-store/events'\nimport { getResolvedRef } from '@scalar/workspace-store/helpers/get-resolved-ref'\nimport type { RequestBodyObject } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport { computed, ref } from 'vue'\n\nimport { Schema } from '@/components/Content/Schema'\nimport { isTypeObject } from '@/components/Content/Schema/helpers/is-type-object'\nimport {\n reduceNamesToObject,\n sortPropertyNames,\n} from '@/components/Content/Schema/helpers/sort-property-names'\n\nimport ContentTypeSelect from './ContentTypeSelect.vue'\n\nconst { requestBody, options } = defineProps<{\n breadcrumb?: string[]\n requestBody?: RequestBodyObject\n eventBus: WorkspaceEventBus | null\n options: {\n orderRequiredPropertiesFirst: boolean | undefined\n orderSchemaPropertiesBy: 'alpha' | 'preserve' | undefined\n }\n}>()\n\n/**\n * The maximum number of properties to show in the request body schema.\n */\nconst MAX_VISIBLE_PROPERTIES = 12\n\nconst availableContentTypes = computed(() =>\n Object.keys(requestBody?.content ?? {}),\n)\n\nconst selectedContentType = ref<string>('application/json')\n\nif (requestBody?.content) {\n if (availableContentTypes.value[0]) {\n selectedContentType.value = availableContentTypes.value[0]\n }\n}\n\nconst schema = computed(() =>\n getResolvedRef(requestBody?.content?.[selectedContentType.value]?.schema),\n)\n\n/**\n * Splits schema properties into visible and collapsed sections when there are more than 12 properties.\n * Returns null for schemas with fewer properties or non-object schemas.\n */\nconst partitionedSchema = computed(() => {\n // Early return if not an object schema\n if (!schema.value || !isTypeObject(schema.value)) {\n return null\n }\n\n // Lets sort the names first\n const sortedNames = sortPropertyNames(\n schema.value,\n schema.value.discriminator,\n {\n hideReadOnly: true,\n orderSchemaPropertiesBy: options.orderSchemaPropertiesBy,\n orderRequiredPropertiesFirst: options.orderRequiredPropertiesFirst,\n },\n )\n\n if (sortedNames.length <= MAX_VISIBLE_PROPERTIES) {\n return null\n }\n\n // Destructure everything except properties\n const { properties, ...schemaMetadata } = schema.value\n if (!properties) {\n return null\n }\n\n return {\n visibleProperties: {\n ...schemaMetadata,\n properties: reduceNamesToObject(\n sortedNames.slice(0, MAX_VISIBLE_PROPERTIES),\n properties,\n ),\n },\n collapsedProperties: {\n ...schemaMetadata,\n properties: reduceNamesToObject(\n sortedNames.slice(MAX_VISIBLE_PROPERTIES),\n properties,\n ),\n },\n }\n})\n\n/**\n * We don't want to render the request body if its completely empty\n * @example\n * {\n * \"content\": {},\n * }\n */\nconst shouldRenderRequestBody = computed(\n () =>\n Object.keys(requestBody?.content ?? {}).length > 0 ||\n requestBody?.description ||\n requestBody?.required,\n)\n</script>\n<template>\n <div\n v-if=\"requestBody && shouldRenderRequestBody\"\n aria-label=\"Request Body\"\n class=\"request-body\"\n role=\"group\">\n <div class=\"request-body-header\">\n <div class=\"request-body-title\">\n <slot name=\"title\" />\n </div>\n <div class=\"flex items-center gap-2\">\n <div\n v-if=\"requestBody.required\"\n class=\"request-body-required\">\n required\n </div>\n <ContentTypeSelect\n v-model=\"selectedContentType\"\n :content=\"requestBody.content\" />\n </div>\n <div\n v-if=\"requestBody.description\"\n class=\"request-body-description\">\n <ScalarMarkdown :value=\"requestBody.description\" />\n </div>\n </div>\n\n <!-- For over 12 properties we want to show 12 and collapse the rest -->\n <div\n v-if=\"partitionedSchema\"\n class=\"request-body-schema\">\n <Schema\n :breadcrumb\n compact\n :eventBus=\"eventBus\"\n name=\"Request Body\"\n noncollapsible\n :options=\"{\n hideReadOnly: true,\n orderRequiredPropertiesFirst: options.orderRequiredPropertiesFirst,\n orderSchemaPropertiesBy: options.orderSchemaPropertiesBy,\n }\"\n :compositionPath=\"['requestBody']\"\n schemaContext=\"requestBody\"\n :schema=\"partitionedSchema.visibleProperties\" />\n\n <Schema\n additionalProperties\n :breadcrumb\n compact\n :eventBus=\"eventBus\"\n name=\"Request Body\"\n :options=\"{\n hideReadOnly: true,\n orderRequiredPropertiesFirst: options.orderRequiredPropertiesFirst,\n orderSchemaPropertiesBy: options.orderSchemaPropertiesBy,\n }\"\n :compositionPath=\"['requestBody']\"\n schemaContext=\"requestBody\"\n :schema=\"partitionedSchema.collapsedProperties\" />\n </div>\n\n <!-- Show em all 12 and under -->\n <div\n v-else-if=\"schema\"\n class=\"request-body-schema\">\n <Schema\n :breadcrumb\n compact\n :eventBus=\"eventBus\"\n :hideReadOnly=\"true\"\n name=\"Request Body\"\n noncollapsible\n :options=\"{\n hideReadOnly: true,\n orderRequiredPropertiesFirst: options.orderRequiredPropertiesFirst,\n orderSchemaPropertiesBy: options.orderSchemaPropertiesBy,\n }\"\n :compositionPath=\"['requestBody']\"\n schemaContext=\"requestBody\"\n :schema=\"schema\" />\n </div>\n </div>\n</template>\n\n<style scoped>\n.request-body {\n margin-top: 24px;\n}\n.request-body-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding-bottom: 12px;\n border-bottom: var(--scalar-border-width) solid var(--scalar-border-color);\n flex-flow: wrap;\n}\n.request-body-title {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: var(--scalar-font-size-2);\n font-weight: var(--scalar-semibold);\n color: var(--scalar-color-1);\n}\n.request-body-required {\n font-size: var(--scalar-micro);\n color: var(--scalar-color-orange);\n font-weight: normal;\n border-radius: 16px;\n border: var(--scalar-border-width) solid var(--scalar-border-color);\n padding: 2px 8px;\n height: 20px;\n}\n.request-body-description {\n margin-top: 6px;\n font-size: var(--scalar-small);\n width: 100%;\n}\n\n.request-body-header\n + .request-body-schema:has(> .schema-card > .schema-card-description),\n.request-body-header\n + .request-body-schema:has(\n > .schema-card > .schema-properties > * > .property--level-0\n ) {\n /** Add a bit of space between the heading border and the schema description or properties */\n padding-top: 8px;\n}\n.request-body-description :deep(.markdown) * {\n color: var(--scalar-color-2) !important;\n}\n</style>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"RequestBody.vue.script.js","names":[],"sources":["../../../../src/features/Operation/components/RequestBody.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ScalarMarkdown } from '@scalar/components'\nimport type { WorkspaceEventBus } from '@scalar/workspace-store/events'\nimport { getResolvedRef } from '@scalar/workspace-store/helpers/get-resolved-ref'\nimport type { RequestBodyObject } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport { computed, ref } from 'vue'\n\nimport { Schema } from '@/components/Content/Schema'\nimport { isTypeObject } from '@/components/Content/Schema/helpers/is-type-object'\nimport { getModelNameFromSchema } from '@/components/Content/Schema/helpers/schema-name'\nimport {\n reduceNamesToObject,\n sortPropertyNames,\n} from '@/components/Content/Schema/helpers/sort-property-names'\n\nimport ContentTypeSelect from './ContentTypeSelect.vue'\n\nconst { requestBody, options } = defineProps<{\n breadcrumb?: string[]\n requestBody?: RequestBodyObject\n eventBus: WorkspaceEventBus | null\n options: {\n orderRequiredPropertiesFirst: boolean | undefined\n orderSchemaPropertiesBy: 'alpha' | 'preserve' | undefined\n }\n}>()\n\n/**\n * The maximum number of properties to show in the request body schema.\n */\nconst MAX_VISIBLE_PROPERTIES = 12\n\nconst availableContentTypes = computed(() =>\n Object.keys(requestBody?.content ?? {}),\n)\n\nconst selectedContentType = ref<string>('application/json')\n\nif (requestBody?.content) {\n if (availableContentTypes.value[0]) {\n selectedContentType.value = availableContentTypes.value[0]\n }\n}\n\n/** Raw schema (possibly with $ref) for the selected content type */\nconst rawSchema = computed(\n () => requestBody?.content?.[selectedContentType.value]?.schema,\n)\n\nconst schema = computed(() => getResolvedRef(rawSchema.value))\n\n/** When the schema is a $ref, preserve its name so the UI can show the ref name instead of just the type. */\nconst schemaModelName = computed(\n () => (rawSchema.value && getModelNameFromSchema(rawSchema.value)) ?? null,\n)\n\n/**\n * Splits schema properties into visible and collapsed sections when there are more than 12 properties.\n * Returns null for schemas with fewer properties or non-object schemas.\n */\nconst partitionedSchema = computed(() => {\n // Early return if not an object schema\n if (!schema.value || !isTypeObject(schema.value)) {\n return null\n }\n\n // Lets sort the names first\n const sortedNames = sortPropertyNames(\n schema.value,\n schema.value.discriminator,\n {\n hideReadOnly: true,\n orderSchemaPropertiesBy: options.orderSchemaPropertiesBy,\n orderRequiredPropertiesFirst: options.orderRequiredPropertiesFirst,\n },\n )\n\n if (sortedNames.length <= MAX_VISIBLE_PROPERTIES) {\n return null\n }\n\n // Destructure everything except properties\n const { properties, ...schemaMetadata } = schema.value\n if (!properties) {\n return null\n }\n\n return {\n visibleProperties: {\n ...schemaMetadata,\n properties: reduceNamesToObject(\n sortedNames.slice(0, MAX_VISIBLE_PROPERTIES),\n properties,\n ),\n },\n collapsedProperties: {\n ...schemaMetadata,\n properties: reduceNamesToObject(\n sortedNames.slice(MAX_VISIBLE_PROPERTIES),\n properties,\n ),\n },\n }\n})\n\n/**\n * We don't want to render the request body if its completely empty\n * @example\n * {\n * \"content\": {},\n * }\n */\nconst shouldRenderRequestBody = computed(\n () =>\n Object.keys(requestBody?.content ?? {}).length > 0 ||\n requestBody?.description ||\n requestBody?.required,\n)\n</script>\n<template>\n <div\n v-if=\"requestBody && shouldRenderRequestBody\"\n aria-label=\"Request Body\"\n class=\"request-body\"\n role=\"group\">\n <div class=\"request-body-header\">\n <div class=\"request-body-title\">\n <slot name=\"title\" />\n <span\n v-if=\"schemaModelName\"\n class=\"text-c-2 text-xs leading-none font-normal\"\n data-testid=\"request-body-schema-name\">\n <span class=\"text-c-3 mx-1.5\">·</span>{{ schemaModelName }}\n </span>\n </div>\n <div class=\"flex items-center gap-2\">\n <div\n v-if=\"requestBody.required\"\n class=\"request-body-required\">\n required\n </div>\n <ContentTypeSelect\n v-model=\"selectedContentType\"\n :content=\"requestBody.content\" />\n </div>\n <div\n v-if=\"requestBody.description\"\n class=\"request-body-description\">\n <ScalarMarkdown :value=\"requestBody.description\" />\n </div>\n </div>\n\n <!-- For over 12 properties we want to show 12 and collapse the rest -->\n <div\n v-if=\"partitionedSchema\"\n class=\"request-body-schema\">\n <Schema\n :breadcrumb\n compact\n :compositionPath=\"['requestBody']\"\n :eventBus=\"eventBus\"\n name=\"Request Body\"\n noncollapsible\n :options=\"{\n hideReadOnly: true,\n orderRequiredPropertiesFirst: options.orderRequiredPropertiesFirst,\n orderSchemaPropertiesBy: options.orderSchemaPropertiesBy,\n }\"\n :schema=\"partitionedSchema.visibleProperties\"\n schemaContext=\"requestBody\" />\n\n <Schema\n additionalProperties\n :breadcrumb\n compact\n :compositionPath=\"['requestBody']\"\n :eventBus=\"eventBus\"\n name=\"Request Body\"\n :options=\"{\n hideReadOnly: true,\n orderRequiredPropertiesFirst: options.orderRequiredPropertiesFirst,\n orderSchemaPropertiesBy: options.orderSchemaPropertiesBy,\n }\"\n :schema=\"partitionedSchema.collapsedProperties\"\n schemaContext=\"requestBody\" />\n </div>\n\n <!-- Show em all 12 and under -->\n <div\n v-else-if=\"schema\"\n class=\"request-body-schema\">\n <Schema\n :breadcrumb\n compact\n :compositionPath=\"['requestBody']\"\n :eventBus=\"eventBus\"\n :hideReadOnly=\"true\"\n name=\"Request Body\"\n noncollapsible\n :options=\"{\n hideReadOnly: true,\n orderRequiredPropertiesFirst: options.orderRequiredPropertiesFirst,\n orderSchemaPropertiesBy: options.orderSchemaPropertiesBy,\n }\"\n :schema=\"schema\"\n schemaContext=\"requestBody\" />\n </div>\n </div>\n</template>\n\n<style scoped>\n.request-body {\n margin-top: 24px;\n}\n.request-body-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding-bottom: 12px;\n border-bottom: var(--scalar-border-width) solid var(--scalar-border-color);\n flex-flow: wrap;\n}\n.request-body-title {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: var(--scalar-font-size-2);\n font-weight: var(--scalar-semibold);\n color: var(--scalar-color-1);\n}\n.request-body-required {\n font-size: var(--scalar-micro);\n color: var(--scalar-color-orange);\n font-weight: normal;\n border-radius: 16px;\n border: var(--scalar-border-width) solid var(--scalar-border-color);\n padding: 2px 8px;\n height: 20px;\n}\n.request-body-description {\n margin-top: 6px;\n font-size: var(--scalar-small);\n width: 100%;\n}\n\n.request-body-header\n + .request-body-schema:has(> .schema-card > .schema-card-description),\n.request-body-header\n + .request-body-schema:has(\n > .schema-card > .schema-properties > * > .property--level-0\n ) {\n /** Add a bit of space between the heading border and the schema description or properties */\n padding-top: 8px;\n}\n.request-body-description :deep(.markdown) * {\n color: var(--scalar-color-2) !important;\n}\n</style>\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-fuse-instance.d.ts","sourceRoot":"","sources":["../../../../src/features/Search/helpers/create-fuse-instance.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,SAAS,CAAA;AAE1B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAEvD;;;;GAIG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAAC,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"create-fuse-instance.d.ts","sourceRoot":"","sources":["../../../../src/features/Search/helpers/create-fuse-instance.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,SAAS,CAAA;AAE1B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAEvD;;;;GAIG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAAC,QAAQ,CAAC,CAiDnD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-fuse-instance.js","names":[],"sources":["../../../../src/features/Search/helpers/create-fuse-instance.ts"],"sourcesContent":["import Fuse from 'fuse.js'\n\nimport type { FuseData } from '@/features/Search/types'\n\n/**\n * Create a Fuse instance for searching the API reference.\n *\n * Doesn't have any data yet, so it's empty.\n */\nexport function createFuseInstance(): Fuse<FuseData> {\n return new Fuse([], {\n // Define searchable fields with weights to prioritize more important matches\n keys: [\n // Highest weight - titles are most descriptive\n { name: 'title', weight: 0.7 },\n // Medium weight - helpful but often verbose\n { name: 'description', weight: 0.3 },\n // Lowest weight - can be very long and noisy\n { name: 'body', weight: 0.2 },\n // Low-medium weight - response examples can help full-text matching\n { name: 'responseExamples', weight: 0.25 },\n // High weight - unique identifiers for operations\n { name: 'operationId', weight: 0.6 },\n // Good weight - endpoint paths are searchable\n { name: 'path', weight: 0.5 },\n // Medium-high weight - helps with categorization\n { name: 'tag', weight: 0.4 },\n // Medium weight - useful for filtering by method\n { name: 'method', weight: 0.3 },\n ],\n\n // Threshold controls how strict the matching is (0.0 = perfect match, 1.0 = very loose)\n // 0.3 allows for some typos and partial matches while maintaining relevance\n threshold: 0.3,\n\n // Maximum distance between characters that can be matched\n // Higher values allow matches even when characters are far apart in long text\n distance: 100,\n\n // Include the match score in results for debugging and potential UI enhancements\n includeScore: true,\n\n // Include detailed match information showing which parts of the text matched\n includeMatches: true,\n\n // Don't require matches to be at the beginning of strings\n // Makes search more flexible and user-friendly\n ignoreLocation: true,\n\n // Enable advanced search syntax like 'exact' for exact matches or !exclude for exclusions\n useExtendedSearch: true,\n\n // Find all possible matches in each item, not just the first one\n // Ensures comprehensive search results\n findAllMatches: true,\n })\n}\n"],"mappings":";;;;;;;AASA,SAAgB,qBAAqC;AACnD,QAAO,IAAI,KAAK,EAAE,EAAE;EAElB,MAAM;GAEJ;IAAE,MAAM;IAAS,QAAQ;IAAK;GAE9B;IAAE,MAAM;IAAe,QAAQ;IAAK;GAEpC;IAAE,MAAM;IAAQ,QAAQ;IAAK;GAE7B;IAAE,MAAM;IAAoB,QAAQ;IAAM;GAE1C;IAAE,MAAM;IAAe,QAAQ;IAAK;GAEpC;IAAE,MAAM;IAAQ,QAAQ;IAAK;GAE7B;IAAE,MAAM;IAAO,QAAQ;IAAK;GAE5B;IAAE,MAAM;IAAU,QAAQ;IAAK;GAChC;EAID,WAAW;EAIX,UAAU;EAGV,cAAc;EAGd,gBAAgB;EAIhB,gBAAgB;EAGhB,mBAAmB;EAInB,gBAAgB;EACjB,CAAC"}
|
|
1
|
+
{"version":3,"file":"create-fuse-instance.js","names":[],"sources":["../../../../src/features/Search/helpers/create-fuse-instance.ts"],"sourcesContent":["import Fuse from 'fuse.js'\n\nimport type { FuseData } from '@/features/Search/types'\n\n/**\n * Create a Fuse instance for searching the API reference.\n *\n * Doesn't have any data yet, so it's empty.\n */\nexport function createFuseInstance(): Fuse<FuseData> {\n return new Fuse([], {\n // Define searchable fields with weights to prioritize more important matches\n keys: [\n // Highest weight - titles are most descriptive\n { name: 'title', weight: 0.7 },\n // Medium weight - helpful but often verbose\n { name: 'description', weight: 0.3 },\n // Lowest weight - parameters are searchable but they can be very long and noisy\n { name: 'parameters', weight: 0.2 },\n // Lowest weight - can be very long and noisy\n { name: 'body', weight: 0.2 },\n // Low-medium weight - response examples can help full-text matching\n { name: 'responseExamples', weight: 0.25 },\n // High weight - unique identifiers for operations\n { name: 'operationId', weight: 0.6 },\n // Good weight - endpoint paths are searchable\n { name: 'path', weight: 0.5 },\n // Medium-high weight - helps with categorization\n { name: 'tag', weight: 0.4 },\n // Medium weight - useful for filtering by method\n { name: 'method', weight: 0.3 },\n ],\n\n // Threshold controls how strict the matching is (0.0 = perfect match, 1.0 = very loose)\n // 0.3 allows for some typos and partial matches while maintaining relevance\n threshold: 0.3,\n\n // Maximum distance between characters that can be matched\n // Higher values allow matches even when characters are far apart in long text\n distance: 100,\n\n // Include the match score in results for debugging and potential UI enhancements\n includeScore: true,\n\n // Include detailed match information showing which parts of the text matched\n includeMatches: true,\n\n // Don't require matches to be at the beginning of strings\n // Makes search more flexible and user-friendly\n ignoreLocation: true,\n\n // Enable advanced search syntax like 'exact' for exact matches or !exclude for exclusions\n useExtendedSearch: true,\n\n // Find all possible matches in each item, not just the first one\n // Ensures comprehensive search results\n findAllMatches: true,\n })\n}\n"],"mappings":";;;;;;;AASA,SAAgB,qBAAqC;AACnD,QAAO,IAAI,KAAK,EAAE,EAAE;EAElB,MAAM;GAEJ;IAAE,MAAM;IAAS,QAAQ;IAAK;GAE9B;IAAE,MAAM;IAAe,QAAQ;IAAK;GAEpC;IAAE,MAAM;IAAc,QAAQ;IAAK;GAEnC;IAAE,MAAM;IAAQ,QAAQ;IAAK;GAE7B;IAAE,MAAM;IAAoB,QAAQ;IAAM;GAE1C;IAAE,MAAM;IAAe,QAAQ;IAAK;GAEpC;IAAE,MAAM;IAAQ,QAAQ;IAAK;GAE7B;IAAE,MAAM;IAAO,QAAQ;IAAK;GAE5B;IAAE,MAAM;IAAU,QAAQ;IAAK;GAChC;EAID,WAAW;EAIX,UAAU;EAGV,cAAc;EAGd,gBAAgB;EAIhB,gBAAgB;EAGhB,mBAAmB;EAInB,gBAAgB;EACjB,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { extractParameters, extractRequestBody } from "../../../helpers/openapi.js";
|
|
2
2
|
import { combineParams } from "@scalar/workspace-store/request-example";
|
|
3
3
|
import { getResolvedRef } from "@scalar/workspace-store/helpers/get-resolved-ref";
|
|
4
4
|
//#region src/features/Search/helpers/create-search-index.ts
|
|
@@ -59,8 +59,8 @@ function addEntryToIndex(entry, index, document) {
|
|
|
59
59
|
...operation,
|
|
60
60
|
parameters: combineParams(pathItem?.parameters, operation.parameters)
|
|
61
61
|
};
|
|
62
|
-
const
|
|
63
|
-
const body =
|
|
62
|
+
const parameters = extractParameters(operationWithPathParams.parameters ?? []);
|
|
63
|
+
const body = extractRequestBody(operationWithPathParams);
|
|
64
64
|
const responseExamples = extractResponseExamples(operationWithPathParams.responses);
|
|
65
65
|
index.push({
|
|
66
66
|
type: "operation",
|
|
@@ -70,6 +70,7 @@ function addEntryToIndex(entry, index, document) {
|
|
|
70
70
|
method: entry.method,
|
|
71
71
|
path: entry.path,
|
|
72
72
|
body: body || "",
|
|
73
|
+
parameters: parameters ?? "",
|
|
73
74
|
responseExamples,
|
|
74
75
|
operationId: operationWithPathParams.operationId,
|
|
75
76
|
entry
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-search-index.js","names":[],"sources":["../../../../src/features/Search/helpers/create-search-index.ts"],"sourcesContent":["import { getResolvedRef } from '@scalar/workspace-store/helpers/get-resolved-ref'\nimport { combineParams } from '@scalar/workspace-store/request-example'\nimport type { TraversedEntry } from '@scalar/workspace-store/schemas/navigation'\nimport type {\n MediaTypeObject,\n OpenApiDocument,\n OperationObject,\n ResponsesObject,\n} from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\n\nimport type { FuseData } from '@/features/Search/types'\nimport {
|
|
1
|
+
{"version":3,"file":"create-search-index.js","names":[],"sources":["../../../../src/features/Search/helpers/create-search-index.ts"],"sourcesContent":["import { getResolvedRef } from '@scalar/workspace-store/helpers/get-resolved-ref'\nimport { combineParams } from '@scalar/workspace-store/request-example'\nimport type { TraversedEntry } from '@scalar/workspace-store/schemas/navigation'\nimport type {\n MediaTypeObject,\n OpenApiDocument,\n OperationObject,\n ResponsesObject,\n} from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\n\nimport type { FuseData } from '@/features/Search/types'\nimport { extractParameters, extractRequestBody } from '@/helpers/openapi'\n\nfunction responseExampleValueToString(value: unknown): string {\n if (typeof value === 'string') {\n return value\n }\n\n try {\n return JSON.stringify(value)\n } catch (_error) {\n return ''\n }\n}\n\nfunction mediaTypeExamplesToStrings(mediaType: MediaTypeObject): string[] {\n const examplesFromNamedMap = Object.values(mediaType.examples ?? {})\n .flatMap((example) => {\n const resolvedExample = getResolvedRef(example)\n\n if (!resolvedExample || !('value' in resolvedExample)) {\n return []\n }\n\n return responseExampleValueToString(resolvedExample.value)\n })\n .filter((value) => value.length > 0)\n\n const mediaTypeExample =\n 'example' in mediaType && mediaType.example !== undefined ? responseExampleValueToString(mediaType.example) : ''\n\n return mediaTypeExample ? [mediaTypeExample, ...examplesFromNamedMap] : examplesFromNamedMap\n}\n\nfunction extractResponseExamples(responses: ResponsesObject | undefined): string[] {\n if (!responses) {\n return []\n }\n\n return Object.values(responses)\n .flatMap((response) => {\n const resolvedResponse = getResolvedRef(response)\n if (!resolvedResponse?.content) {\n return []\n }\n\n return Object.values(resolvedResponse.content).flatMap((mediaType) => {\n const resolvedMediaType = getResolvedRef(mediaType)\n if (!resolvedMediaType) {\n return []\n }\n\n return mediaTypeExamplesToStrings(resolvedMediaType)\n })\n })\n .filter((value) => value.length > 0)\n}\n\n/**\n * Create a search index from a list of entries.\n */\nexport function createSearchIndex(document: OpenApiDocument | undefined): FuseData[] {\n const index: FuseData[] = []\n\n /**\n * Recursively processes entries and their children to build the search index.\n */\n function processEntries(entriesToProcess: TraversedEntry[]): void {\n entriesToProcess.forEach((entry) => {\n addEntryToIndex(entry, index, document)\n\n // Recursively process children if they exist\n if ('children' in entry && entry.children) {\n processEntries(entry.children)\n }\n })\n }\n\n processEntries(document?.['x-scalar-navigation']?.children ?? [])\n\n return index\n}\n\n/**\n * Adds a single entry to the search index, handling all entry types recursively.\n */\nfunction addEntryToIndex(entry: TraversedEntry, index: FuseData[], document?: OpenApiDocument): void {\n // Operation\n if (entry.type === 'operation') {\n const pathItem = getResolvedRef(document?.paths?.[entry.path])\n const operation = (getResolvedRef(pathItem?.[entry.method]) ?? {}) as OperationObject\n const operationWithPathParams = {\n ...operation,\n parameters: combineParams(pathItem?.parameters, operation.parameters),\n }\n\n const parameters = extractParameters(operationWithPathParams.parameters ?? [])\n const body = extractRequestBody(operationWithPathParams)\n const responseExamples = extractResponseExamples(operationWithPathParams.responses)\n\n index.push({\n type: 'operation',\n title: entry.title,\n id: entry.id,\n description: operationWithPathParams.description || '',\n method: entry.method,\n path: entry.path,\n body: body || '',\n parameters: parameters ?? '',\n responseExamples,\n operationId: operationWithPathParams.operationId,\n entry,\n })\n\n return\n }\n\n // Webhook\n if (entry.type === 'webhook') {\n const webhook = getResolvedRef(document?.webhooks?.[entry.name]?.[entry.method]) ?? {}\n\n index.push({\n id: entry.id,\n type: 'webhook',\n title: entry.title,\n description: 'Webhook',\n method: entry.method,\n body: webhook.description || '',\n operationId: webhook.operationId,\n entry,\n })\n\n return\n }\n\n // Model\n if (entry.type === 'model') {\n const schema = getResolvedRef(document?.components?.schemas?.[entry.name])\n\n const description = schema?.description ?? ''\n\n index.push({\n type: 'model',\n title: entry.title,\n description: 'Model',\n id: entry.id,\n body: description,\n entry,\n })\n\n return\n }\n\n // Models heading\n if (entry.type === 'models') {\n index.push({\n id: entry.id,\n type: 'heading',\n title: 'Models',\n description: 'Heading',\n body: '',\n entry,\n })\n\n return\n }\n\n // Tag\n if (entry.type === 'tag' && entry.isWebhooks === true) {\n index.push({\n id: entry.id,\n type: 'heading',\n title: 'Webhooks',\n description: 'Heading',\n body: '',\n entry,\n })\n\n return\n }\n\n if (entry.type === 'tag' && entry.isGroup === false) {\n index.push({\n id: entry.id,\n title: entry.title,\n description: entry.description || '',\n type: 'tag',\n body: '',\n entry,\n })\n\n return\n }\n\n // Tag group\n if (entry.type === 'tag' && entry.isGroup === true) {\n index.push({\n id: entry.id,\n title: entry.title,\n description: 'Tag Group',\n type: 'tag',\n body: '',\n entry,\n })\n\n return\n }\n\n // Headings from info.description\n if (entry.type === 'text') {\n index.push({\n id: entry.id,\n type: 'heading',\n title: entry.title ?? '',\n description: 'Heading',\n body: '',\n entry,\n })\n\n return\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type { TraversedEntry } from '@scalar/workspace-store/schemas/navigation';
|
|
2
|
-
import type { ParameterMap } from '../../helpers/openapi.js';
|
|
3
2
|
export type EntryType = 'operation' | 'webhook' | 'model' | 'heading' | 'tag';
|
|
4
3
|
export type FuseData = {
|
|
5
4
|
type: EntryType;
|
|
6
5
|
id: string;
|
|
7
6
|
title: string;
|
|
8
7
|
description: string;
|
|
9
|
-
body?: string | string[]
|
|
8
|
+
body?: string | string[];
|
|
9
|
+
parameters?: string | string[];
|
|
10
10
|
responseExamples?: string[];
|
|
11
11
|
method?: string;
|
|
12
12
|
path?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/features/Search/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4CAA4C,CAAA;AAEhF,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/features/Search/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4CAA4C,CAAA;AAEhF,MAAM,MAAM,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,KAAK,CAAA;AAE7E,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,SAAS,CAAA;IACf,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IACxB,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IAC9B,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,KAAK,EAAE,cAAc,CAAA;CACtB,CAAA"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ClientPlugin } from '@scalar/oas-utils/helpers';
|
|
2
|
-
import type {
|
|
2
|
+
import type { ApiReferenceConfiguration } from '@scalar/types/api-reference';
|
|
3
|
+
import type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments';
|
|
3
4
|
import { type ComputedRef } from 'vue';
|
|
4
5
|
/**
|
|
5
6
|
* Maps API reference configuration callbacks to client plugins.
|
|
@@ -16,5 +17,5 @@ import { type ComputedRef } from 'vue';
|
|
|
16
17
|
* @param config - Reactive configuration object containing optional hook callbacks
|
|
17
18
|
* @returns Array containing a single plugin with the mapped hooks
|
|
18
19
|
*/
|
|
19
|
-
export declare const mapConfigPlugins: (config: ComputedRef<
|
|
20
|
+
export declare const mapConfigPlugins: (config: ComputedRef<ApiReferenceConfiguration>, environment: ComputedRef<XScalarEnvironment>) => ClientPlugin[];
|
|
20
21
|
//# sourceMappingURL=map-config-plugins.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"map-config-plugins.d.ts","sourceRoot":"","sources":["../../src/helpers/map-config-plugins.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAC7D,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"map-config-plugins.d.ts","sourceRoot":"","sources":["../../src/helpers/map-config-plugins.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAC7D,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAA;AAE5E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2EAA2E,CAAA;AACnH,OAAO,EAAE,KAAK,WAAW,EAAS,MAAM,KAAK,CAAA;AAE7C;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,gBAAgB,GAC3B,QAAQ,WAAW,CAAC,yBAAyB,CAAC,EAC9C,aAAa,WAAW,CAAC,kBAAkB,CAAC,KAC3C,YAAY,EAwCd,CAAA"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { watch } from "vue";
|
|
2
|
+
import { buildRequest, getEnvironmentVariables } from "@scalar/workspace-store/request-example";
|
|
2
3
|
//#region src/helpers/map-config-plugins.ts
|
|
3
4
|
/**
|
|
4
5
|
* Maps API reference configuration callbacks to client plugins.
|
|
@@ -15,18 +16,21 @@ import { watch } from "vue";
|
|
|
15
16
|
* @param config - Reactive configuration object containing optional hook callbacks
|
|
16
17
|
* @returns Array containing a single plugin with the mapped hooks
|
|
17
18
|
*/
|
|
18
|
-
var mapConfigPlugins = (config) => {
|
|
19
|
+
var mapConfigPlugins = (config, environment) => {
|
|
19
20
|
const plugin = { hooks: {} };
|
|
20
|
-
watch([
|
|
21
|
+
watch([
|
|
22
|
+
() => config.value.onBeforeRequest,
|
|
23
|
+
() => config.value.onRequestSent,
|
|
24
|
+
() => environment.value
|
|
25
|
+
], ([onBeforeRequest, onRequestSent, environment]) => {
|
|
26
|
+
const envVariables = getEnvironmentVariables(environment);
|
|
21
27
|
if (!plugin.hooks) plugin.hooks = {};
|
|
22
28
|
plugin.hooks.beforeRequest = onBeforeRequest ? async (payload) => {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
if (result === void 0) return payload;
|
|
29
|
-
return result;
|
|
29
|
+
await onBeforeRequest({
|
|
30
|
+
request: buildRequest(payload.requestBuilder, { envVariables }).request,
|
|
31
|
+
requestBuilder: payload.requestBuilder,
|
|
32
|
+
envVariables
|
|
33
|
+
});
|
|
30
34
|
} : void 0;
|
|
31
35
|
/**
|
|
32
36
|
* Maps onRequestSent to responseReceived hook.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"map-config-plugins.js","names":[],"sources":["../../src/helpers/map-config-plugins.ts"],"sourcesContent":["import type { ClientPlugin } from '@scalar/oas-utils/helpers'\nimport type {
|
|
1
|
+
{"version":3,"file":"map-config-plugins.js","names":[],"sources":["../../src/helpers/map-config-plugins.ts"],"sourcesContent":["import type { ClientPlugin } from '@scalar/oas-utils/helpers'\nimport type { ApiReferenceConfiguration } from '@scalar/types/api-reference'\nimport { buildRequest, getEnvironmentVariables } from '@scalar/workspace-store/request-example'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport { type ComputedRef, watch } from 'vue'\n\n/**\n * Maps API reference configuration callbacks to client plugins.\n *\n * This function transforms the legacy onBeforeRequest and onRequestSent callbacks\n * into the new plugin hook system. The mapping is reactive, so changes to the\n * configuration will automatically update the plugin hooks.\n *\n * Note: onRequestSent is mapped to responseReceived hook. This is not a perfect\n * one-to-one mapping, but it maintains backward compatibility with the old API.\n * The old callback receives only the URL string, while the new hook receives\n * the full response object.\n *\n * @param config - Reactive configuration object containing optional hook callbacks\n * @returns Array containing a single plugin with the mapped hooks\n */\nexport const mapConfigPlugins = (\n config: ComputedRef<ApiReferenceConfiguration>,\n environment: ComputedRef<XScalarEnvironment>,\n): ClientPlugin[] => {\n // Create a new plugin with the hooks which is going to be updated by the watcher when config changes\n const plugin: ClientPlugin = { hooks: {} }\n\n watch(\n [() => config.value.onBeforeRequest, () => config.value.onRequestSent, () => environment.value],\n ([onBeforeRequest, onRequestSent, environment]) => {\n // Get the environment variables for the current environment\n const envVariables = getEnvironmentVariables(environment)\n\n // Initialize the hooks object if it doesn't exist\n if (!plugin.hooks) {\n plugin.hooks = {}\n }\n\n plugin.hooks.beforeRequest = onBeforeRequest\n ? async (payload) => {\n await onBeforeRequest({\n // We need to build the request to get the fetch `Request`\n request: buildRequest(payload.requestBuilder, { envVariables }).request,\n requestBuilder: payload.requestBuilder,\n envVariables,\n })\n }\n : undefined\n\n /**\n * Maps onRequestSent to responseReceived hook.\n * The old API only passed the URL string, so we extract it from the request.\n */\n plugin.hooks.responseReceived = onRequestSent\n ? (payload) => {\n onRequestSent(payload.request.url)\n }\n : undefined\n },\n { immediate: true },\n )\n\n return [plugin]\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAqBA,IAAa,oBACX,QACA,gBACmB;CAEnB,MAAM,SAAuB,EAAE,OAAO,EAAE,EAAE;AAE1C,OACE;QAAO,OAAO,MAAM;QAAuB,OAAO,MAAM;QAAqB,YAAY;EAAM,GAC9F,CAAC,iBAAiB,eAAe,iBAAiB;EAEjD,MAAM,eAAe,wBAAwB,YAAY;AAGzD,MAAI,CAAC,OAAO,MACV,QAAO,QAAQ,EAAE;AAGnB,SAAO,MAAM,gBAAgB,kBACzB,OAAO,YAAY;AACjB,SAAM,gBAAgB;IAEpB,SAAS,aAAa,QAAQ,gBAAgB,EAAE,cAAc,CAAC,CAAC;IAChE,gBAAgB,QAAQ;IACxB;IACD,CAAC;MAEJ,KAAA;;;;;AAMJ,SAAO,MAAM,mBAAmB,iBAC3B,YAAY;AACX,iBAAc,QAAQ,QAAQ,IAAI;MAEpC,KAAA;IAEN,EAAE,WAAW,MAAM,CACpB;AAED,QAAO,CAAC,OAAO"}
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
import type { OpenApiDocument, OperationObject, ParameterObject } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document';
|
|
1
|
+
import type { OpenApiDocument, OperationObject, ParameterObject, ReferenceType } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document';
|
|
2
2
|
/**
|
|
3
3
|
* Extracts the request body from an operation.
|
|
4
4
|
*/
|
|
5
|
-
export declare function extractRequestBody(operation: OperationObject): string[] |
|
|
5
|
+
export declare function extractRequestBody(operation: OperationObject): string[] | null;
|
|
6
|
+
/**
|
|
7
|
+
* Extracts parameters from an operation into searchable strings.
|
|
8
|
+
*/
|
|
9
|
+
export declare function extractParameters(parameters: ReferenceType<ParameterObject>[]): string[] | null;
|
|
6
10
|
/**
|
|
7
11
|
* Deep merge for objects
|
|
8
12
|
*/
|
|
@@ -12,16 +16,4 @@ export declare function deepMerge(source: Record<any, any>, target: Record<any,
|
|
|
12
16
|
* The returning object has the same structure as a valid OpenAPI specification, but everything is empty.
|
|
13
17
|
*/
|
|
14
18
|
export declare function createEmptySpecification(partialSpecification?: Partial<OpenApiDocument>): OpenApiDocument;
|
|
15
|
-
export type ParameterMap = {
|
|
16
|
-
path: ParameterObject[];
|
|
17
|
-
query: ParameterObject[];
|
|
18
|
-
header: ParameterObject[];
|
|
19
|
-
cookie: ParameterObject[];
|
|
20
|
-
};
|
|
21
|
-
/**
|
|
22
|
-
* This function creates a parameter map from an Operation Object, that's easier to consume.
|
|
23
|
-
*
|
|
24
|
-
* TODO: Isn't it easier to just stick to the OpenAPI structure, without transforming it?
|
|
25
|
-
*/
|
|
26
|
-
export declare function createParameterMap(operation: OperationObject): ParameterMap;
|
|
27
19
|
//# sourceMappingURL=openapi.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openapi.d.ts","sourceRoot":"","sources":["../../src/helpers/openapi.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,eAAe,EACf,eAAe,EACf,eAAe,
|
|
1
|
+
{"version":3,"file":"openapi.d.ts","sourceRoot":"","sources":["../../src/helpers/openapi.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,eAAe,EACf,eAAe,EACf,eAAe,EACf,aAAa,EAGd,MAAM,8DAA8D,CAAA;AAwGrE;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,eAAe,GAAG,MAAM,EAAE,GAAG,IAAI,CAS9E;AAwBD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,aAAa,CAAC,eAAe,CAAC,EAAE,GAAG,MAAM,EAAE,GAAG,IAAI,CAE/F;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,oBAW3E;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,mBA4BvF"}
|
package/dist/helpers/openapi.js
CHANGED
|
@@ -66,13 +66,30 @@ function recursiveLogger(obj) {
|
|
|
66
66
|
* Extracts the request body from an operation.
|
|
67
67
|
*/
|
|
68
68
|
function extractRequestBody(operation) {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
69
|
+
const content = getResolvedRef(operation?.requestBody)?.content;
|
|
70
|
+
const contentValue = Object.values(content ?? {});
|
|
71
|
+
if (contentValue.length === 0) return null;
|
|
72
|
+
return contentValue.flatMap((media) => recursiveLogger(media));
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Formats a parameter into a searchable string.
|
|
76
|
+
*/
|
|
77
|
+
function formatParameter(param) {
|
|
78
|
+
const output = [param.name];
|
|
79
|
+
output.push(param.required ? "REQUIRED" : "optional");
|
|
80
|
+
output.push(param.in);
|
|
81
|
+
if ("schema" in param && param.schema) {
|
|
82
|
+
const schema = getResolvedRef(param.schema);
|
|
83
|
+
if (schema) output.push(schemaTypeToString(schema));
|
|
75
84
|
}
|
|
85
|
+
if (param.description) output.push(param.description);
|
|
86
|
+
return output.join(" ");
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Extracts parameters from an operation into searchable strings.
|
|
90
|
+
*/
|
|
91
|
+
function extractParameters(parameters) {
|
|
92
|
+
return parameters.map((parameter) => formatParameter(getResolvedRef(parameter)));
|
|
76
93
|
}
|
|
77
94
|
/**
|
|
78
95
|
* Deep merge for objects
|
|
@@ -110,29 +127,7 @@ function createEmptySpecification(partialSpecification) {
|
|
|
110
127
|
deepMerge(partialSpecification, emptySpecification);
|
|
111
128
|
return emptySpecification;
|
|
112
129
|
}
|
|
113
|
-
/**
|
|
114
|
-
* This function creates a parameter map from an Operation Object, that's easier to consume.
|
|
115
|
-
*
|
|
116
|
-
* TODO: Isn't it easier to just stick to the OpenAPI structure, without transforming it?
|
|
117
|
-
*/
|
|
118
|
-
function createParameterMap(operation) {
|
|
119
|
-
const map = {
|
|
120
|
-
path: [],
|
|
121
|
-
query: [],
|
|
122
|
-
header: [],
|
|
123
|
-
cookie: []
|
|
124
|
-
};
|
|
125
|
-
(operation.parameters ?? []).forEach((parameterRef) => {
|
|
126
|
-
const parameter = getResolvedRef(parameterRef);
|
|
127
|
-
if (!parameter) return;
|
|
128
|
-
if (parameter.in === "path") map.path.push(parameter);
|
|
129
|
-
else if (parameter.in === "query") map.query.push(parameter);
|
|
130
|
-
else if (parameter.in === "header") map.header.push(parameter);
|
|
131
|
-
else if (parameter.in === "cookie") map.cookie.push(parameter);
|
|
132
|
-
});
|
|
133
|
-
return map;
|
|
134
|
-
}
|
|
135
130
|
//#endregion
|
|
136
|
-
export { createEmptySpecification,
|
|
131
|
+
export { createEmptySpecification, extractParameters, extractRequestBody };
|
|
137
132
|
|
|
138
133
|
//# sourceMappingURL=openapi.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openapi.js","names":[],"sources":["../../src/helpers/openapi.ts"],"sourcesContent":["import { getResolvedRef } from '@scalar/workspace-store/helpers/get-resolved-ref'\nimport type { MediaTypeObject } from '@scalar/workspace-store/schemas/v3.1/strict/media-type'\nimport type {\n OpenApiDocument,\n OperationObject,\n ParameterObject,\n SchemaObject,\n SchemaReferenceType,\n} from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport { isObjectSchema } from '@scalar/workspace-store/schemas/v3.1/strict/type-guards'\n\n/** Object schema shape with properties, used when logging request body. */\ntype ObjectSchemaWithProperties = {\n properties: Record<string, SchemaReferenceType<SchemaObject>>\n required?: string[]\n}\n\nconst isSchemaObject = (value: unknown): value is SchemaObject => typeof value === 'object' && value !== null\n\nconst schemaTypeToString = (schema: SchemaObject): string => {\n if (!('type' in schema)) {\n return ''\n }\n\n if (typeof schema.type === 'string') {\n return schema.type\n }\n\n return Array.isArray(schema.type) ? schema.type.join('|') : ''\n}\n\n/**\n * Resolves a schema reference from workspace-store to a SchemaObject.\n * Returns undefined when a reference exists but has not been resolved yet.\n */\nfunction resolveSchemaRef(ref: SchemaReferenceType<SchemaObject>): SchemaObject | undefined {\n if (typeof ref === 'object' && ref !== null && '$ref' in ref) {\n return isSchemaObject(ref['$ref-value']) ? ref['$ref-value'] : undefined\n }\n\n return ref\n}\n\n/**\n * Formats a property object into a string.\n */\nfunction formatProperty(key: string, obj: ObjectSchemaWithProperties): string {\n let output = key\n const isRequired = obj.required?.includes(key)\n output += isRequired ? ' REQUIRED ' : ' optional '\n const propRef = obj.properties[key]\n if (!propRef) return output\n const property = resolveSchemaRef(propRef)\n\n if (property) {\n output += schemaTypeToString(property)\n\n if ('description' in property && typeof property.description === 'string') {\n output += ` ${property.description}`\n }\n }\n\n return output\n}\n\n/**\n * Recursively logs the properties of an object.\n */\nfunction recursiveLogger(obj: MediaTypeObject): string[] {\n const results: string[] = ['Body']\n const schema = getResolvedRef(obj?.schema)\n\n if (!schema || !isObjectSchema(schema) || !schema.properties) {\n return results\n }\n\n const properties = schema.properties\n const schemaWithProps: ObjectSchemaWithProperties = {\n properties,\n required: schema.required,\n }\n Object.keys(properties).forEach((key) => {\n if (!obj.schema) {\n return\n }\n\n results.push(formatProperty(key, schemaWithProps))\n\n const propRef = properties[key]\n if (!propRef) return\n const property = resolveSchemaRef(propRef)\n if (property && isObjectSchema(property) && property.properties) {\n const nestedProperties = property.properties\n Object.keys(nestedProperties).forEach((subKey) => {\n const ref = nestedProperties[subKey]\n if (!ref) return\n const nested = resolveSchemaRef(ref)\n const typeStr = nested ? schemaTypeToString(nested) : ''\n results.push(`${subKey} ${typeStr}`)\n })\n }\n })\n\n return results\n}\n\n/**\n * Extracts the request body from an operation.\n */\nexport function extractRequestBody(operation: OperationObject): string[] |
|
|
1
|
+
{"version":3,"file":"openapi.js","names":[],"sources":["../../src/helpers/openapi.ts"],"sourcesContent":["import { getResolvedRef } from '@scalar/workspace-store/helpers/get-resolved-ref'\nimport type { MediaTypeObject } from '@scalar/workspace-store/schemas/v3.1/strict/media-type'\nimport type {\n OpenApiDocument,\n OperationObject,\n ParameterObject,\n ReferenceType,\n SchemaObject,\n SchemaReferenceType,\n} from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport { isObjectSchema } from '@scalar/workspace-store/schemas/v3.1/strict/type-guards'\n\n/** Object schema shape with properties, used when logging request body. */\ntype ObjectSchemaWithProperties = {\n properties: Record<string, SchemaReferenceType<SchemaObject>>\n required?: string[]\n}\n\nconst isSchemaObject = (value: unknown): value is SchemaObject => typeof value === 'object' && value !== null\n\nconst schemaTypeToString = (schema: SchemaObject): string => {\n if (!('type' in schema)) {\n return ''\n }\n\n if (typeof schema.type === 'string') {\n return schema.type\n }\n\n return Array.isArray(schema.type) ? schema.type.join('|') : ''\n}\n\n/**\n * Resolves a schema reference from workspace-store to a SchemaObject.\n * Returns undefined when a reference exists but has not been resolved yet.\n */\nfunction resolveSchemaRef(ref: SchemaReferenceType<SchemaObject>): SchemaObject | undefined {\n if (typeof ref === 'object' && ref !== null && '$ref' in ref) {\n return isSchemaObject(ref['$ref-value']) ? ref['$ref-value'] : undefined\n }\n\n return ref\n}\n\n/**\n * Formats a property object into a string.\n */\nfunction formatProperty(key: string, obj: ObjectSchemaWithProperties): string {\n let output = key\n const isRequired = obj.required?.includes(key)\n output += isRequired ? ' REQUIRED ' : ' optional '\n const propRef = obj.properties[key]\n if (!propRef) {\n return output\n }\n const property = resolveSchemaRef(propRef)\n\n if (property) {\n output += schemaTypeToString(property)\n\n if ('description' in property && typeof property.description === 'string') {\n output += ` ${property.description}`\n }\n }\n\n return output\n}\n\n/**\n * Recursively logs the properties of an object.\n */\nfunction recursiveLogger(obj: MediaTypeObject): string[] {\n const results: string[] = ['Body']\n const schema = getResolvedRef(obj?.schema)\n\n if (!schema || !isObjectSchema(schema) || !schema.properties) {\n return results\n }\n\n const properties = schema.properties\n const schemaWithProps: ObjectSchemaWithProperties = {\n properties,\n required: schema.required,\n }\n Object.keys(properties).forEach((key) => {\n if (!obj.schema) {\n return\n }\n\n results.push(formatProperty(key, schemaWithProps))\n\n const propRef = properties[key]\n if (!propRef) {\n return\n }\n const property = resolveSchemaRef(propRef)\n if (property && isObjectSchema(property) && property.properties) {\n const nestedProperties = property.properties\n Object.keys(nestedProperties).forEach((subKey) => {\n const ref = nestedProperties[subKey]\n if (!ref) {\n return\n }\n const nested = resolveSchemaRef(ref)\n const typeStr = nested ? schemaTypeToString(nested) : ''\n results.push(`${subKey} ${typeStr}`)\n })\n }\n })\n\n return results\n}\n\n/**\n * Extracts the request body from an operation.\n */\nexport function extractRequestBody(operation: OperationObject): string[] | null {\n const content = getResolvedRef(operation?.requestBody)?.content\n const contentValue = Object.values(content ?? {})\n if (contentValue.length === 0) {\n // No content found\n return null\n }\n\n return contentValue.flatMap((media) => recursiveLogger(media))\n}\n\n/**\n * Formats a parameter into a searchable string.\n */\nfunction formatParameter(param: ParameterObject): string {\n const output = [param.name]\n output.push(param.required ? 'REQUIRED' : 'optional')\n output.push(param.in)\n\n if ('schema' in param && param.schema) {\n const schema = getResolvedRef(param.schema)\n if (schema) {\n output.push(schemaTypeToString(schema))\n }\n }\n\n if (param.description) {\n output.push(param.description)\n }\n\n return output.join(' ')\n}\n\n/**\n * Extracts parameters from an operation into searchable strings.\n */\nexport function extractParameters(parameters: ReferenceType<ParameterObject>[]): string[] | null {\n return parameters.map((parameter) => formatParameter(getResolvedRef(parameter)))\n}\n\n/**\n * Deep merge for objects\n */\nexport function deepMerge(source: Record<any, any>, target: Record<any, any>) {\n for (const [key, val] of Object.entries(source)) {\n if (val !== null && typeof val === 'object') {\n target[key] ??= new val.__proto__.constructor()\n deepMerge(val, target[key])\n } else if (typeof val !== 'undefined') {\n target[key] = val\n }\n }\n\n return target\n}\n\n/**\n * Creates an empty specification object.\n * The returning object has the same structure as a valid OpenAPI specification, but everything is empty.\n */\nexport function createEmptySpecification(partialSpecification?: Partial<OpenApiDocument>) {\n const emptySpecification = {\n openapi: '3.1.0',\n info: {\n title: '',\n description: '',\n termsOfService: '',\n version: '',\n license: {\n name: '',\n url: '',\n },\n contact: {\n email: '',\n },\n },\n servers: [],\n tags: [],\n 'x-scalar-original-document-hash': '',\n }\n\n if (!partialSpecification) {\n return emptySpecification as OpenApiDocument\n }\n\n deepMerge(partialSpecification, emptySpecification)\n\n return emptySpecification as OpenApiDocument\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deep-clones plain data for use where mutation must not affect the source.
|
|
3
|
+
*
|
|
4
|
+
* In the browser we use `structuredClone`, which preserves `Date`, `Map`, `Set`,
|
|
5
|
+
* typed arrays, and other structured types. During SSR there is no `window`, so
|
|
6
|
+
* we fall back to `JSON.parse(JSON.stringify(...))`, which only supports JSON
|
|
7
|
+
* values (functions, `undefined` in objects, symbols, etc. are dropped or altered).
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* const copy = safeDeepClone(spec)
|
|
12
|
+
* copy.info.title = 'Draft'
|
|
13
|
+
* // original spec is unchanged
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export declare const safeDeepClone: <T>(value: T) => T;
|
|
17
|
+
//# sourceMappingURL=safe-deep-clone.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safe-deep-clone.d.ts","sourceRoot":"","sources":["../../src/helpers/safe-deep-clone.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,aAAa,GAAI,CAAC,EAAE,OAAO,CAAC,KAAG,CAK3C,CAAA"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { deepClone } from "@scalar/workspace-store/helpers/deep-clone";
|
|
2
|
+
//#region src/helpers/safe-deep-clone.ts
|
|
3
|
+
/**
|
|
4
|
+
* Deep-clones plain data for use where mutation must not affect the source.
|
|
5
|
+
*
|
|
6
|
+
* In the browser we use `structuredClone`, which preserves `Date`, `Map`, `Set`,
|
|
7
|
+
* typed arrays, and other structured types. During SSR there is no `window`, so
|
|
8
|
+
* we fall back to `JSON.parse(JSON.stringify(...))`, which only supports JSON
|
|
9
|
+
* values (functions, `undefined` in objects, symbols, etc. are dropped or altered).
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* const copy = safeDeepClone(spec)
|
|
14
|
+
* copy.info.title = 'Draft'
|
|
15
|
+
* // original spec is unchanged
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
var safeDeepClone = (value) => {
|
|
19
|
+
if (typeof window === "undefined") return deepClone(value);
|
|
20
|
+
return window.structuredClone(value);
|
|
21
|
+
};
|
|
22
|
+
//#endregion
|
|
23
|
+
export { safeDeepClone };
|
|
24
|
+
|
|
25
|
+
//# sourceMappingURL=safe-deep-clone.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safe-deep-clone.js","names":[],"sources":["../../src/helpers/safe-deep-clone.ts"],"sourcesContent":["import { deepClone } from '@scalar/workspace-store/helpers/deep-clone'\n\n/**\n * Deep-clones plain data for use where mutation must not affect the source.\n *\n * In the browser we use `structuredClone`, which preserves `Date`, `Map`, `Set`,\n * typed arrays, and other structured types. During SSR there is no `window`, so\n * we fall back to `JSON.parse(JSON.stringify(...))`, which only supports JSON\n * values (functions, `undefined` in objects, symbols, etc. are dropped or altered).\n *\n * @example\n * ```ts\n * const copy = safeDeepClone(spec)\n * copy.info.title = 'Draft'\n * // original spec is unchanged\n * ```\n */\nexport const safeDeepClone = <T>(value: T): T => {\n if (typeof window === 'undefined') {\n return deepClone(value)\n }\n return window.structuredClone(value) as T\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAiBA,IAAa,iBAAoB,UAAgB;AAC/C,KAAI,OAAO,WAAW,YACpB,QAAO,UAAU,MAAM;AAEzB,QAAO,OAAO,gBAAgB,MAAM"}
|