@scalar/api-reference 1.55.3 → 1.57.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/CHANGELOG.md +82 -0
  2. package/dist/blocks/scalar-info-block/components/DownloadLink.vue.d.ts +2 -0
  3. package/dist/blocks/scalar-info-block/components/DownloadLink.vue.d.ts.map +1 -1
  4. package/dist/blocks/scalar-info-block/components/DownloadLink.vue.js +1 -1
  5. package/dist/blocks/scalar-info-block/components/DownloadLink.vue.js.map +1 -1
  6. package/dist/blocks/scalar-info-block/components/DownloadLink.vue.script.js +9 -7
  7. package/dist/blocks/scalar-info-block/components/DownloadLink.vue.script.js.map +1 -1
  8. package/dist/blocks/scalar-info-block/components/InfoBlock.vue.d.ts +4 -2
  9. package/dist/blocks/scalar-info-block/components/InfoBlock.vue.d.ts.map +1 -1
  10. package/dist/blocks/scalar-info-block/components/InfoBlock.vue.js.map +1 -1
  11. package/dist/blocks/scalar-info-block/components/InfoBlock.vue.script.js +9 -4
  12. package/dist/blocks/scalar-info-block/components/InfoBlock.vue.script.js.map +1 -1
  13. package/dist/blocks/scalar-info-block/components/IntroductionLayout.vue.d.ts +2 -1
  14. package/dist/blocks/scalar-info-block/components/IntroductionLayout.vue.d.ts.map +1 -1
  15. package/dist/blocks/scalar-info-block/components/IntroductionLayout.vue.js +1 -1
  16. package/dist/blocks/scalar-info-block/components/IntroductionLayout.vue.js.map +1 -1
  17. package/dist/blocks/scalar-info-block/components/IntroductionLayout.vue.script.js +7 -3
  18. package/dist/blocks/scalar-info-block/components/IntroductionLayout.vue.script.js.map +1 -1
  19. package/dist/blocks/scalar-info-block/components/{OpenApiVersion.vue.d.ts → SpecificationVersion.vue.d.ts} +5 -2
  20. package/dist/blocks/scalar-info-block/components/SpecificationVersion.vue.d.ts.map +1 -0
  21. package/dist/blocks/scalar-info-block/components/SpecificationVersion.vue.js +7 -0
  22. package/dist/blocks/scalar-info-block/components/SpecificationVersion.vue.js.map +1 -0
  23. package/dist/blocks/scalar-info-block/components/SpecificationVersion.vue.script.js +23 -0
  24. package/dist/blocks/scalar-info-block/components/SpecificationVersion.vue.script.js.map +1 -0
  25. package/dist/browser/standalone.js +275 -261
  26. package/dist/browser/webpack-stats.json +1 -1
  27. package/dist/components/AgentScalar/AgentScalarChatInterface.vue.d.ts +1 -1
  28. package/dist/components/AgentScalar/AgentScalarChatInterface.vue.d.ts.map +1 -1
  29. package/dist/components/AgentScalar/AgentScalarChatInterface.vue.js.map +1 -1
  30. package/dist/components/AgentScalar/AgentScalarChatInterface.vue.script.js.map +1 -1
  31. package/dist/components/AgentScalar/AgentScalarDrawer.vue.d.ts +1 -1
  32. package/dist/components/AgentScalar/AgentScalarDrawer.vue.d.ts.map +1 -1
  33. package/dist/components/AgentScalar/AgentScalarDrawer.vue.js +1 -1
  34. package/dist/components/AgentScalar/AgentScalarDrawer.vue.js.map +1 -1
  35. package/dist/components/AgentScalar/AgentScalarDrawer.vue.script.js.map +1 -1
  36. package/dist/components/ApiReference.vue.d.ts.map +1 -1
  37. package/dist/components/ApiReference.vue.js +1 -1
  38. package/dist/components/ApiReference.vue.js.map +1 -1
  39. package/dist/components/ApiReference.vue.script.js +20 -8
  40. package/dist/components/ApiReference.vue.script.js.map +1 -1
  41. package/dist/components/Badge/Badge.vue.js +1 -1
  42. package/dist/components/Badge/Badge.vue.js.map +1 -1
  43. package/dist/components/Badge/Badge.vue.script.js.map +1 -1
  44. package/dist/components/Content/Auth/Auth.vue.d.ts.map +1 -1
  45. package/dist/components/Content/Auth/Auth.vue.js.map +1 -1
  46. package/dist/components/Content/Auth/Auth.vue.script.js +3 -2
  47. package/dist/components/Content/Auth/Auth.vue.script.js.map +1 -1
  48. package/dist/components/Content/Content.vue.d.ts.map +1 -1
  49. package/dist/components/Content/Content.vue.js.map +1 -1
  50. package/dist/components/Content/Content.vue.script.js +23 -9
  51. package/dist/components/Content/Content.vue.script.js.map +1 -1
  52. package/dist/components/Content/Operations/TraversedEntry.vue.d.ts +2 -3
  53. package/dist/components/Content/Operations/TraversedEntry.vue.d.ts.map +1 -1
  54. package/dist/components/Content/Operations/TraversedEntry.vue.js.map +1 -1
  55. package/dist/components/Content/Operations/TraversedEntry.vue.script.js.map +1 -1
  56. package/dist/components/Content/Schema/Schema.vue.d.ts +2 -0
  57. package/dist/components/Content/Schema/Schema.vue.d.ts.map +1 -1
  58. package/dist/components/Content/Schema/Schema.vue.js +1 -1
  59. package/dist/components/Content/Schema/Schema.vue.js.map +1 -1
  60. package/dist/components/Content/Schema/Schema.vue.script.js +5 -0
  61. package/dist/components/Content/Schema/Schema.vue.script.js.map +1 -1
  62. package/dist/components/Content/Schema/SchemaObjectProperties.vue.d.ts.map +1 -1
  63. package/dist/components/Content/Schema/SchemaObjectProperties.vue.js.map +1 -1
  64. package/dist/components/Content/Schema/SchemaObjectProperties.vue.script.js +5 -3
  65. package/dist/components/Content/Schema/SchemaObjectProperties.vue.script.js.map +1 -1
  66. package/dist/components/MobileHeader.vue.js.map +1 -1
  67. package/dist/components/MobileHeader.vue.script.js +1 -1
  68. package/dist/components/MobileHeader.vue.script.js.map +1 -1
  69. package/dist/features/Operation/components/RequestBody.vue.d.ts.map +1 -1
  70. package/dist/features/Operation/components/RequestBody.vue.js +1 -1
  71. package/dist/features/Operation/components/RequestBody.vue.js.map +1 -1
  72. package/dist/features/Operation/components/RequestBody.vue.script.js +1 -0
  73. package/dist/features/Operation/components/RequestBody.vue.script.js.map +1 -1
  74. package/dist/features/Search/helpers/create-fuse-instance.d.ts.map +1 -1
  75. package/dist/features/Search/helpers/create-fuse-instance.js +20 -12
  76. package/dist/features/Search/helpers/create-fuse-instance.js.map +1 -1
  77. package/dist/features/Search/helpers/create-search-index.d.ts.map +1 -1
  78. package/dist/features/Search/helpers/create-search-index.js +18 -8
  79. package/dist/features/Search/helpers/create-search-index.js.map +1 -1
  80. package/dist/features/Search/types.d.ts +6 -0
  81. package/dist/features/Search/types.d.ts.map +1 -1
  82. package/dist/features/developer-tools/components/ApiReferenceToolbarConfigTheme.vue.d.ts +2 -2
  83. package/dist/helpers/map-config-plugins.d.ts.map +1 -1
  84. package/dist/helpers/map-config-plugins.js +9 -1
  85. package/dist/helpers/map-config-plugins.js.map +1 -1
  86. package/dist/helpers/normalize-configurations.d.ts.map +1 -1
  87. package/dist/helpers/normalize-configurations.js +6 -6
  88. package/dist/helpers/normalize-configurations.js.map +1 -1
  89. package/dist/helpers/openapi.d.ts +34 -5
  90. package/dist/helpers/openapi.d.ts.map +1 -1
  91. package/dist/helpers/openapi.js +108 -66
  92. package/dist/helpers/openapi.js.map +1 -1
  93. package/dist/standalone/lib/html-api.d.ts.map +1 -1
  94. package/dist/standalone/lib/html-api.js +10 -4
  95. package/dist/standalone/lib/html-api.js.map +1 -1
  96. package/dist/style.css +367 -1782
  97. package/dist/vue-styles.css +83 -83
  98. package/package.json +17 -15
  99. package/dist/blocks/scalar-info-block/components/OpenApiVersion.vue.d.ts.map +0 -1
  100. package/dist/blocks/scalar-info-block/components/OpenApiVersion.vue.js +0 -7
  101. package/dist/blocks/scalar-info-block/components/OpenApiVersion.vue.js.map +0 -1
  102. package/dist/blocks/scalar-info-block/components/OpenApiVersion.vue.script.js +0 -19
  103. package/dist/blocks/scalar-info-block/components/OpenApiVersion.vue.script.js.map +0 -1
