@scalar/import 0.3.23 → 0.3.24

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 CHANGED
@@ -1,5 +1,14 @@
1
1
  # @scalar/import
2
2
 
3
+ ## 0.3.24
4
+
5
+ ### Patch Changes
6
+
7
+ - 8c7bad8: chore: move build tooling to esbuild
8
+ - Updated dependencies [8c7bad8]
9
+ - @scalar/openapi-parser@0.10.17
10
+ - @scalar/oas-utils@0.2.141
11
+
3
12
  ## 0.3.23
4
13
 
5
14
  ### Patch Changes
@@ -0,0 +1,33 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { getConfigurationAttribute } from "./resolve.js";
3
+ describe("getConfigurationAttribute", () => {
4
+ it("returns the configuration attribute with double quotes", () => {
5
+ const html = `<script id="api-reference" data-configuration="{&quot;spec&quot;:{&quot;content&quot;:&quot;foo&quot;}}"><\/script>`;
6
+ const result = getConfigurationAttribute(html);
7
+ expect(result).toBe("{&quot;spec&quot;:{&quot;content&quot;:&quot;foo&quot;}}");
8
+ });
9
+ it("returns the configuration attribute with single quotes", () => {
10
+ const html = `<script id='api-reference' data-configuration='{&quot;spec&quot;:{&quot;content&quot;:&quot;foo&quot;}}'><\/script>`;
11
+ const result = getConfigurationAttribute(html);
12
+ expect(result).toBe("{&quot;spec&quot;:{&quot;content&quot;:&quot;foo&quot;}}");
13
+ });
14
+ it("returns undefined if no configuration attribute is present", () => {
15
+ const html = `<script id="api-reference"><\/script>`;
16
+ const result = getConfigurationAttribute(html);
17
+ expect(result).toBeUndefined();
18
+ });
19
+ it("returns undefined for non-matching script tags", () => {
20
+ const html = `<script data-other-attribute="value" data-configuration="{&quot;spec&quot;:{&quot;content&quot;:&quot;foo&quot;}}"><\/script>`;
21
+ const result = getConfigurationAttribute(html);
22
+ expect(result).toBeUndefined();
23
+ });
24
+ it("handles multiple script tags and returns the first match", () => {
25
+ const html = `
26
+ <script id="api-reference" data-configuration="{&quot;spec&quot;:{&quot;content&quot;:&quot;first&quot;}}"><\/script>
27
+ <script id="api-reference" data-configuration="{&quot;spec&quot;:{&quot;content&quot;:&quot;second&quot;}}"><\/script>
28
+ `;
29
+ const result = getConfigurationAttribute(html);
30
+ expect(result).toBe("{&quot;spec&quot;:{&quot;content&quot;:&quot;first&quot;}}");
31
+ });
32
+ });
33
+ //# sourceMappingURL=get-configuration-attribute.test.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/get-configuration-attribute.test.ts"],
4
+ "sourcesContent": ["import { describe, expect, it } from 'vitest'\n\nimport { getConfigurationAttribute } from './resolve'\n\ndescribe('getConfigurationAttribute', () => {\n it('returns the configuration attribute with double quotes', () => {\n const html = `<script id=\"api-reference\" data-configuration=\"{&quot;spec&quot;:{&quot;content&quot;:&quot;foo&quot;}}\"></script>`\n const result = getConfigurationAttribute(html)\n expect(result).toBe('{&quot;spec&quot;:{&quot;content&quot;:&quot;foo&quot;}}')\n })\n\n it('returns the configuration attribute with single quotes', () => {\n const html = `<script id='api-reference' data-configuration='{&quot;spec&quot;:{&quot;content&quot;:&quot;foo&quot;}}'></script>`\n const result = getConfigurationAttribute(html)\n expect(result).toBe('{&quot;spec&quot;:{&quot;content&quot;:&quot;foo&quot;}}')\n })\n\n it('returns undefined if no configuration attribute is present', () => {\n const html = `<script id=\"api-reference\"></script>`\n const result = getConfigurationAttribute(html)\n expect(result).toBeUndefined()\n })\n\n it('returns undefined for non-matching script tags', () => {\n const html = `<script data-other-attribute=\"value\" data-configuration=\"{&quot;spec&quot;:{&quot;content&quot;:&quot;foo&quot;}}\"></script>`\n const result = getConfigurationAttribute(html)\n expect(result).toBeUndefined()\n })\n\n it('handles multiple script tags and returns the first match', () => {\n const html = `\n <script id=\"api-reference\" data-configuration=\"{&quot;spec&quot;:{&quot;content&quot;:&quot;first&quot;}}\"></script>\n <script id=\"api-reference\" data-configuration=\"{&quot;spec&quot;:{&quot;content&quot;:&quot;second&quot;}}\"></script>\n `\n const result = getConfigurationAttribute(html)\n expect(result).toBe('{&quot;spec&quot;:{&quot;content&quot;:&quot;first&quot;}}')\n })\n})\n"],
5
+ "mappings": "AAAA,SAAS,UAAU,QAAQ,UAAU;AAErC,SAAS,iCAAiC;AAE1C,SAAS,6BAA6B,MAAM;AAC1C,KAAG,0DAA0D,MAAM;AACjE,UAAM,OAAO;AACb,UAAM,SAAS,0BAA0B,IAAI;AAC7C,WAAO,MAAM,EAAE,KAAK,0DAA0D;AAAA,EAChF,CAAC;AAED,KAAG,0DAA0D,MAAM;AACjE,UAAM,OAAO;AACb,UAAM,SAAS,0BAA0B,IAAI;AAC7C,WAAO,MAAM,EAAE,KAAK,0DAA0D;AAAA,EAChF,CAAC;AAED,KAAG,8DAA8D,MAAM;AACrE,UAAM,OAAO;AACb,UAAM,SAAS,0BAA0B,IAAI;AAC7C,WAAO,MAAM,EAAE,cAAc;AAAA,EAC/B,CAAC;AAED,KAAG,kDAAkD,MAAM;AACzD,UAAM,OAAO;AACb,UAAM,SAAS,0BAA0B,IAAI;AAC7C,WAAO,MAAM,EAAE,cAAc;AAAA,EAC/B,CAAC;AAED,KAAG,4DAA4D,MAAM;AACnE,UAAM,OAAO;AAAA;AAAA;AAAA;AAIb,UAAM,SAAS,0BAA0B,IAAI;AAC7C,WAAO,MAAM,EAAE,KAAK,4DAA4D;AAAA,EAClF,CAAC;AACH,CAAC;",
6
+ "names": []
7
+ }
@@ -0,0 +1,33 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { getContentOfScriptTag } from "./resolve.js";
3
+ describe("getContentOfScriptTag", () => {
4
+ it("returns the content of the script tag", () => {
5
+ const html = '<script id="api-reference">console.log("Hello, world!");<\/script>';
6
+ expect(getContentOfScriptTag(html)).toBe('console.log("Hello, world!");');
7
+ });
8
+ it("works with single quotes", () => {
9
+ const html = `<script id='api-reference'>console.log("Hello, world!");<\/script>`;
10
+ expect(getContentOfScriptTag(html)).toBe('console.log("Hello, world!");');
11
+ });
12
+ it("ignores HTML characters inside the attributes", () => {
13
+ const html = `<!DOCTYPE html>
14
+ <html>
15
+ <head>
16
+ <title>Scalar API Reference</title>
17
+ <meta charset="utf-8" />
18
+ <meta
19
+ name="viewport"
20
+ content="width=device-width, initial-scale=1" />
21
+ <style>
22
+ null
23
+ </style>
24
+ </head>
25
+ <body>
26
+ <script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference"><\/script>
27
+ <script id="api-reference" type="application/json" data-configuration="foo<br>bar">console.log("Hello, world!");<\/script>
28
+ </body>
29
+ </html>`;
30
+ expect(getContentOfScriptTag(html)).toBe('console.log("Hello, world!");');
31
+ });
32
+ });
33
+ //# sourceMappingURL=get-content-of-script-tag.test.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/get-content-of-script-tag.test.ts"],
4
+ "sourcesContent": ["import { describe, expect, it } from 'vitest'\n\nimport { getContentOfScriptTag } from './resolve'\n\ndescribe('getContentOfScriptTag', () => {\n it('returns the content of the script tag', () => {\n const html = '<script id=\"api-reference\">console.log(\"Hello, world!\");</script>'\n expect(getContentOfScriptTag(html)).toBe('console.log(\"Hello, world!\");')\n })\n\n it('works with single quotes', () => {\n const html = `<script id='api-reference'>console.log(\"Hello, world!\");</script>`\n expect(getContentOfScriptTag(html)).toBe('console.log(\"Hello, world!\");')\n })\n\n it('ignores HTML characters inside the attributes', () => {\n // HTML tags inside the attributes\n const html = `<!DOCTYPE html>\n <html>\n <head>\n <title>Scalar API Reference</title>\n <meta charset=\"utf-8\" />\n <meta\n name=\"viewport\"\n content=\"width=device-width, initial-scale=1\" />\n <style>\n null\n </style>\n </head>\n <body>\n <script src=\"https://cdn.jsdelivr.net/npm/@scalar/api-reference\"></script>\n <script id=\"api-reference\" type=\"application/json\" data-configuration=\"foo<br>bar\">console.log(\"Hello, world!\");</script>\n </body>\n </html>`\n\n expect(getContentOfScriptTag(html)).toBe('console.log(\"Hello, world!\");')\n })\n})\n"],
5
+ "mappings": "AAAA,SAAS,UAAU,QAAQ,UAAU;AAErC,SAAS,6BAA6B;AAEtC,SAAS,yBAAyB,MAAM;AACtC,KAAG,yCAAyC,MAAM;AAChD,UAAM,OAAO;AACb,WAAO,sBAAsB,IAAI,CAAC,EAAE,KAAK,+BAA+B;AAAA,EAC1E,CAAC;AAED,KAAG,4BAA4B,MAAM;AACnC,UAAM,OAAO;AACb,WAAO,sBAAsB,IAAI,CAAC,EAAE,KAAK,+BAA+B;AAAA,EAC1E,CAAC;AAED,KAAG,iDAAiD,MAAM;AAExD,UAAM,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkBb,WAAO,sBAAsB,IAAI,CAAC,EAAE,KAAK,+BAA+B;AAAA,EAC1E,CAAC;AACH,CAAC;",
6
+ "names": []
7
+ }
package/dist/index.js CHANGED
@@ -1 +1,5 @@
1
- export { resolve } from './resolve.js';
1
+ import { resolve } from "./resolve.js";
2
+ export {
3
+ resolve
4
+ };
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/index.ts"],
4
+ "sourcesContent": ["export { resolve } from './resolve'\n"],
5
+ "mappings": "AAAA,SAAS,eAAe;",
6
+ "names": []
7
+ }
package/dist/resolve.js CHANGED
@@ -1,316 +1,234 @@
1
- import { makeUrlAbsolute } from '@scalar/oas-utils/helpers';
2
- import { parse } from 'yaml';
3
-
4
- /**
5
- * Find an OpenAPI document URL in the HTML of @scalar/api-reference and other places.
6
- * This is useful to open the OpenAPI document from basically any source.
7
- */
1
+ import { makeUrlAbsolute } from "@scalar/oas-utils/helpers";
2
+ import { parse } from "yaml";
8
3
  async function resolve(value, options) {
9
- // URLs
10
- if (value?.startsWith('http://') || value?.startsWith('https://')) {
11
- // Transform GitHub URLs to raw file URLs
12
- const githubRawUrl = transformGitHubUrl(value);
13
- if (githubRawUrl) {
14
- return githubRawUrl;
15
- }
16
- // https://*.json
17
- if (value?.toLowerCase().endsWith('.json')) {
4
+ if (value?.startsWith("http://") || value?.startsWith("https://")) {
5
+ const githubRawUrl = transformGitHubUrl(value);
6
+ if (githubRawUrl) {
7
+ return githubRawUrl;
8
+ }
9
+ if (value?.toLowerCase().endsWith(".json")) {
10
+ return value;
11
+ }
12
+ if (value?.toLowerCase().endsWith(".yaml") || value?.toLowerCase().endsWith(".yml")) {
13
+ return value;
14
+ }
15
+ const sandboxUrl = value.match(/https:\/\/sandbox\.scalar\.com\/(p|e)\/([a-zA-Z0-9]+)/);
16
+ if (sandboxUrl?.[2]) {
17
+ return `https://sandbox.scalar.com/files/${sandboxUrl[2]}/openapi.yaml`;
18
+ }
19
+ try {
20
+ let result = await (options?.fetch ? options.fetch(value) : fetch(value, {
21
+ cache: "no-cache"
22
+ }));
23
+ if (!result.ok && options?.fetch) {
24
+ result = await fetch(value, {
25
+ cache: "no-cache"
26
+ });
27
+ }
28
+ if (result.ok) {
29
+ const content = await result.text();
30
+ const forwardedHost = result.headers.get("X-Forwarded-Host");
31
+ try {
32
+ const jsonContent = JSON.parse(content);
33
+ if (jsonContent.openapi || jsonContent.swagger) {
18
34
  return value;
35
+ }
36
+ } catch {
37
+ try {
38
+ const yamlContent = parse(content);
39
+ if (yamlContent?.openapi || yamlContent?.swagger) {
40
+ return value;
41
+ }
42
+ } catch {
43
+ }
19
44
  }
20
- // https://*.yaml
21
- if (value?.toLowerCase().endsWith('.yaml') || value?.toLowerCase().endsWith('.yml')) {
22
- return value;
45
+ const urlOrPathOrDocument = parseHtml(content);
46
+ if (typeof urlOrPathOrDocument === "string") {
47
+ try {
48
+ return JSON.parse(urlOrPathOrDocument);
49
+ } catch {
50
+ try {
51
+ const yaml = parse(urlOrPathOrDocument);
52
+ if (typeof yaml === "object") {
53
+ return yaml;
54
+ }
55
+ } catch {
56
+ }
57
+ }
23
58
  }
24
- // https://sandbox.scalar.com
25
- const sandboxUrl = value.match(/https:\/\/sandbox\.scalar\.com\/(p|e)\/([a-zA-Z0-9]+)/);
26
- if (sandboxUrl?.[2]) {
27
- return `https://sandbox.scalar.com/files/${sandboxUrl[2]}/openapi.yaml`;
59
+ if (typeof urlOrPathOrDocument === "object") {
60
+ return urlOrPathOrDocument;
28
61
  }
29
- // Fetch URL
30
- try {
31
- let result = await (options?.fetch
32
- ? options.fetch(value)
33
- : fetch(value, {
34
- cache: 'no-cache',
35
- }));
36
- // If the custom fetch failed, try again with regular fetch
37
- if (!result.ok && options?.fetch) {
38
- result = await fetch(value, {
39
- cache: 'no-cache',
40
- });
41
- }
42
- if (result.ok) {
43
- const content = await result.text();
44
- const forwardedHost = result.headers.get('X-Forwarded-Host');
45
- // Check if content is directly JSON/YAML
46
- try {
47
- // Try parsing as JSON
48
- const jsonContent = JSON.parse(content);
49
- if (jsonContent.openapi || jsonContent.swagger) {
50
- return value;
51
- }
52
- }
53
- catch {
54
- // Try parsing as YAML
55
- try {
56
- const yamlContent = parse(content);
57
- if (yamlContent?.openapi || yamlContent?.swagger) {
58
- return value;
59
- }
60
- }
61
- catch {
62
- // Not YAML
63
- }
64
- }
65
- const urlOrPathOrDocument = parseHtml(content);
66
- // Document (string)
67
- if (typeof urlOrPathOrDocument === 'string') {
68
- try {
69
- // JSON?
70
- return JSON.parse(urlOrPathOrDocument);
71
- }
72
- catch {
73
- // No JSON
74
- try {
75
- // YAML?
76
- const yaml = parse(urlOrPathOrDocument);
77
- if (typeof yaml === 'object') {
78
- return yaml;
79
- }
80
- }
81
- catch {
82
- // Not YAML
83
- }
84
- }
85
- }
86
- // Document (object)
87
- if (typeof urlOrPathOrDocument === 'object') {
88
- return urlOrPathOrDocument;
89
- }
90
- // Relative or absolute URL
91
- if (urlOrPathOrDocument) {
92
- return makeUrlAbsolute(urlOrPathOrDocument, forwardedHost || value);
93
- }
94
- // Check for configuration attribute URL
95
- const configUrl = getConfigurationAttributeUrl(content);
96
- if (configUrl) {
97
- return makeUrlAbsolute(configUrl, forwardedHost || value);
98
- }
99
- // Check for embedded OpenAPI document
100
- const embeddedSpec = parseEmbeddedOpenApi(content);
101
- if (embeddedSpec) {
102
- return embeddedSpec;
103
- }
104
- }
105
- else {
106
- console.warn(`[@scalar/import] Failed to fetch ${value}`);
107
- }
62
+ if (urlOrPathOrDocument) {
63
+ return makeUrlAbsolute(urlOrPathOrDocument, forwardedHost || value);
108
64
  }
109
- catch (error) {
110
- console.error(`[@scalar/import] Failed to fetch ${value}`, error);
65
+ const configUrl = getConfigurationAttributeUrl(content);
66
+ if (configUrl) {
67
+ return makeUrlAbsolute(configUrl, forwardedHost || value);
111
68
  }
112
- }
113
- return undefined;
69
+ const embeddedSpec = parseEmbeddedOpenApi(content);
70
+ if (embeddedSpec) {
71
+ return embeddedSpec;
72
+ }
73
+ } else {
74
+ console.warn(`[@scalar/import] Failed to fetch ${value}`);
75
+ }
76
+ } catch (error) {
77
+ console.error(`[@scalar/import] Failed to fetch ${value}`, error);
78
+ }
79
+ }
80
+ return void 0;
114
81
  }
115
- /**
116
- * Go through the HTML and try to find the OpenAPI document URL
117
- */
118
82
  function parseHtml(html) {
119
- // Check whether it could be HTML
120
- if (!html?.includes('<')) {
121
- return undefined;
122
- }
123
- // id="api-reference" data-url="*"
124
- const dataUrlMatch = html
125
- .match(/id=["']api-reference["'][\s\S]*?data-url=["']([^"']+)["']/)
126
- ?.slice(1)
127
- .find(Boolean);
128
- if (dataUrlMatch) {
129
- return dataUrlMatch;
130
- }
131
- // spec-url="*"
132
- const specUrlMatch = html.match(/spec-url=["']([^"']+)["']/);
133
- if (specUrlMatch?.[1]) {
134
- return specUrlMatch[1];
135
- }
136
- // Redoc.init('*')
137
- const redocInit = html.match(/Redoc.init\(["']([^"']+)["']/);
138
- if (redocInit?.[1]) {
139
- return redocInit[1];
140
- }
141
- // &amp;quot;url&amp;quot;:&amp;quot;MY_CUSTOM_URL&amp;quot;
142
- const doubleEncodedConfigurationUrl = html.match(/&amp;quot;url&amp;quot;:&amp;quot;([^;]+)&amp;quot;/);
143
- if (doubleEncodedConfigurationUrl?.[1]) {
144
- return doubleEncodedConfigurationUrl[1];
145
- }
146
- // &amp;quot;url&amp;quot;:&amp;quot;MY_CUSTOM_URL&amp;quot;
147
- const encodedConfigurationUrl = html.match(/&quot;url&quot;:&quot;([^;]+)&quot;/);
148
- if (encodedConfigurationUrl?.[1]) {
149
- return encodedConfigurationUrl[1];
150
- }
151
- // Try to find embedded OpenAPI document in script tag first
152
- const scriptContent = parseScriptContent(html);
153
- if (scriptContent) {
154
- return scriptContent;
155
- }
156
- // Check for configuration in script tag
157
- const scriptConfigMatch = html.match(/url:\s*["']([^"']+)["']/i);
158
- if (scriptConfigMatch?.[1]) {
159
- return scriptConfigMatch?.[1];
160
- }
161
- // Check for OpenAPI URLs in the HTML
162
- const linkMatch = html.match(/<a[^>]*href=["']([^"']+\.(?:yaml|yml|json))["'][^>]*>/i);
163
- if (linkMatch?.[1]) {
164
- return linkMatch[1];
165
- }
166
- // Check for URLs in escaped JS objects
167
- const escapedJsonMatch = html.match(/\\"spec\\":\{.*?\\"url\\":\\"([^"\\]+)\\"/);
168
- if (escapedJsonMatch?.[1]) {
169
- return escapedJsonMatch[1];
170
- }
171
- return undefined;
83
+ if (!html?.includes("<")) {
84
+ return void 0;
85
+ }
86
+ const dataUrlMatch = html.match(/id=["']api-reference["'][\s\S]*?data-url=["']([^"']+)["']/)?.slice(1).find(Boolean);
87
+ if (dataUrlMatch) {
88
+ return dataUrlMatch;
89
+ }
90
+ const specUrlMatch = html.match(/spec-url=["']([^"']+)["']/);
91
+ if (specUrlMatch?.[1]) {
92
+ return specUrlMatch[1];
93
+ }
94
+ const redocInit = html.match(/Redoc.init\(["']([^"']+)["']/);
95
+ if (redocInit?.[1]) {
96
+ return redocInit[1];
97
+ }
98
+ const doubleEncodedConfigurationUrl = html.match(/&amp;quot;url&amp;quot;:&amp;quot;([^;]+)&amp;quot;/);
99
+ if (doubleEncodedConfigurationUrl?.[1]) {
100
+ return doubleEncodedConfigurationUrl[1];
101
+ }
102
+ const encodedConfigurationUrl = html.match(/&quot;url&quot;:&quot;([^;]+)&quot;/);
103
+ if (encodedConfigurationUrl?.[1]) {
104
+ return encodedConfigurationUrl[1];
105
+ }
106
+ const scriptContent = parseScriptContent(html);
107
+ if (scriptContent) {
108
+ return scriptContent;
109
+ }
110
+ const scriptConfigMatch = html.match(/url:\s*["']([^"']+)["']/i);
111
+ if (scriptConfigMatch?.[1]) {
112
+ return scriptConfigMatch?.[1];
113
+ }
114
+ const linkMatch = html.match(/<a[^>]*href=["']([^"']+\.(?:yaml|yml|json))["'][^>]*>/i);
115
+ if (linkMatch?.[1]) {
116
+ return linkMatch[1];
117
+ }
118
+ const escapedJsonMatch = html.match(/\\"spec\\":\{.*?\\"url\\":\\"([^"\\]+)\\"/);
119
+ if (escapedJsonMatch?.[1]) {
120
+ return escapedJsonMatch[1];
121
+ }
122
+ return void 0;
172
123
  }
173
- /**
174
- * Get the content between the script tags
175
- *
176
- * @example <script id="api-reference">console.log("Hello, world!");</script>
177
- */
178
124
  function getContentOfScriptTag(html) {
179
- const patterns = [
180
- // Double quotes
181
- /<script[^>]*id="api-reference[\s\S]*?">([\s\S]*?)<\/script>/i,
182
- // Single quotes
183
- /<script[^>]*id='api-reference[\s\S]*?'>([\s\S]*?)<\/script>/i,
184
- ];
185
- for (const pattern of patterns) {
186
- const match = html.match(pattern);
187
- if (match?.[1]) {
188
- return match[1].trim();
189
- }
190
- }
191
- return undefined;
125
+ const patterns = [
126
+ // Double quotes
127
+ /<script[^>]*id="api-reference[\s\S]*?">([\s\S]*?)<\/script>/i,
128
+ // Single quotes
129
+ /<script[^>]*id='api-reference[\s\S]*?'>([\s\S]*?)<\/script>/i
130
+ ];
131
+ for (const pattern of patterns) {
132
+ const match = html.match(pattern);
133
+ if (match?.[1]) {
134
+ return match[1].trim();
135
+ }
136
+ }
137
+ return void 0;
192
138
  }
193
- /**
194
- * Parse OpenAPI document directly from script tag content
195
- */
196
139
  function parseScriptContent(html) {
197
- const content = getContentOfScriptTag(html);
198
- try {
199
- if (content) {
200
- try {
201
- // JSON
202
- return JSON.parse(content);
203
- }
204
- catch {
205
- try {
206
- // JSON with escaped whitespace
207
- const sanitizedContent = content.replace(/\\s/g, '\\\\s');
208
- return JSON.parse(sanitizedContent);
209
- }
210
- catch {
211
- // YAML
212
- return parse(content);
213
- }
214
- }
140
+ const content = getContentOfScriptTag(html);
141
+ try {
142
+ if (content) {
143
+ try {
144
+ return JSON.parse(content);
145
+ } catch {
146
+ try {
147
+ const sanitizedContent = content.replace(/\\s/g, "\\\\s");
148
+ return JSON.parse(sanitizedContent);
149
+ } catch {
150
+ return parse(content);
215
151
  }
152
+ }
216
153
  }
217
- catch (error) {
218
- console.error('[@scalar/import] Failed to parse script content:', error);
219
- }
220
- return undefined;
154
+ } catch (error) {
155
+ console.error("[@scalar/import] Failed to parse script content:", error);
156
+ }
157
+ return void 0;
221
158
  }
222
- /**
223
- * Get the configuration attribute from the script tag
224
- *
225
- * @example <script id="api-reference" data-configuration="{&quot;spec&quot;:{&quot;content&quot;:&quot;foo&quot;}}"></script>
226
- */
227
159
  function getConfigurationAttribute(html) {
228
- const patterns = [
229
- // Double quotes
230
- /<script[^>]*id="api-reference"[^>]*data-configuration=["]([^"]+)["][^>]*>(.*?)<\/script>/s,
231
- // Single quotes
232
- /<script[^>]*id='api-reference'[^>]*data-configuration=[']([^']+)['][^>]*>(.*?)<\/script>/s,
233
- // Mix quote single first
234
- /<script[^>]*id='api-reference'[^>]*data-configuration=["]([^"]+)["][^>]*>(.*?)<\/script>/s,
235
- // Mix quote double first
236
- /<script[^>]*id="api-reference"[^>]*data-configuration=[']([^']+)['][^>]*>(.*?)<\/script>/s,
237
- ];
238
- for (const pattern of patterns) {
239
- const match = html.match(pattern);
240
- if (match?.[1]) {
241
- return match[1];
242
- }
243
- }
244
- return undefined;
160
+ const patterns = [
161
+ // Double quotes
162
+ /<script[^>]*id="api-reference"[^>]*data-configuration=["]([^"]+)["][^>]*>(.*?)<\/script>/s,
163
+ // Single quotes
164
+ /<script[^>]*id='api-reference'[^>]*data-configuration=[']([^']+)['][^>]*>(.*?)<\/script>/s,
165
+ // Mix quote single first
166
+ /<script[^>]*id='api-reference'[^>]*data-configuration=["]([^"]+)["][^>]*>(.*?)<\/script>/s,
167
+ // Mix quote double first
168
+ /<script[^>]*id="api-reference"[^>]*data-configuration=[']([^']+)['][^>]*>(.*?)<\/script>/s
169
+ ];
170
+ for (const pattern of patterns) {
171
+ const match = html.match(pattern);
172
+ if (match?.[1]) {
173
+ return match[1];
174
+ }
175
+ }
176
+ return void 0;
245
177
  }
246
- /** Grab the URL from the configuration data attribute */
247
178
  const getConfigurationAttributeUrl = (html) => {
248
- const configString = getConfigurationAttribute(html);
249
- if (!configString) {
250
- return undefined;
251
- }
252
- const config = JSON.parse(decodeHtmlEntities(configString));
253
- return config.url || config.spec?.url;
179
+ const configString = getConfigurationAttribute(html);
180
+ if (!configString) {
181
+ return void 0;
182
+ }
183
+ const config = JSON.parse(decodeHtmlEntities(configString));
184
+ return config.url || config.spec?.url;
254
185
  };
255
- /**
256
- * Parse embedded OpenAPI document from HTML
257
- */
258
186
  function parseEmbeddedOpenApi(html) {
259
- const configString = getConfigurationAttribute(html);
260
- if (!configString) {
261
- return undefined;
262
- }
263
- try {
264
- const config = JSON.parse(decodeHtmlEntities(configString));
265
- // Handle the old spec format while we transition to the new one
266
- const content = config.content || config.spec?.content;
267
- // Handle both direct JSON content and YAML content
268
- if (content) {
269
- // If content is a string, assume it's YAML
270
- if (typeof content === 'string') {
271
- return parse(content);
272
- }
273
- // If content is an object, return it directly
274
- return content;
275
- }
276
- }
277
- catch (error) {
278
- console.error('[@scalar/import] Failed to parse embedded OpenAPI document:', error);
279
- }
280
- return undefined;
187
+ const configString = getConfigurationAttribute(html);
188
+ if (!configString) {
189
+ return void 0;
190
+ }
191
+ try {
192
+ const config = JSON.parse(decodeHtmlEntities(configString));
193
+ const content = config.content || config.spec?.content;
194
+ if (content) {
195
+ if (typeof content === "string") {
196
+ return parse(content);
197
+ }
198
+ return content;
199
+ }
200
+ } catch (error) {
201
+ console.error("[@scalar/import] Failed to parse embedded OpenAPI document:", error);
202
+ }
203
+ return void 0;
281
204
  }
282
- /**
283
- * Decode HTML entities in a string
284
- */
285
205
  function decodeHtmlEntities(text) {
286
- const entities = {
287
- '&amp;': '&',
288
- '&lt;': '<',
289
- '&gt;': '>',
290
- '&quot;': '"',
291
- '&#39;': "'",
292
- };
293
- const updatedText = text
294
- .replace(new RegExp(Object.keys(entities).join('|'), 'g'), (match) => entities[match])
295
- .replace(/\n/g, '\\n')
296
- .trim();
297
- if (updatedText.startsWith('{&quot;')) {
298
- // console.log('ok', updatedText)
299
- return decodeHtmlEntities(updatedText);
300
- }
301
- return updatedText;
206
+ const entities = {
207
+ "&amp;": "&",
208
+ "&lt;": "<",
209
+ "&gt;": ">",
210
+ "&quot;": '"',
211
+ "&#39;": "'"
212
+ };
213
+ const updatedText = text.replace(new RegExp(Object.keys(entities).join("|"), "g"), (match) => entities[match]).replace(/\n/g, "\\n").trim();
214
+ if (updatedText.startsWith("{&quot;")) {
215
+ return decodeHtmlEntities(updatedText);
216
+ }
217
+ return updatedText;
302
218
  }
303
- /**
304
- * Transform GitHub URLs to raw file URLs, preserving the branch information
305
- */
306
219
  function transformGitHubUrl(url) {
307
- const githubRegex = /^https:\/\/github\.com\/([^/]+)\/([^/]+)\/blob\/([^/]+)\/(.+)$/;
308
- const match = url.match(githubRegex);
309
- if (match) {
310
- const [, owner, repo, branch, path] = match;
311
- return `https://raw.githubusercontent.com/${owner}/${repo}/refs/heads/${branch}/${path}`;
312
- }
313
- return undefined;
220
+ const githubRegex = /^https:\/\/github\.com\/([^/]+)\/([^/]+)\/blob\/([^/]+)\/(.+)$/;
221
+ const match = url.match(githubRegex);
222
+ if (match) {
223
+ const [, owner, repo, branch, path] = match;
224
+ return `https://raw.githubusercontent.com/${owner}/${repo}/refs/heads/${branch}/${path}`;
225
+ }
226
+ return void 0;
314
227
  }
315
-
316
- export { getConfigurationAttribute, getConfigurationAttributeUrl, getContentOfScriptTag, resolve };
228
+ export {
229
+ getConfigurationAttribute,
230
+ getConfigurationAttributeUrl,
231
+ getContentOfScriptTag,
232
+ resolve
233
+ };
234
+ //# sourceMappingURL=resolve.js.map