@@ -2,11 +2,6 @@ import { getResolvedRef } from "@scalar/workspace-store/helpers/get-resolved-ref
2
2
  import { isObjectSchema } from "@scalar/workspace-store/schemas/v3.1/strict/type-guards";
3
3
  //#region src/helpers/openapi.ts
4
4
  var isSchemaObject = (value) => typeof value === "object" && value !== null;
5
- var schemaTypeToString = (schema) => {
6
- if (!("type" in schema)) return "";
7
- if (typeof schema.type === "string") return schema.type;
8
- return Array.isArray(schema.type) ? schema.type.join("|") : "";
9
- };
10
5
  /**
11
6
  * Resolves a schema reference from workspace-store to a SchemaObject.
12
7
  * Returns undefined when a reference exists but has not been resolved yet.
@@ -15,81 +10,128 @@ function resolveSchemaRef(ref) {
15
10
  if (typeof ref === "object" && ref !== null && "$ref" in ref) return isSchemaObject(ref["$ref-value"]) ? ref["$ref-value"] : void 0;
16
11
  return ref;
17
12
  }
18
- /**
19
- * Formats a property object into a string.
20
- */
21
- function formatProperty(key, obj) {
22
- let output = key;
23
- const isRequired = obj.required?.includes(key);
24
- output += isRequired ? " REQUIRED " : " optional ";
25
- const propRef = obj.properties[key];
26
- if (!propRef) return output;
27
- const property = resolveSchemaRef(propRef);
28
- if (property) {
29
- output += schemaTypeToString(property);
30
- if ("description" in property && typeof property.description === "string") output += ` ${property.description}`;
31
- }
32
- return output;
13
+ function pushUnique(target, value) {
14
+ if (!value) return;
15
+ if (!target.includes(value)) target.push(value);
33
16
  }
34
17
  /**
35
- * Recursively logs the properties of an object.
18
+ * Recursively visits every property of a schema, descending transparently through composition
19
+ * keywords (`oneOf`, `anyOf`, `allOf`) and one level into nested object properties.
20
+ *
21
+ * Composition is treated as transparent — a `oneOf` of two object variants is *the same level* as a
22
+ * single object, just expressed as multiple shapes. Property nesting is capped to keep the index
23
+ * focused on shallow, commonly-searched fields. A visited-set keyed by resolved-schema identity
24
+ * guards against recursive (`Tree → Tree`) schemas.
36
25
  */
37
- function recursiveLogger(obj) {
38
- const results = ["Body"];
39
- const schema = getResolvedRef(obj?.schema);
40
- if (!schema || !isObjectSchema(schema) || !schema.properties) return results;
41
- const properties = schema.properties;
42
- const schemaWithProps = {
43
- properties,
44
- required: schema.required
45
- };
46
- Object.keys(properties).forEach((key) => {
47
- if (!obj.schema) return;
48
- results.push(formatProperty(key, schemaWithProps));
49
- const propRef = properties[key];
50
- if (!propRef) return;
26
+ function collectSchemaProperties(schema, options, propertyDepth = 0) {
27
+ if (!schema || options.visited.has(schema)) return;
28
+ options.visited.add(schema);
29
+ [
30
+ ...schema.oneOf ?? [],
31
+ ...schema.anyOf ?? [],
32
+ ...schema.allOf ?? []
33
+ ].forEach((variantRef) => {
34
+ collectSchemaProperties(resolveSchemaRef(variantRef), options, propertyDepth);
35
+ });
36
+ if (isObjectSchema(schema) && schema.properties) Object.entries(schema.properties).forEach(([key, propRef]) => {
51
37
  const property = resolveSchemaRef(propRef);
52
- if (property && isObjectSchema(property) && property.properties) {
53
- const nestedProperties = property.properties;
54
- Object.keys(nestedProperties).forEach((subKey) => {
55
- const ref = nestedProperties[subKey];
56
- if (!ref) return;
57
- const nested = resolveSchemaRef(ref);
58
- const typeStr = nested ? schemaTypeToString(nested) : "";
59
- results.push(`${subKey} ${typeStr}`);
60
- });
61
- }
38
+ options.visit(key, property);
39
+ if (propertyDepth + 1 < options.maxPropertyDepth) collectSchemaProperties(property, options, propertyDepth + 1);
62
40
  });
63
- return results;
64
41
  }
65
42
  /**
66
- * Extracts the request body from an operation.
43
+ * Walks the request body schemas of an operation and yields each property schema with its key.
67
44
  */
68
- function extractRequestBody(operation) {
45
+ function forEachRequestBodyProperty(operation, visit) {
69
46
  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));
47
+ if (!content) return;
48
+ const visited = /* @__PURE__ */ new Set();
49
+ Object.values(content).forEach((media) => {
50
+ collectSchemaProperties(getResolvedRef(getResolvedRef(media)?.schema), {
51
+ visit,
52
+ visited,
53
+ maxPropertyDepth: 2
54
+ });
55
+ });
56
+ }
57
+ /**
58
+ * Extracts the names of every parameter on an operation.
59
+ *
60
+ * The returned strings contain only parameter names (e.g. `userId`, `limit`) so they can be indexed
61
+ * as a high-signal field for search. Filter-style metadata like `REQUIRED`, `optional`, `query` and
62
+ * the schema type are intentionally excluded — those tokens dilute fuzzy matches and produce false
63
+ * positives for queries like `query` or `integer`.
64
+ */
65
+ function extractParameterNames(parameters) {
66
+ const names = [];
67
+ parameters.forEach((parameter) => {
68
+ pushUnique(names, getResolvedRef(parameter)?.name);
69
+ });
70
+ return names;
71
+ }
72
+ /**
73
+ * Extracts the descriptions of every parameter on an operation.
74
+ *
75
+ * Kept separate from parameter names so the search index can weight each independently.
76
+ */
77
+ function extractParameterDescriptions(parameters) {
78
+ const descriptions = [];
79
+ parameters.forEach((parameter) => {
80
+ pushUnique(descriptions, getResolvedRef(parameter)?.description);
81
+ });
82
+ return descriptions;
83
+ }
84
+ /**
85
+ * Extracts the names of properties from the request body schema(s) of an operation.
86
+ *
87
+ * Walks every media type and includes both top-level and one level of nested property names so
88
+ * common fields like `email` or `username` surface in search regardless of how the body is shaped.
89
+ */
90
+ function extractBodyFieldNames(operation) {
91
+ const names = [];
92
+ forEachRequestBodyProperty(operation, (key) => {
93
+ pushUnique(names, key);
94
+ });
95
+ return names;
96
+ }
97
+ /**
98
+ * Extracts the descriptions of properties from the request body schema(s) of an operation.
99
+ */
100
+ function extractBodyDescriptions(operation) {
101
+ const descriptions = [];
102
+ forEachRequestBodyProperty(operation, (_key, schema) => {
103
+ if (schema && "description" in schema && typeof schema.description === "string") pushUnique(descriptions, schema.description);
104
+ });
105
+ return descriptions;
73
106
  }
74
107
  /**
75
- * Formats a parameter into a searchable string.
108
+ * Extracts the property names of a schema for the search index.
109
+ *
110
+ * Same depth and composition behavior as `extractBodyFieldNames` — descends transparently through
111
+ * `oneOf`/`anyOf`/`allOf`, walks one level into nested object properties, dedupes.
76
112
  */
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));
84
- }
85
- if (param.description) output.push(param.description);
86
- return output.join(" ");
113
+ function extractSchemaFieldNames(schema) {
114
+ const names = [];
115
+ collectSchemaProperties(schema, {
116
+ visit: (key) => pushUnique(names, key),
117
+ visited: /* @__PURE__ */ new Set(),
118
+ maxPropertyDepth: 2
119
+ });
120
+ return names;
87
121
  }
88
122
  /**
89
- * Extracts parameters from an operation into searchable strings.
123
+ * Extracts the property descriptions of a schema for the search index.
90
124
  */
91
- function extractParameters(parameters) {
92
- return parameters.map((parameter) => formatParameter(getResolvedRef(parameter)));
125
+ function extractSchemaDescriptions(schema) {
126
+ const descriptions = [];
127
+ collectSchemaProperties(schema, {
128
+ visit: (_key, propertySchema) => {
129
+ if (propertySchema && "description" in propertySchema && typeof propertySchema.description === "string") pushUnique(descriptions, propertySchema.description);
130
+ },
131
+ visited: /* @__PURE__ */ new Set(),
132
+ maxPropertyDepth: 2
133
+ });
134
+ return descriptions;
93
135
  }
94
136
  /**
95
137
  * Deep merge for objects
@@ -128,6 +170,6 @@ function createEmptySpecification(partialSpecification) {
128
170
  return emptySpecification;
129
171
  }
130
172
  //#endregion
131
- export { createEmptySpecification, extractParameters, extractRequestBody };
173
+ export { createEmptySpecification, extractBodyDescriptions, extractBodyFieldNames, extractParameterDescriptions, extractParameterNames, extractSchemaDescriptions, extractSchemaFieldNames };
132
174
 
133
175
  //# 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 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":";;;AAkBA,IAAM,kBAAkB,UAA0C,OAAO,UAAU,YAAY,UAAU;AAEzG,IAAM,sBAAsB,WAAiC;AAC3D,KAAI,EAAE,UAAU,QACd,QAAO;AAGT,KAAI,OAAO,OAAO,SAAS,SACzB,QAAO,OAAO;AAGhB,QAAO,MAAM,QAAQ,OAAO,KAAK,GAAG,OAAO,KAAK,KAAK,IAAI,GAAG;;;;;;AAO9D,SAAS,iBAAiB,KAAkE;AAC1F,KAAI,OAAO,QAAQ,YAAY,QAAQ,QAAQ,UAAU,IACvD,QAAO,eAAe,IAAI,cAAc,GAAG,IAAI,gBAAgB,KAAA;AAGjE,QAAO;;;;;AAMT,SAAS,eAAe,KAAa,KAAyC;CAC5E,IAAI,SAAS;CACb,MAAM,aAAa,IAAI,UAAU,SAAS,IAAI;AAC9C,WAAU,aAAa,eAAe;CACtC,MAAM,UAAU,IAAI,WAAW;AAC/B,KAAI,CAAC,QACH,QAAO;CAET,MAAM,WAAW,iBAAiB,QAAQ;AAE1C,KAAI,UAAU;AACZ,YAAU,mBAAmB,SAAS;AAEtC,MAAI,iBAAiB,YAAY,OAAO,SAAS,gBAAgB,SAC/D,WAAU,IAAI,SAAS;;AAI3B,QAAO;;;;;AAMT,SAAS,gBAAgB,KAAgC;CACvD,MAAM,UAAoB,CAAC,OAAO;CAClC,MAAM,SAAS,eAAe,KAAK,OAAO;AAE1C,KAAI,CAAC,UAAU,CAAC,eAAe,OAAO,IAAI,CAAC,OAAO,WAChD,QAAO;CAGT,MAAM,aAAa,OAAO;CAC1B,MAAM,kBAA8C;EAClD;EACA,UAAU,OAAO;EAClB;AACD,QAAO,KAAK,WAAW,CAAC,SAAS,QAAQ;AACvC,MAAI,CAAC,IAAI,OACP;AAGF,UAAQ,KAAK,eAAe,KAAK,gBAAgB,CAAC;EAElD,MAAM,UAAU,WAAW;AAC3B,MAAI,CAAC,QACH;EAEF,MAAM,WAAW,iBAAiB,QAAQ;AAC1C,MAAI,YAAY,eAAe,SAAS,IAAI,SAAS,YAAY;GAC/D,MAAM,mBAAmB,SAAS;AAClC,UAAO,KAAK,iBAAiB,CAAC,SAAS,WAAW;IAChD,MAAM,MAAM,iBAAiB;AAC7B,QAAI,CAAC,IACH;IAEF,MAAM,SAAS,iBAAiB,IAAI;IACpC,MAAM,UAAU,SAAS,mBAAmB,OAAO,GAAG;AACtD,YAAQ,KAAK,GAAG,OAAO,GAAG,UAAU;KACpC;;GAEJ;AAEF,QAAO;;;;;AAMT,SAAgB,mBAAmB,WAA6C;CAC9E,MAAM,UAAU,eAAe,WAAW,YAAY,EAAE;CACxD,MAAM,eAAe,OAAO,OAAO,WAAW,EAAE,CAAC;AACjD,KAAI,aAAa,WAAW,EAE1B,QAAO;AAGT,QAAO,aAAa,SAAS,UAAU,gBAAgB,MAAM,CAAC;;;;;AAMhE,SAAS,gBAAgB,OAAgC;CACvD,MAAM,SAAS,CAAC,MAAM,KAAK;AAC3B,QAAO,KAAK,MAAM,WAAW,aAAa,WAAW;AACrD,QAAO,KAAK,MAAM,GAAG;AAErB,KAAI,YAAY,SAAS,MAAM,QAAQ;EACrC,MAAM,SAAS,eAAe,MAAM,OAAO;AAC3C,MAAI,OACF,QAAO,KAAK,mBAAmB,OAAO,CAAC;;AAI3C,KAAI,MAAM,YACR,QAAO,KAAK,MAAM,YAAY;AAGhC,QAAO,OAAO,KAAK,IAAI;;;;;AAMzB,SAAgB,kBAAkB,YAA+D;AAC/F,QAAO,WAAW,KAAK,cAAc,gBAAgB,eAAe,UAAU,CAAC,CAAC;;;;;AAMlF,SAAgB,UAAU,QAA0B,QAA0B;AAC5E,MAAK,MAAM,CAAC,KAAK,QAAQ,OAAO,QAAQ,OAAO,CAC7C,KAAI,QAAQ,QAAQ,OAAO,QAAQ,UAAU;AAC3C,SAAO,SAAS,IAAI,IAAI,UAAU,aAAa;AAC/C,YAAU,KAAK,OAAO,KAAK;YAClB,OAAO,QAAQ,YACxB,QAAO,OAAO;AAIlB,QAAO;;;;;;AAOT,SAAgB,yBAAyB,sBAAiD;CACxF,MAAM,qBAAqB;EACzB,SAAS;EACT,MAAM;GACJ,OAAO;GACP,aAAa;GACb,gBAAgB;GAChB,SAAS;GACT,SAAS;IACP,MAAM;IACN,KAAK;IACN;GACD,SAAS,EACP,OAAO,IACR;GACF;EACD,SAAS,EAAE;EACX,MAAM,EAAE;EACR,mCAAmC;EACpC;AAED,KAAI,CAAC,qBACH,QAAO;AAGT,WAAU,sBAAsB,mBAAmB;AAEnD,QAAO"}
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 {\n MediaTypeObject,\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\nconst isSchemaObject = (value: unknown): value is SchemaObject => typeof value === 'object' && value !== null\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\nfunction pushUnique(target: string[], value: string | undefined): void {\n if (!value) {\n return\n }\n if (!target.includes(value)) {\n target.push(value)\n }\n}\n\ntype CollectOptions = {\n visit: (key: string, schema: SchemaObject | undefined) => void\n visited: Set<SchemaObject>\n maxPropertyDepth: number\n}\n\n/**\n * Recursively visits every property of a schema, descending transparently through composition\n * keywords (`oneOf`, `anyOf`, `allOf`) and one level into nested object properties.\n *\n * Composition is treated as transparent — a `oneOf` of two object variants is *the same level* as a\n * single object, just expressed as multiple shapes. Property nesting is capped to keep the index\n * focused on shallow, commonly-searched fields. A visited-set keyed by resolved-schema identity\n * guards against recursive (`Tree → Tree`) schemas.\n */\nfunction collectSchemaProperties(schema: SchemaObject | undefined, options: CollectOptions, propertyDepth = 0): void {\n if (!schema || options.visited.has(schema)) {\n return\n }\n options.visited.add(schema)\n\n const variants = [...(schema.oneOf ?? []), ...(schema.anyOf ?? []), ...(schema.allOf ?? [])]\n variants.forEach((variantRef) => {\n collectSchemaProperties(resolveSchemaRef(variantRef), options, propertyDepth)\n })\n\n if (isObjectSchema(schema) && schema.properties) {\n Object.entries(schema.properties).forEach(([key, propRef]) => {\n const property = resolveSchemaRef(propRef)\n options.visit(key, property)\n if (propertyDepth + 1 < options.maxPropertyDepth) {\n collectSchemaProperties(property, options, propertyDepth + 1)\n }\n })\n }\n}\n\n/**\n * Walks the request body schemas of an operation and yields each property schema with its key.\n */\nfunction forEachRequestBodyProperty(\n operation: OperationObject,\n visit: (key: string, schema: SchemaObject | undefined) => void,\n): void {\n const content = getResolvedRef(operation?.requestBody)?.content\n if (!content) {\n return\n }\n\n const visited = new Set<SchemaObject>()\n Object.values(content).forEach((media) => {\n const resolvedMedia = getResolvedRef(media) as MediaTypeObject | undefined\n const schema = getResolvedRef(resolvedMedia?.schema)\n collectSchemaProperties(schema, { visit, visited, maxPropertyDepth: 2 })\n })\n}\n\n/**\n * Extracts the names of every parameter on an operation.\n *\n * The returned strings contain only parameter names (e.g. `userId`, `limit`) so they can be indexed\n * as a high-signal field for search. Filter-style metadata like `REQUIRED`, `optional`, `query` and\n * the schema type are intentionally excluded — those tokens dilute fuzzy matches and produce false\n * positives for queries like `query` or `integer`.\n */\nexport function extractParameterNames(parameters: ReferenceType<ParameterObject>[]): string[] {\n const names: string[] = []\n\n parameters.forEach((parameter) => {\n const resolved = getResolvedRef(parameter)\n pushUnique(names, resolved?.name)\n })\n\n return names\n}\n\n/**\n * Extracts the descriptions of every parameter on an operation.\n *\n * Kept separate from parameter names so the search index can weight each independently.\n */\nexport function extractParameterDescriptions(parameters: ReferenceType<ParameterObject>[]): string[] {\n const descriptions: string[] = []\n\n parameters.forEach((parameter) => {\n const resolved = getResolvedRef(parameter)\n pushUnique(descriptions, resolved?.description)\n })\n\n return descriptions\n}\n\n/**\n * Extracts the names of properties from the request body schema(s) of an operation.\n *\n * Walks every media type and includes both top-level and one level of nested property names so\n * common fields like `email` or `username` surface in search regardless of how the body is shaped.\n */\nexport function extractBodyFieldNames(operation: OperationObject): string[] {\n const names: string[] = []\n\n forEachRequestBodyProperty(operation, (key) => {\n pushUnique(names, key)\n })\n\n return names\n}\n\n/**\n * Extracts the descriptions of properties from the request body schema(s) of an operation.\n */\nexport function extractBodyDescriptions(operation: OperationObject): string[] {\n const descriptions: string[] = []\n\n forEachRequestBodyProperty(operation, (_key, schema) => {\n if (schema && 'description' in schema && typeof schema.description === 'string') {\n pushUnique(descriptions, schema.description)\n }\n })\n\n return descriptions\n}\n\n/**\n * Extracts the property names of a schema for the search index.\n *\n * Same depth and composition behavior as `extractBodyFieldNames` — descends transparently through\n * `oneOf`/`anyOf`/`allOf`, walks one level into nested object properties, dedupes.\n */\nexport function extractSchemaFieldNames(schema: SchemaObject | undefined): string[] {\n const names: string[] = []\n collectSchemaProperties(schema, {\n visit: (key) => pushUnique(names, key),\n visited: new Set<SchemaObject>(),\n maxPropertyDepth: 2,\n })\n return names\n}\n\n/**\n * Extracts the property descriptions of a schema for the search index.\n */\nexport function extractSchemaDescriptions(schema: SchemaObject | undefined): string[] {\n const descriptions: string[] = []\n collectSchemaProperties(schema, {\n visit: (_key, propertySchema) => {\n if (propertySchema && 'description' in propertySchema && typeof propertySchema.description === 'string') {\n pushUnique(descriptions, propertySchema.description)\n }\n },\n visited: new Set<SchemaObject>(),\n maxPropertyDepth: 2,\n })\n return descriptions\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":";;;AAYA,IAAM,kBAAkB,UAA0C,OAAO,UAAU,YAAY,UAAU;;;;;AAMzG,SAAS,iBAAiB,KAAkE;AAC1F,KAAI,OAAO,QAAQ,YAAY,QAAQ,QAAQ,UAAU,IACvD,QAAO,eAAe,IAAI,cAAc,GAAG,IAAI,gBAAgB,KAAA;AAGjE,QAAO;;AAGT,SAAS,WAAW,QAAkB,OAAiC;AACrE,KAAI,CAAC,MACH;AAEF,KAAI,CAAC,OAAO,SAAS,MAAM,CACzB,QAAO,KAAK,MAAM;;;;;;;;;;;AAmBtB,SAAS,wBAAwB,QAAkC,SAAyB,gBAAgB,GAAS;AACnH,KAAI,CAAC,UAAU,QAAQ,QAAQ,IAAI,OAAO,CACxC;AAEF,SAAQ,QAAQ,IAAI,OAAO;AAEV;EAAC,GAAI,OAAO,SAAS,EAAE;EAAG,GAAI,OAAO,SAAS,EAAE;EAAG,GAAI,OAAO,SAAS,EAAE;EAAE,CACnF,SAAS,eAAe;AAC/B,0BAAwB,iBAAiB,WAAW,EAAE,SAAS,cAAc;GAC7E;AAEF,KAAI,eAAe,OAAO,IAAI,OAAO,WACnC,QAAO,QAAQ,OAAO,WAAW,CAAC,SAAS,CAAC,KAAK,aAAa;EAC5D,MAAM,WAAW,iBAAiB,QAAQ;AAC1C,UAAQ,MAAM,KAAK,SAAS;AAC5B,MAAI,gBAAgB,IAAI,QAAQ,iBAC9B,yBAAwB,UAAU,SAAS,gBAAgB,EAAE;GAE/D;;;;;AAON,SAAS,2BACP,WACA,OACM;CACN,MAAM,UAAU,eAAe,WAAW,YAAY,EAAE;AACxD,KAAI,CAAC,QACH;CAGF,MAAM,0BAAU,IAAI,KAAmB;AACvC,QAAO,OAAO,QAAQ,CAAC,SAAS,UAAU;AAGxC,0BADe,eADO,eAAe,MAAM,EACE,OAAO,EACpB;GAAE;GAAO;GAAS,kBAAkB;GAAG,CAAC;GACxE;;;;;;;;;;AAWJ,SAAgB,sBAAsB,YAAwD;CAC5F,MAAM,QAAkB,EAAE;AAE1B,YAAW,SAAS,cAAc;AAEhC,aAAW,OADM,eAAe,UAAU,EACd,KAAK;GACjC;AAEF,QAAO;;;;;;;AAQT,SAAgB,6BAA6B,YAAwD;CACnG,MAAM,eAAyB,EAAE;AAEjC,YAAW,SAAS,cAAc;AAEhC,aAAW,cADM,eAAe,UAAU,EACP,YAAY;GAC/C;AAEF,QAAO;;;;;;;;AAST,SAAgB,sBAAsB,WAAsC;CAC1E,MAAM,QAAkB,EAAE;AAE1B,4BAA2B,YAAY,QAAQ;AAC7C,aAAW,OAAO,IAAI;GACtB;AAEF,QAAO;;;;;AAMT,SAAgB,wBAAwB,WAAsC;CAC5E,MAAM,eAAyB,EAAE;AAEjC,4BAA2B,YAAY,MAAM,WAAW;AACtD,MAAI,UAAU,iBAAiB,UAAU,OAAO,OAAO,gBAAgB,SACrE,YAAW,cAAc,OAAO,YAAY;GAE9C;AAEF,QAAO;;;;;;;;AAST,SAAgB,wBAAwB,QAA4C;CAClF,MAAM,QAAkB,EAAE;AAC1B,yBAAwB,QAAQ;EAC9B,QAAQ,QAAQ,WAAW,OAAO,IAAI;EACtC,yBAAS,IAAI,KAAmB;EAChC,kBAAkB;EACnB,CAAC;AACF,QAAO;;;;;AAMT,SAAgB,0BAA0B,QAA4C;CACpF,MAAM,eAAyB,EAAE;AACjC,yBAAwB,QAAQ;EAC9B,QAAQ,MAAM,mBAAmB;AAC/B,OAAI,kBAAkB,iBAAiB,kBAAkB,OAAO,eAAe,gBAAgB,SAC7F,YAAW,cAAc,eAAe,YAAY;;EAGxD,yBAAS,IAAI,KAAmB;EAChC,kBAAkB;EACnB,CAAC;AACF,QAAO;;;;;AAMT,SAAgB,UAAU,QAA0B,QAA0B;AAC5E,MAAK,MAAM,CAAC,KAAK,QAAQ,OAAO,QAAQ,OAAO,CAC7C,KAAI,QAAQ,QAAQ,OAAO,QAAQ,UAAU;AAC3C,SAAO,SAAS,IAAI,IAAI,UAAU,aAAa;AAC/C,YAAU,KAAK,OAAO,KAAK;YAClB,OAAO,QAAQ,YACxB,QAAO,OAAO;AAIlB,QAAO;;;;;;AAOT,SAAgB,yBAAyB,sBAAiD;CACxF,MAAM,qBAAqB;EACzB,SAAS;EACT,MAAM;GACJ,OAAO;GACP,aAAa;GACb,gBAAgB;GAChB,SAAS;GACT,SAAS;IACP,MAAM;IACN,KAAK;IACN;GACD,SAAS,EACP,OAAO,IACR;GACF;EACD,SAAS,EAAE;EACX,MAAM,EAAE;EACR,mCAAmC;EACpC;AAED,KAAI,CAAC,qBACH,QAAO;AAGT,WAAU,sBAAsB,mBAAmB;AAEnD,QAAO"}
@@ -1 +1 @@
1
- {"version":3,"file":"html-api.d.ts","sourceRoot":"","sources":["../../../src/standalone/lib/html-api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,mCAAmC,EACnC,kBAAkB,EACnB,MAAM,6BAA6B,CAAA;AASpC;;GAEG;AACH,wBAAgB,kCAAkC,CAAC,GAAG,EAAE,QAAQ,GAAG,mCAAmC,CA+GrG;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,QAAQ,EAAE,aAAa,EAAE,mCAAmC,QAiBnG;AAID,eAAO,MAAM,eAAe,GAAI,KAAK,QAAQ,EAAE,UAAU,OAAO,GAAG,IAAI,mBAatE,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,EAAE,kBA4HhC,CAAA"}
1
+ {"version":3,"file":"html-api.d.ts","sourceRoot":"","sources":["../../../src/standalone/lib/html-api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,mCAAmC,EACnC,kBAAkB,EACnB,MAAM,6BAA6B,CAAA;AASpC;;GAEG;AACH,wBAAgB,kCAAkC,CAAC,GAAG,EAAE,QAAQ,GAAG,mCAAmC,CA+GrG;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,QAAQ,EAAE,aAAa,EAAE,mCAAmC,QAiBnG;AAID,eAAO,MAAM,eAAe,GAAI,KAAK,QAAQ,EAAE,UAAU,OAAO,GAAG,IAAI,mBAatE,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,EAAE,kBAuIhC,CAAA"}
@@ -1,6 +1,6 @@
1
1
  import ApiReference_default from "../../components/ApiReference.vue.js";
2
2
  import { createApp, createSSRApp, h, reactive } from "vue";
3
- import "@scalar/types/api-reference";
3
+ import "@scalar/schemas/api-reference";
4
4
  import { createHead } from "@unhead/vue/client";
5
5
  //#region src/standalone/lib/html-api.ts
6
6
  /**
@@ -23,6 +23,11 @@ var createApiReference = (elementOrSelectorOrConfig, optionalConfiguration) => {
23
23
  let app = createReferenceApp(!!optionalConfiguration && !!mountElement && mountElement.children.length > 0);
24
24
  if (optionalConfiguration) if (mountElement) app.mount(mountElement);
25
25
  else console.error("Could not find a mount point for API References:", elementOrSelectorOrConfig);
26
+ const abortController = new AbortController();
27
+ const listenerOptions = {
28
+ capture: false,
29
+ signal: abortController.signal
30
+ };
26
31
  /**
27
32
  * Reload the API Reference
28
33
  * @deprecated
@@ -36,9 +41,10 @@ var createApiReference = (elementOrSelectorOrConfig, optionalConfiguration) => {
36
41
  app.unmount();
37
42
  app = createReferenceApp();
38
43
  app.mount(currentElement);
39
- }, false);
44
+ }, listenerOptions);
40
45
  /** Destroy the current API Reference instance */
41
46
  const destroy = () => {
47
+ abortController.abort();
42
48
  props.configuration = {};
43
49
  app.unmount();
44
50
  };
@@ -49,7 +55,7 @@ var createApiReference = (elementOrSelectorOrConfig, optionalConfiguration) => {
49
55
  document.addEventListener("scalar:destroy-references", () => {
50
56
  console.warn("scalar:destroy-references event has been deprecated, please use scalarInstance.destroy instead.");
51
57
  destroy();
52
- }, false);
58
+ }, listenerOptions);
53
59
  /**
54
60
  * Allow user to update configuration
55
61
  * @deprecated
@@ -57,7 +63,7 @@ var createApiReference = (elementOrSelectorOrConfig, optionalConfiguration) => {
57
63
  document.addEventListener("scalar:update-references-config", (ev) => {
58
64
  console.warn("scalar:update-references-config event has been deprecated, please use scalarInstance.updateConfiguration instead.");
59
65
  if ("detail" in ev) Object.assign(props, ev.detail);
60
- }, false);
66
+ }, listenerOptions);
61
67
  return {
62
68
  app,
63
69
  getConfiguration: () => props.configuration ?? {},
@@ -1 +1 @@
1
- {"version":3,"file":"html-api.js","names":[],"sources":["../../../src/standalone/lib/html-api.ts"],"sourcesContent":["import type {\n AnyApiReferenceConfiguration,\n ApiReferenceConfigurationWithSource,\n CreateApiReference,\n} from '@scalar/types/api-reference'\nimport { apiReferenceConfigurationWithSourceSchema } from '@scalar/types/api-reference'\nimport { createHead } from '@unhead/vue/client'\nimport { createApp, createSSRApp, h, reactive } from 'vue'\n\nimport { default as ApiReference } from '@/components/ApiReference.vue'\n\nconst getSpecScriptTag = (doc: Document) => doc.getElementById('api-reference')\n\n/**\n * Reading the configuration from the data-attributes.\n */\nexport function getConfigurationFromDataAttributes(doc: Document): ApiReferenceConfigurationWithSource {\n const specElement = doc.querySelector('[data-spec]')\n const specUrlElement = doc.querySelector('[data-spec-url]')\n const configurationScriptElement = doc.querySelector('#api-reference[data-configuration]')\n\n const getConfiguration = () => {\n // <script data-configuration=\"{ … }\" />\n if (configurationScriptElement) {\n const configurationFromElement = configurationScriptElement.getAttribute('data-configuration')\n\n if (configurationFromElement) {\n return {\n _integration: 'html',\n ...JSON.parse(configurationFromElement.split('&quot;').join('\"')),\n }\n }\n }\n\n return apiReferenceConfigurationWithSourceSchema.parse({ _integration: 'html' })\n }\n\n const getUrl = () => {\n // Let's first check if the user passed a spec URL in the configuration.\n if (getConfiguration().url) {\n return getConfiguration().url\n }\n\n if (getConfiguration().spec?.url) {\n return getConfiguration().spec?.url\n }\n\n // <script id=\"api-reference\" data-url=\"/scalar.json\" />\n const specScriptTag = getSpecScriptTag(doc)\n if (specScriptTag) {\n const urlFromScriptTag = specScriptTag.getAttribute('data-url')?.trim()\n\n if (urlFromScriptTag) {\n return urlFromScriptTag\n }\n }\n\n // <div data-spec-url=\"/scalar.json\" />\n if (specUrlElement) {\n console.warn(\n '[@scalar/api-reference] The [data-spec-url] HTML API is deprecated. Use the new <script id=\"api-reference\" data-url=\"/scalar.json\" /> API instead.',\n )\n const urlFromSpecUrlElement = specUrlElement.getAttribute('data-spec-url')\n\n if (urlFromSpecUrlElement) {\n return urlFromSpecUrlElement\n }\n }\n\n return undefined\n }\n\n const getContent = (): string | undefined => {\n // <script id=\"api-reference\" type=\"application/json\">{\"openapi\":\"3.1.0\",\"info\":{\"title\":\"Example\"},\"paths\":{}}</script>\n const specScriptTag = getSpecScriptTag(doc)\n if (specScriptTag) {\n const specFromScriptTag = specScriptTag.innerHTML?.trim()\n\n if (specFromScriptTag) {\n return specFromScriptTag\n }\n }\n\n // <div data-spec='{\"openapi\":\"3.1.0\",\"info\":{\"title\":\"Example\"},\"paths\":{}}' />\n if (specElement) {\n console.warn(\n '[@scalar/api-reference] The [data-spec] HTML API is deprecated. Use the new <script id=\"api-reference\" type=\"application/json\">{\"openapi\":\"3.1.0\",\"info\":{\"title\":\"Example\"},\"paths\":{}}</script> API instead.',\n )\n const specFromSpecElement = specElement.getAttribute('data-spec')?.trim()\n\n if (specFromSpecElement) {\n return specFromSpecElement\n }\n }\n\n return undefined\n }\n\n const getProxyUrl = () => {\n // <script id=\"api-reference\" data-proxy-url=\"https://proxy.scalar.com\">…</script>\n const specScriptTag = getSpecScriptTag(doc)\n if (specScriptTag) {\n const proxyUrl = specScriptTag.getAttribute('data-proxy-url')\n\n if (proxyUrl) {\n return proxyUrl.trim()\n }\n }\n\n return undefined\n }\n\n // Ensure Reference Props are reactive\n if (!specUrlElement && !specElement && !getSpecScriptTag(doc)) {\n // Stay quiet.\n } else {\n const urlOrContent = getContent() ? { content: getContent() } : { url: getUrl() }\n\n return apiReferenceConfigurationWithSourceSchema.parse({\n _integration: 'html',\n proxyUrl: getProxyUrl(),\n ...getConfiguration(),\n ...urlOrContent,\n })\n }\n\n return apiReferenceConfigurationWithSourceSchema.parse({ _integration: 'html' })\n}\n\n/**\n * Mount the Scalar API Reference on a given document.\n * Read the HTML data-attributes for configuration.\n */\nexport function findDataAttributes(doc: Document, configuration: ApiReferenceConfigurationWithSource) {\n /** @deprecated Use the new <script id=\"api-reference\" data-url=\"/scalar.json\" /> API instead. */\n const specElement = doc.querySelector('[data-spec]')\n /** @deprecated Use the new <script id=\"api-reference\" data-url=\"/scalar.json\" /> API instead. */\n const specUrlElement = doc.querySelector('[data-spec-url]')\n\n if (configuration?.darkMode) {\n doc.body?.classList.add('dark-mode')\n } else {\n doc.body?.classList.add('light-mode')\n }\n\n const container = createContainer(doc, specElement || specUrlElement)\n\n if (container) {\n createApiReference(container, configuration)\n }\n}\n\n// If it's a script tag, we can't mount the Vue.js app inside that tag.\n// We need to add a new container element before the script tag.\nexport const createContainer = (doc: Document, element?: Element | null) => {\n let _container: Element | null = null\n\n const specScriptTag = getSpecScriptTag(doc)\n\n if (specScriptTag) {\n _container = doc.createElement('div')\n specScriptTag?.parentNode?.insertBefore(_container, specScriptTag)\n } else if (element) {\n _container = element\n }\n\n return _container\n}\n\n/**\n * Create (and mount) a new Scalar API Reference\n *\n * @example createApiReference({ url: '/scalar.json' }).mount('#app')\n * @example createApiReference('#app', { url: '/scalar.json' })\n * @example createApiReference(document.getElementById('app'), { url: '/scalar.json' })\n */\nexport const createApiReference: CreateApiReference = (\n elementOrSelectorOrConfig,\n optionalConfiguration?: AnyApiReferenceConfiguration,\n) => {\n // Create an id prefix for useId so we don't have collisions with other Vue apps\n const idPrefix = 'scalar-refs'\n\n const props = reactive<{ configuration: AnyApiReferenceConfiguration }>({\n // Either the configuration will be the second argument or it MUST be the first (configuration only)\n configuration: optionalConfiguration ?? (elementOrSelectorOrConfig as AnyApiReferenceConfiguration) ?? {},\n })\n\n const createReferenceApp = (isSsr = false) => {\n const referenceApp = isSsr ? createSSRApp(() => h(ApiReference, props)) : createApp(() => h(ApiReference, props))\n\n // Meta tags, etc.\n referenceApp.use(createHead())\n referenceApp.config.idPrefix = idPrefix\n\n return referenceApp\n }\n\n // If we have an optional config, then we must mount the element immediately (not sure why type is not narrowing)\n const mountElement = optionalConfiguration\n ? typeof elementOrSelectorOrConfig === 'string'\n ? document.querySelector(elementOrSelectorOrConfig)\n : (elementOrSelectorOrConfig as Element)\n : null\n\n // Detect server-rendered content and use createSSRApp for hydration\n const shouldHydrate = !!optionalConfiguration && !!mountElement && mountElement.children.length > 0\n let app = createReferenceApp(shouldHydrate)\n\n if (optionalConfiguration) {\n if (mountElement) {\n app.mount(mountElement)\n } else {\n console.error('Could not find a mount point for API References:', elementOrSelectorOrConfig)\n }\n }\n\n /**\n * Reload the API Reference\n * @deprecated\n */\n document.addEventListener(\n 'scalar:reload-references',\n () => {\n console.warn(\n 'scalar:reload-references event has been deprecated, please use the scalarInstance.app.mount method instead.',\n )\n if (!props.configuration) {\n return\n }\n\n // Snag the current element\n const currentElement =\n typeof elementOrSelectorOrConfig === 'string'\n ? document.querySelector(elementOrSelectorOrConfig)\n : (elementOrSelectorOrConfig as Element)\n\n if (!currentElement) {\n return\n }\n\n // Ensure we re-attach the element if it was unmounted\n if (currentElement && !document.body.contains(currentElement)) {\n document.body.appendChild(currentElement)\n }\n\n // Create a new Vue app instance\n app.unmount()\n app = createReferenceApp()\n app.mount(currentElement)\n },\n false,\n )\n\n /** Destroy the current API Reference instance */\n const destroy = () => {\n props.configuration = {}\n app.unmount()\n }\n\n /**\n * Allow user to destroy the API Reference\n * @deprecated\n */\n document.addEventListener(\n 'scalar:destroy-references',\n () => {\n console.warn('scalar:destroy-references event has been deprecated, please use scalarInstance.destroy instead.')\n destroy()\n },\n false,\n )\n\n /**\n * Allow user to update configuration\n * @deprecated\n */\n document.addEventListener(\n 'scalar:update-references-config',\n (ev) => {\n console.warn(\n 'scalar:update-references-config event has been deprecated, please use scalarInstance.updateConfiguration instead.',\n )\n if ('detail' in ev) {\n Object.assign(props, ev.detail)\n }\n },\n false,\n )\n\n const instance = {\n app,\n getConfiguration: () => props.configuration ?? {},\n updateConfiguration: (newConfig: AnyApiReferenceConfiguration) => {\n props.configuration = newConfig\n },\n destroy,\n }\n\n return instance\n}\n"],"mappings":";;;;;;;;;;;;AAgLA,IAAa,sBACX,2BACA,0BACG;CAEH,MAAM,WAAW;CAEjB,MAAM,QAAQ,SAA0D,EAEtE,eAAe,yBAA0B,6BAA8D,EAAE,EAC1G,CAAC;CAEF,MAAM,sBAAsB,QAAQ,UAAU;EAC5C,MAAM,eAAe,QAAQ,mBAAmB,EAAE,sBAAc,MAAM,CAAC,GAAG,gBAAgB,EAAE,sBAAc,MAAM,CAAC;AAGjH,eAAa,IAAI,YAAY,CAAC;AAC9B,eAAa,OAAO,WAAW;AAE/B,SAAO;;CAIT,MAAM,eAAe,wBACjB,OAAO,8BAA8B,WACnC,SAAS,cAAc,0BAA0B,GAChD,4BACH;CAIJ,IAAI,MAAM,mBADY,CAAC,CAAC,yBAAyB,CAAC,CAAC,gBAAgB,aAAa,SAAS,SAAS,EACvD;AAE3C,KAAI,sBACF,KAAI,aACF,KAAI,MAAM,aAAa;KAEvB,SAAQ,MAAM,oDAAoD,0BAA0B;;;;;AAQhG,UAAS,iBACP,kCACM;AACJ,UAAQ,KACN,8GACD;AACD,MAAI,CAAC,MAAM,cACT;EAIF,MAAM,iBACJ,OAAO,8BAA8B,WACjC,SAAS,cAAc,0BAA0B,GAChD;AAEP,MAAI,CAAC,eACH;AAIF,MAAI,kBAAkB,CAAC,SAAS,KAAK,SAAS,eAAe,CAC3D,UAAS,KAAK,YAAY,eAAe;AAI3C,MAAI,SAAS;AACb,QAAM,oBAAoB;AAC1B,MAAI,MAAM,eAAe;IAE3B,MACD;;CAGD,MAAM,gBAAgB;AACpB,QAAM,gBAAgB,EAAE;AACxB,MAAI,SAAS;;;;;;AAOf,UAAS,iBACP,mCACM;AACJ,UAAQ,KAAK,kGAAkG;AAC/G,WAAS;IAEX,MACD;;;;;AAMD,UAAS,iBACP,oCACC,OAAO;AACN,UAAQ,KACN,oHACD;AACD,MAAI,YAAY,GACd,QAAO,OAAO,OAAO,GAAG,OAAO;IAGnC,MACD;AAWD,QATiB;EACf;EACA,wBAAwB,MAAM,iBAAiB,EAAE;EACjD,sBAAsB,cAA4C;AAChE,SAAM,gBAAgB;;EAExB;EACD"}
1
+ {"version":3,"file":"html-api.js","names":[],"sources":["../../../src/standalone/lib/html-api.ts"],"sourcesContent":["import type {\n AnyApiReferenceConfiguration,\n ApiReferenceConfigurationWithSource,\n CreateApiReference,\n} from '@scalar/types/api-reference'\nimport { apiReferenceConfigurationWithSourceSchema } from '@scalar/schemas/api-reference'\nimport { createHead } from '@unhead/vue/client'\nimport { createApp, createSSRApp, h, reactive } from 'vue'\n\nimport { default as ApiReference } from '@/components/ApiReference.vue'\n\nconst getSpecScriptTag = (doc: Document) => doc.getElementById('api-reference')\n\n/**\n * Reading the configuration from the data-attributes.\n */\nexport function getConfigurationFromDataAttributes(doc: Document): ApiReferenceConfigurationWithSource {\n const specElement = doc.querySelector('[data-spec]')\n const specUrlElement = doc.querySelector('[data-spec-url]')\n const configurationScriptElement = doc.querySelector('#api-reference[data-configuration]')\n\n const getConfiguration = () => {\n // <script data-configuration=\"{ … }\" />\n if (configurationScriptElement) {\n const configurationFromElement = configurationScriptElement.getAttribute('data-configuration')\n\n if (configurationFromElement) {\n return {\n _integration: 'html',\n ...JSON.parse(configurationFromElement.split('&quot;').join('\"')),\n }\n }\n }\n\n return apiReferenceConfigurationWithSourceSchema({ _integration: 'html' })\n }\n\n const getUrl = () => {\n // Let's first check if the user passed a spec URL in the configuration.\n if (getConfiguration().url) {\n return getConfiguration().url\n }\n\n if (getConfiguration().spec?.url) {\n return getConfiguration().spec?.url\n }\n\n // <script id=\"api-reference\" data-url=\"/scalar.json\" />\n const specScriptTag = getSpecScriptTag(doc)\n if (specScriptTag) {\n const urlFromScriptTag = specScriptTag.getAttribute('data-url')?.trim()\n\n if (urlFromScriptTag) {\n return urlFromScriptTag\n }\n }\n\n // <div data-spec-url=\"/scalar.json\" />\n if (specUrlElement) {\n console.warn(\n '[@scalar/api-reference] The [data-spec-url] HTML API is deprecated. Use the new <script id=\"api-reference\" data-url=\"/scalar.json\" /> API instead.',\n )\n const urlFromSpecUrlElement = specUrlElement.getAttribute('data-spec-url')\n\n if (urlFromSpecUrlElement) {\n return urlFromSpecUrlElement\n }\n }\n\n return undefined\n }\n\n const getContent = (): string | undefined => {\n // <script id=\"api-reference\" type=\"application/json\">{\"openapi\":\"3.1.0\",\"info\":{\"title\":\"Example\"},\"paths\":{}}</script>\n const specScriptTag = getSpecScriptTag(doc)\n if (specScriptTag) {\n const specFromScriptTag = specScriptTag.innerHTML?.trim()\n\n if (specFromScriptTag) {\n return specFromScriptTag\n }\n }\n\n // <div data-spec='{\"openapi\":\"3.1.0\",\"info\":{\"title\":\"Example\"},\"paths\":{}}' />\n if (specElement) {\n console.warn(\n '[@scalar/api-reference] The [data-spec] HTML API is deprecated. Use the new <script id=\"api-reference\" type=\"application/json\">{\"openapi\":\"3.1.0\",\"info\":{\"title\":\"Example\"},\"paths\":{}}</script> API instead.',\n )\n const specFromSpecElement = specElement.getAttribute('data-spec')?.trim()\n\n if (specFromSpecElement) {\n return specFromSpecElement\n }\n }\n\n return undefined\n }\n\n const getProxyUrl = () => {\n // <script id=\"api-reference\" data-proxy-url=\"https://proxy.scalar.com\">…</script>\n const specScriptTag = getSpecScriptTag(doc)\n if (specScriptTag) {\n const proxyUrl = specScriptTag.getAttribute('data-proxy-url')\n\n if (proxyUrl) {\n return proxyUrl.trim()\n }\n }\n\n return undefined\n }\n\n // Ensure Reference Props are reactive\n if (!specUrlElement && !specElement && !getSpecScriptTag(doc)) {\n // Stay quiet.\n } else {\n const urlOrContent = getContent() ? { content: getContent() } : { url: getUrl() }\n\n return apiReferenceConfigurationWithSourceSchema({\n _integration: 'html',\n proxyUrl: getProxyUrl(),\n ...getConfiguration(),\n ...urlOrContent,\n })\n }\n\n return apiReferenceConfigurationWithSourceSchema({ _integration: 'html' })\n}\n\n/**\n * Mount the Scalar API Reference on a given document.\n * Read the HTML data-attributes for configuration.\n */\nexport function findDataAttributes(doc: Document, configuration: ApiReferenceConfigurationWithSource) {\n /** @deprecated Use the new <script id=\"api-reference\" data-url=\"/scalar.json\" /> API instead. */\n const specElement = doc.querySelector('[data-spec]')\n /** @deprecated Use the new <script id=\"api-reference\" data-url=\"/scalar.json\" /> API instead. */\n const specUrlElement = doc.querySelector('[data-spec-url]')\n\n if (configuration?.darkMode) {\n doc.body?.classList.add('dark-mode')\n } else {\n doc.body?.classList.add('light-mode')\n }\n\n const container = createContainer(doc, specElement || specUrlElement)\n\n if (container) {\n createApiReference(container, configuration)\n }\n}\n\n// If it's a script tag, we can't mount the Vue.js app inside that tag.\n// We need to add a new container element before the script tag.\nexport const createContainer = (doc: Document, element?: Element | null) => {\n let _container: Element | null = null\n\n const specScriptTag = getSpecScriptTag(doc)\n\n if (specScriptTag) {\n _container = doc.createElement('div')\n specScriptTag?.parentNode?.insertBefore(_container, specScriptTag)\n } else if (element) {\n _container = element\n }\n\n return _container\n}\n\n/**\n * Create (and mount) a new Scalar API Reference\n *\n * @example createApiReference({ url: '/scalar.json' }).mount('#app')\n * @example createApiReference('#app', { url: '/scalar.json' })\n * @example createApiReference(document.getElementById('app'), { url: '/scalar.json' })\n */\nexport const createApiReference: CreateApiReference = (\n elementOrSelectorOrConfig,\n optionalConfiguration?: AnyApiReferenceConfiguration,\n) => {\n // Create an id prefix for useId so we don't have collisions with other Vue apps\n const idPrefix = 'scalar-refs'\n\n const props = reactive<{ configuration: AnyApiReferenceConfiguration }>({\n // Either the configuration will be the second argument or it MUST be the first (configuration only)\n configuration: optionalConfiguration ?? (elementOrSelectorOrConfig as AnyApiReferenceConfiguration) ?? {},\n })\n\n const createReferenceApp = (isSsr = false) => {\n const referenceApp = isSsr ? createSSRApp(() => h(ApiReference, props)) : createApp(() => h(ApiReference, props))\n\n // Meta tags, etc.\n referenceApp.use(createHead())\n referenceApp.config.idPrefix = idPrefix\n\n return referenceApp\n }\n\n // If we have an optional config, then we must mount the element immediately (not sure why type is not narrowing)\n const mountElement = optionalConfiguration\n ? typeof elementOrSelectorOrConfig === 'string'\n ? document.querySelector(elementOrSelectorOrConfig)\n : (elementOrSelectorOrConfig as Element)\n : null\n\n // Detect server-rendered content and use createSSRApp for hydration\n const shouldHydrate = !!optionalConfiguration && !!mountElement && mountElement.children.length > 0\n let app = createReferenceApp(shouldHydrate)\n\n if (optionalConfiguration) {\n if (mountElement) {\n app.mount(mountElement)\n } else {\n console.error('Could not find a mount point for API References:', elementOrSelectorOrConfig)\n }\n }\n\n // Tie the deprecated `document` listeners to an AbortController so `destroy`\n // can remove them all at once. Without this, every `createApiReference()`\n // call leaks three permanent listeners — visible during Astro view\n // transitions where each navigation creates a new instance.\n const abortController = new AbortController()\n const listenerOptions: AddEventListenerOptions = {\n capture: false,\n signal: abortController.signal,\n }\n\n /**\n * Reload the API Reference\n * @deprecated\n */\n document.addEventListener(\n 'scalar:reload-references',\n () => {\n console.warn(\n 'scalar:reload-references event has been deprecated, please use the scalarInstance.app.mount method instead.',\n )\n if (!props.configuration) {\n return\n }\n\n // Snag the current element\n const currentElement =\n typeof elementOrSelectorOrConfig === 'string'\n ? document.querySelector(elementOrSelectorOrConfig)\n : (elementOrSelectorOrConfig as Element)\n\n if (!currentElement) {\n return\n }\n\n // Ensure we re-attach the element if it was unmounted\n if (currentElement && !document.body.contains(currentElement)) {\n document.body.appendChild(currentElement)\n }\n\n // Create a new Vue app instance\n app.unmount()\n app = createReferenceApp()\n app.mount(currentElement)\n },\n listenerOptions,\n )\n\n /** Destroy the current API Reference instance */\n const destroy = () => {\n abortController.abort()\n props.configuration = {}\n app.unmount()\n }\n\n /**\n * Allow user to destroy the API Reference\n * @deprecated\n */\n document.addEventListener(\n 'scalar:destroy-references',\n () => {\n console.warn('scalar:destroy-references event has been deprecated, please use scalarInstance.destroy instead.')\n destroy()\n },\n listenerOptions,\n )\n\n /**\n * Allow user to update configuration\n * @deprecated\n */\n document.addEventListener(\n 'scalar:update-references-config',\n (ev) => {\n console.warn(\n 'scalar:update-references-config event has been deprecated, please use scalarInstance.updateConfiguration instead.',\n )\n if ('detail' in ev) {\n Object.assign(props, ev.detail)\n }\n },\n listenerOptions,\n )\n\n const instance = {\n app,\n getConfiguration: () => props.configuration ?? {},\n updateConfiguration: (newConfig: AnyApiReferenceConfiguration) => {\n props.configuration = newConfig\n },\n destroy,\n }\n\n return instance\n}\n"],"mappings":";;;;;;;;;;;;AAgLA,IAAa,sBACX,2BACA,0BACG;CAEH,MAAM,WAAW;CAEjB,MAAM,QAAQ,SAA0D,EAEtE,eAAe,yBAA0B,6BAA8D,EAAE,EAC1G,CAAC;CAEF,MAAM,sBAAsB,QAAQ,UAAU;EAC5C,MAAM,eAAe,QAAQ,mBAAmB,EAAE,sBAAc,MAAM,CAAC,GAAG,gBAAgB,EAAE,sBAAc,MAAM,CAAC;AAGjH,eAAa,IAAI,YAAY,CAAC;AAC9B,eAAa,OAAO,WAAW;AAE/B,SAAO;;CAIT,MAAM,eAAe,wBACjB,OAAO,8BAA8B,WACnC,SAAS,cAAc,0BAA0B,GAChD,4BACH;CAIJ,IAAI,MAAM,mBADY,CAAC,CAAC,yBAAyB,CAAC,CAAC,gBAAgB,aAAa,SAAS,SAAS,EACvD;AAE3C,KAAI,sBACF,KAAI,aACF,KAAI,MAAM,aAAa;KAEvB,SAAQ,MAAM,oDAAoD,0BAA0B;CAQhG,MAAM,kBAAkB,IAAI,iBAAiB;CAC7C,MAAM,kBAA2C;EAC/C,SAAS;EACT,QAAQ,gBAAgB;EACzB;;;;;AAMD,UAAS,iBACP,kCACM;AACJ,UAAQ,KACN,8GACD;AACD,MAAI,CAAC,MAAM,cACT;EAIF,MAAM,iBACJ,OAAO,8BAA8B,WACjC,SAAS,cAAc,0BAA0B,GAChD;AAEP,MAAI,CAAC,eACH;AAIF,MAAI,kBAAkB,CAAC,SAAS,KAAK,SAAS,eAAe,CAC3D,UAAS,KAAK,YAAY,eAAe;AAI3C,MAAI,SAAS;AACb,QAAM,oBAAoB;AAC1B,MAAI,MAAM,eAAe;IAE3B,gBACD;;CAGD,MAAM,gBAAgB;AACpB,kBAAgB,OAAO;AACvB,QAAM,gBAAgB,EAAE;AACxB,MAAI,SAAS;;;;;;AAOf,UAAS,iBACP,mCACM;AACJ,UAAQ,KAAK,kGAAkG;AAC/G,WAAS;IAEX,gBACD;;;;;AAMD,UAAS,iBACP,oCACC,OAAO;AACN,UAAQ,KACN,oHACD;AACD,MAAI,YAAY,GACd,QAAO,OAAO,OAAO,GAAG,OAAO;IAGnC,gBACD;AAWD,QATiB;EACf;EACA,wBAAwB,MAAM,iBAAiB,EAAE;EACjD,sBAAsB,cAA4C;AAChE,SAAM,gBAAgB;;EAExB;EACD"}