@scalar/cli 2.0.1 → 2.5.1
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/README.md +68 -24
- package/chunks/action-37EV4UHW.js +125 -0
- package/chunks/action-4XI7XJR4.js +204 -0
- package/chunks/action-5IU77OII.js +60 -0
- package/chunks/action-B3KKREWQ.js +64 -0
- package/chunks/action-CH24QGTE.js +86 -0
- package/chunks/action-F3UX5E3M.js +522 -0
- package/chunks/action-FDB7NEOK.js +81 -0
- package/chunks/action-FIXBOJEW.js +244 -0
- package/chunks/action-G26LSVZ7.js +40 -0
- package/chunks/action-H3RTILLM.js +46 -0
- package/chunks/action-HGBBV353.js +86 -0
- package/chunks/action-IUE4IOWO.js +2142 -0
- package/chunks/action-JZLZ7ZAD.js +110 -0
- package/chunks/action-LA6KVAXQ.js +374 -0
- package/chunks/action-M7RQKBSB.js +169 -0
- package/chunks/action-MSLBC2SO.js +92 -0
- package/chunks/action-NVSZT2ZD.js +37 -0
- package/chunks/action-OGQSTRMX.js +37 -0
- package/chunks/action-PAGJ5PWC.js +60 -0
- package/chunks/action-QE2ZQQX7.js +250 -0
- package/chunks/action-QPUSPD5M.js +54 -0
- package/chunks/action-R7IMFHQ5.js +147 -0
- package/chunks/action-SH4UUXPL.js +60 -0
- package/chunks/action-SNLCIBQC.js +84 -0
- package/chunks/action-SQG3JAII.js +150 -0
- package/chunks/action-UZQJNYK4.js +18 -0
- package/chunks/action-VC4DCVST.js +68 -0
- package/chunks/action-VTVFY2MP.js +181 -0
- package/chunks/action-WFWYGY7O.js +67 -0
- package/chunks/action-XMNX5ZYT.js +197 -0
- package/chunks/agent-HCQRMHQ5.js +132 -0
- package/chunks/asyncapi-QM76O55R.js +105 -0
- package/chunks/build.action-P7FCIMYU.js +108 -0
- package/chunks/chunk-24WAOKGG.js +105 -0
- package/chunks/chunk-3L6DLIXJ.js +25530 -0
- package/chunks/chunk-3MZYUBJ6.js +49 -0
- package/chunks/chunk-3ZJYGGAA.js +30 -0
- package/chunks/chunk-4NHMAG6F.js +21 -0
- package/chunks/chunk-4ORL4MST.js +16 -0
- package/chunks/chunk-4ZDQXWBT.js +26 -0
- package/chunks/chunk-6ZMT63IV.js +19 -0
- package/chunks/chunk-7AGLC7WV.js +107 -0
- package/chunks/chunk-AEFPCC4U.js +16 -0
- package/chunks/chunk-AO3F5XWR.js +3147 -0
- package/chunks/chunk-B2MHTD3R.js +90 -0
- package/chunks/chunk-CISTON3A.js +153 -0
- package/chunks/chunk-COBPBRQF.js +25 -0
- package/chunks/chunk-F467BYYR.js +568 -0
- package/chunks/chunk-GSGZHE26.js +352 -0
- package/chunks/chunk-HCPN3KNF.js +637 -0
- package/chunks/chunk-HPL3ZZ2P.js +1726 -0
- package/chunks/chunk-IKT5F47M.js +17344 -0
- package/chunks/chunk-JFIXNSPP.js +26 -0
- package/chunks/chunk-K4DTP5TV.js +32 -0
- package/chunks/chunk-K74E42RV.js +7311 -0
- package/chunks/chunk-KHDYYVYF.js +16 -0
- package/chunks/chunk-LFU5ZUAP.js +350 -0
- package/chunks/chunk-M37TP6U2.js +445 -0
- package/chunks/chunk-OQKDBLOZ.js +741 -0
- package/chunks/chunk-P7H7GY5A.js +14 -0
- package/chunks/chunk-PBXZN65A.js +63911 -0
- package/chunks/chunk-PT5TI77I.js +34 -0
- package/chunks/chunk-Q7DOQHZN.js +404 -0
- package/chunks/chunk-T5HJUAWB.js +242 -0
- package/chunks/chunk-T7B6WNZC.js +18 -0
- package/chunks/chunk-UGGNHILG.js +38 -0
- package/chunks/chunk-VNYE4R7N.js +499 -0
- package/chunks/chunk-X5T526CE.js +23 -0
- package/chunks/chunk-XCSR4RIT.js +210 -0
- package/chunks/chunk-Z2KMGFE6.js +295 -0
- package/chunks/create.action-HDD2WUON.js +108 -0
- package/chunks/delete.action-7GOZY7ID.js +88 -0
- package/chunks/delete.action-VE66JFDS.js +96 -0
- package/chunks/get.action-2745EB4N.js +86 -0
- package/chunks/list.action-3VTXQJRA.js +116 -0
- package/chunks/list.action-4QDCZLSZ.js +95 -0
- package/chunks/publish.action-ULQLZKWU.js +190 -0
- package/chunks/update.action-6QEFP7NA.js +95 -0
- package/chunks/update.action-OROQSP2S.js +101 -0
- package/docs.html +352 -250
- package/index.js +664 -99064
- package/package.json +17 -11
package/README.md
CHANGED
|
@@ -171,18 +171,18 @@ Options:
|
|
|
171
171
|
|
|
172
172
|
Commands:
|
|
173
173
|
bundle [options] [file|url] Bundle an OpenAPI document by resolving all references and external dependencies
|
|
174
|
-
split [options] [file|url] Split
|
|
175
|
-
join [options] <files...> Merge multiple OpenAPI documents into a single unified document
|
|
176
|
-
format [options] [file|url] Format an OpenAPI file
|
|
174
|
+
split [options] [file|url] Split OpenAPI or AsyncAPI documents into small chunks
|
|
175
|
+
join [options] <files...> Merge multiple OpenAPI or AsyncAPI documents into a single unified document
|
|
176
|
+
format [options] [file|url] Format an OpenAPI or AsyncAPI file
|
|
177
177
|
convert [options] [file|url] Convert a Postman collection to an OpenAPI document
|
|
178
178
|
markdown [options] [file|url] Generate Markdown from an OpenAPI file
|
|
179
|
-
mock [options] [file|url] Mock an API
|
|
180
|
-
serve [options] [file|url] Serve an API Reference from an OpenAPI file
|
|
181
|
-
share [options] [file] Share an OpenAPI file
|
|
182
|
-
validate [file|url] Validate an OpenAPI file
|
|
179
|
+
mock [options] [file|url] Mock an OpenAPI API or AsyncAPI WebSocket and SSE channels
|
|
180
|
+
serve [options] [file|url] Serve an API Reference from an OpenAPI or AsyncAPI file
|
|
181
|
+
share [options] [file] Share an OpenAPI or AsyncAPI file
|
|
182
|
+
validate [file|url] Validate an OpenAPI or AsyncAPI file
|
|
183
183
|
void [options] Boot a server to mirror HTTP requests
|
|
184
|
-
lint [options] [file|url] Lint your OpenAPI file using spectral rules
|
|
185
|
-
upgrade [options] [file|url] Upgrade OpenAPI document to version 3.1
|
|
184
|
+
lint [options] [file|url] Lint your OpenAPI or AsyncAPI file using spectral rules
|
|
185
|
+
upgrade [options] [file|url] Upgrade an OpenAPI or AsyncAPI document to version 3.1
|
|
186
186
|
help [command] display help for command
|
|
187
187
|
```
|
|
188
188
|
|
|
@@ -204,13 +204,16 @@ Options:
|
|
|
204
204
|
```
|
|
205
205
|
|
|
206
206
|
#### split
|
|
207
|
+
|
|
208
|
+
Splits AsyncAPI channels, operations, messages, and reusable components (including payload schemas) into JSON chunks. AsyncAPI versions are preserved, including 2.6, 3.0, and 3.1; splitting does not upgrade the document or add Scalar navigation metadata. Use `scalar document upgrade` separately to normalize versions. Nested external references are bundled relative to their source files or URLs, and chunk references resolve relative to the generated files. Both relative and absolute output directories are supported. The entry point is `out.json`.
|
|
209
|
+
|
|
207
210
|
```
|
|
208
211
|
Usage: scalar document split [options] [file|url]
|
|
209
212
|
|
|
210
|
-
Split
|
|
213
|
+
Split OpenAPI or AsyncAPI documents into small chunks
|
|
211
214
|
|
|
212
215
|
Arguments:
|
|
213
|
-
file|url Path to OpenAPI file or URL to split
|
|
216
|
+
file|url Path to OpenAPI or AsyncAPI file or URL to split
|
|
214
217
|
|
|
215
218
|
Options:
|
|
216
219
|
-o, --output <path> Path to save the chunks
|
|
@@ -221,10 +224,10 @@ Options:
|
|
|
221
224
|
```
|
|
222
225
|
Usage: scalar document join [options] <files...>
|
|
223
226
|
|
|
224
|
-
Merge multiple OpenAPI documents into a single unified document
|
|
227
|
+
Merge multiple OpenAPI or AsyncAPI documents into a single unified document
|
|
225
228
|
|
|
226
229
|
Arguments:
|
|
227
|
-
files Paths to the OpenAPI files to merge
|
|
230
|
+
files Paths to the OpenAPI or AsyncAPI files to merge
|
|
228
231
|
|
|
229
232
|
Options:
|
|
230
233
|
--output -o <file> Path to save the merged output file
|
|
@@ -236,7 +239,7 @@ Options:
|
|
|
236
239
|
```
|
|
237
240
|
Usage: scalar document format [options] [file|url]
|
|
238
241
|
|
|
239
|
-
Format an OpenAPI file
|
|
242
|
+
Format an OpenAPI or AsyncAPI file
|
|
240
243
|
|
|
241
244
|
Arguments:
|
|
242
245
|
file|url File or URL to format
|
|
@@ -279,10 +282,10 @@ Options:
|
|
|
279
282
|
```
|
|
280
283
|
Usage: scalar document mock [options] [file|url]
|
|
281
284
|
|
|
282
|
-
Mock an API
|
|
285
|
+
Mock an OpenAPI API or AsyncAPI WebSocket and SSE channels
|
|
283
286
|
|
|
284
287
|
Arguments:
|
|
285
|
-
file|url OpenAPI file or URL to mock
|
|
288
|
+
file|url OpenAPI or AsyncAPI file or URL to mock
|
|
286
289
|
|
|
287
290
|
Options:
|
|
288
291
|
-w, --watch watch the file for changes
|
|
@@ -295,10 +298,10 @@ Options:
|
|
|
295
298
|
```
|
|
296
299
|
Usage: scalar document serve [options] [file|url]
|
|
297
300
|
|
|
298
|
-
Serve an API Reference from an OpenAPI file
|
|
301
|
+
Serve an API Reference from an OpenAPI or AsyncAPI file
|
|
299
302
|
|
|
300
303
|
Arguments:
|
|
301
|
-
file|url OpenAPI file or URL to show the reference for
|
|
304
|
+
file|url OpenAPI or AsyncAPI file or URL to show the reference for
|
|
302
305
|
|
|
303
306
|
Options:
|
|
304
307
|
-w, --watch watch the file for changes
|
|
@@ -311,7 +314,7 @@ Options:
|
|
|
311
314
|
```
|
|
312
315
|
Usage: scalar document share [options] [file]
|
|
313
316
|
|
|
314
|
-
Share an OpenAPI file
|
|
317
|
+
Share an OpenAPI or AsyncAPI file
|
|
315
318
|
|
|
316
319
|
Arguments:
|
|
317
320
|
file file to share
|
|
@@ -325,7 +328,7 @@ Options:
|
|
|
325
328
|
```
|
|
326
329
|
Usage: scalar document validate [options] [file|url]
|
|
327
330
|
|
|
328
|
-
Validate an OpenAPI file
|
|
331
|
+
Validate an OpenAPI or AsyncAPI file
|
|
329
332
|
|
|
330
333
|
Arguments:
|
|
331
334
|
file|url File or URL to validate
|
|
@@ -350,10 +353,10 @@ Options:
|
|
|
350
353
|
```
|
|
351
354
|
Usage: scalar document lint [options] [file|url]
|
|
352
355
|
|
|
353
|
-
Lint your OpenAPI file using spectral rules
|
|
356
|
+
Lint your OpenAPI or AsyncAPI file using spectral rules
|
|
354
357
|
|
|
355
358
|
Arguments:
|
|
356
|
-
file|url OpenAPI file path or url
|
|
359
|
+
file|url OpenAPI or AsyncAPI file path or url
|
|
357
360
|
|
|
358
361
|
Options:
|
|
359
362
|
-r, --rule <file|url> Rule path or url
|
|
@@ -364,10 +367,10 @@ Options:
|
|
|
364
367
|
```
|
|
365
368
|
Usage: scalar document upgrade [options] [file|url]
|
|
366
369
|
|
|
367
|
-
Upgrade OpenAPI document to version 3.1
|
|
370
|
+
Upgrade an OpenAPI or AsyncAPI document to version 3.1
|
|
368
371
|
|
|
369
372
|
Arguments:
|
|
370
|
-
file|url File or URL to
|
|
373
|
+
file|url File or URL to upgrade
|
|
371
374
|
|
|
372
375
|
Options:
|
|
373
376
|
-o, --output <file> Path to save the upgraded output file
|
|
@@ -389,6 +392,8 @@ Commands:
|
|
|
389
392
|
create [options] Create a new project that is not linked to a github project.
|
|
390
393
|
preview [options] [config] Preview scalar guides
|
|
391
394
|
publish [options] Publish new build for a github sync project that is not linked.
|
|
395
|
+
rollback [options] Roll the live deployment back to a previously deployed build.
|
|
396
|
+
deployments Inspect a project deployment history.
|
|
392
397
|
upgrade [config] Upgrade scalar project
|
|
393
398
|
help [command] display help for command
|
|
394
399
|
```
|
|
@@ -462,6 +467,44 @@ Options:
|
|
|
462
467
|
-h, --help display help for command
|
|
463
468
|
```
|
|
464
469
|
|
|
470
|
+
#### rollback
|
|
471
|
+
```
|
|
472
|
+
Usage: scalar project rollback [options]
|
|
473
|
+
|
|
474
|
+
Roll the live deployment back to a previously deployed build.
|
|
475
|
+
|
|
476
|
+
Options:
|
|
477
|
+
-s, --slug [slug] Project slug found in Scalar Dashboard
|
|
478
|
+
-t, --to <publishUid> Roll back to a specific build id (defaults to the next older deployed build)
|
|
479
|
+
-y, --yes Skip the confirmation prompt
|
|
480
|
+
-h, --help display help for command
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
#### deployments
|
|
484
|
+
```
|
|
485
|
+
Usage: scalar project deployments [options] [command]
|
|
486
|
+
|
|
487
|
+
Inspect a project deployment history.
|
|
488
|
+
|
|
489
|
+
Options:
|
|
490
|
+
-h, --help display help for command
|
|
491
|
+
|
|
492
|
+
Commands:
|
|
493
|
+
list [options] List the production deployment history for a project.
|
|
494
|
+
help [command] display help for command
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
##### list
|
|
498
|
+
```
|
|
499
|
+
Usage: scalar project deployments list [options]
|
|
500
|
+
|
|
501
|
+
List the production deployment history for a project.
|
|
502
|
+
|
|
503
|
+
Options:
|
|
504
|
+
-s, --slug [slug] Project slug found in Scalar Dashboard
|
|
505
|
+
-h, --help display help for command
|
|
506
|
+
```
|
|
507
|
+
|
|
465
508
|
#### upgrade
|
|
466
509
|
```
|
|
467
510
|
Usage: scalar project upgrade [options] [config]
|
|
@@ -779,6 +822,7 @@ Options:
|
|
|
779
822
|
--namespace <namespace> Scalar team namespace
|
|
780
823
|
--version <version> API version (e.g. 0.1.0)
|
|
781
824
|
--private Make API private (default: false)
|
|
825
|
+
--force Force override an existing version (default: false)
|
|
782
826
|
--bundle Bundle all external references before uploading
|
|
783
827
|
--treeShake Remove unused components from the bundled document
|
|
784
828
|
--urlMap Generate a map of resolved URLs when bundling the document
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { createRequire as $$cR } from "node:module"; const require = $$cR(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
createError,
|
|
4
|
+
displayError
|
|
5
|
+
} from "./chunk-3ZJYGGAA.js";
|
|
6
|
+
import {
|
|
7
|
+
readAndParseConfig,
|
|
8
|
+
renderConfigError
|
|
9
|
+
} from "./chunk-7AGLC7WV.js";
|
|
10
|
+
import {
|
|
11
|
+
CONFIG_FILE_DEFAULT,
|
|
12
|
+
findConfig,
|
|
13
|
+
legacyTo2_0_0
|
|
14
|
+
} from "./chunk-PBXZN65A.js";
|
|
15
|
+
import {
|
|
16
|
+
ConfigVersion
|
|
17
|
+
} from "./chunk-OQKDBLOZ.js";
|
|
18
|
+
import "./chunk-K74E42RV.js";
|
|
19
|
+
import "./chunk-CISTON3A.js";
|
|
20
|
+
import "./chunk-Q7DOQHZN.js";
|
|
21
|
+
import {
|
|
22
|
+
output
|
|
23
|
+
} from "./chunk-T5HJUAWB.js";
|
|
24
|
+
import "./chunk-GSGZHE26.js";
|
|
25
|
+
import "./chunk-IKT5F47M.js";
|
|
26
|
+
import "./chunk-3MZYUBJ6.js";
|
|
27
|
+
|
|
28
|
+
// src/domains/project/upgrade/action.ts
|
|
29
|
+
import fs from "node:fs/promises";
|
|
30
|
+
import path from "node:path";
|
|
31
|
+
import { text } from "@clack/prompts";
|
|
32
|
+
import as from "ansis";
|
|
33
|
+
import { n } from "neverpanic";
|
|
34
|
+
async function upgradeAction(__configPath) {
|
|
35
|
+
const configPath = __configPath || findConfig() || await text({
|
|
36
|
+
message: "Where is your configuration file located?",
|
|
37
|
+
defaultValue: CONFIG_FILE_DEFAULT,
|
|
38
|
+
placeholder: CONFIG_FILE_DEFAULT
|
|
39
|
+
});
|
|
40
|
+
const parseConfigResult = readAndParseConfig(configPath);
|
|
41
|
+
if (!parseConfigResult.success) {
|
|
42
|
+
renderConfigError(parseConfigResult.error);
|
|
43
|
+
}
|
|
44
|
+
if (parseConfigResult.success) {
|
|
45
|
+
output.info().line(
|
|
46
|
+
`${as.green("[SUCCESS]")} ${as.green("Configuration is valid:")} ${as.green(parseConfigResult.filePath)}`
|
|
47
|
+
).print();
|
|
48
|
+
}
|
|
49
|
+
const { config } = parseConfigResult;
|
|
50
|
+
if (config.version === ConfigVersion.V2) {
|
|
51
|
+
return output.info().title("Your Scalar configuration is already upgraded").message(
|
|
52
|
+
"You are already on the latest Scalar docs version. No further action required."
|
|
53
|
+
).exit("success");
|
|
54
|
+
}
|
|
55
|
+
const upgradedConfigResult = n.fromUnsafe(
|
|
56
|
+
() => legacyTo2_0_0(config),
|
|
57
|
+
(originalError) => createError("FAILED_TO_UPGRADE_CONFIG_V1", originalError)
|
|
58
|
+
);
|
|
59
|
+
if (!upgradedConfigResult.success) {
|
|
60
|
+
return output.error().title("Could not upgrade config.").message(upgradedConfigResult.error.code).message(displayError(upgradedConfigResult.error.detail)).exit("error");
|
|
61
|
+
}
|
|
62
|
+
const { upgradedConfig, legacyTheme, legacyFooter, legacyScript } = upgradedConfigResult.data;
|
|
63
|
+
if (legacyTheme) {
|
|
64
|
+
const writeUpgradedThemeResult = await n.fromUnsafe(
|
|
65
|
+
() => fs.writeFile(
|
|
66
|
+
path.resolve(
|
|
67
|
+
path.dirname(parseConfigResult.filePath),
|
|
68
|
+
config.root ?? "./",
|
|
69
|
+
legacyTheme.path
|
|
70
|
+
),
|
|
71
|
+
legacyTheme.cssString
|
|
72
|
+
),
|
|
73
|
+
(originalError) => createError("FAILED_TO_WRITE_UPGRADED_THEME", originalError)
|
|
74
|
+
);
|
|
75
|
+
if (!writeUpgradedThemeResult.success) {
|
|
76
|
+
return output.error().title("Could not save upgraded theme.").message(writeUpgradedThemeResult.error.code).message(displayError(writeUpgradedThemeResult.error.detail)).exit("error");
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (legacyFooter) {
|
|
80
|
+
const writeUpgradedFooterResult = await n.fromUnsafe(
|
|
81
|
+
() => fs.writeFile(
|
|
82
|
+
path.resolve(
|
|
83
|
+
path.dirname(parseConfigResult.filePath),
|
|
84
|
+
config.root ?? "./",
|
|
85
|
+
legacyFooter.path
|
|
86
|
+
),
|
|
87
|
+
legacyFooter.footerString
|
|
88
|
+
),
|
|
89
|
+
(originalError) => createError("FAILED_TO_WRITE_UPGRADED_FOOTER", originalError)
|
|
90
|
+
);
|
|
91
|
+
if (!writeUpgradedFooterResult.success) {
|
|
92
|
+
return output.error().title("Could not save upgraded footer.").message(writeUpgradedFooterResult.error.code).message(displayError(writeUpgradedFooterResult.error.detail)).exit("error");
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
if (legacyScript) {
|
|
96
|
+
const writeUpgradedScriptResult = await n.fromUnsafe(
|
|
97
|
+
() => fs.writeFile(
|
|
98
|
+
path.resolve(
|
|
99
|
+
path.dirname(parseConfigResult.filePath),
|
|
100
|
+
config.root ?? "./",
|
|
101
|
+
legacyScript.path
|
|
102
|
+
),
|
|
103
|
+
legacyScript.scriptString
|
|
104
|
+
),
|
|
105
|
+
(originalError) => createError("FAILED_TO_WRITE_UPGRADED_SCRIPT", originalError)
|
|
106
|
+
);
|
|
107
|
+
if (!writeUpgradedScriptResult.success) {
|
|
108
|
+
return output.error().title("Could not save upgraded head script.").message(writeUpgradedScriptResult.error.code).message(displayError(writeUpgradedScriptResult.error.detail)).exit("error");
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
const writeUpgradedConfigResult = await n.fromUnsafe(
|
|
112
|
+
() => fs.writeFile(
|
|
113
|
+
parseConfigResult.filePath,
|
|
114
|
+
JSON.stringify(upgradedConfig, null, 2)
|
|
115
|
+
),
|
|
116
|
+
(originalError) => createError("FAILED_TO_WRITE_UPGRADED_CONFIG", originalError)
|
|
117
|
+
);
|
|
118
|
+
if (!writeUpgradedConfigResult.success) {
|
|
119
|
+
return output.error().title("Could not save upgraded config.").message(writeUpgradedConfigResult.error.code).message(displayError(writeUpgradedConfigResult.error.detail)).exit("error");
|
|
120
|
+
}
|
|
121
|
+
return output.info().title("Successfully upgraded Scalar Docs configuration!").message("Run `scalar project preview` to preview your project").exit("success");
|
|
122
|
+
}
|
|
123
|
+
export {
|
|
124
|
+
upgradeAction
|
|
125
|
+
};
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import { createRequire as $$cR } from "node:module"; const require = $$cR(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
openBrowser
|
|
4
|
+
} from "./chunk-JFIXNSPP.js";
|
|
5
|
+
import {
|
|
6
|
+
accessTokenPayloadSchema,
|
|
7
|
+
decode,
|
|
8
|
+
generateAccessByPersonalToken,
|
|
9
|
+
setAuthData,
|
|
10
|
+
tokenResponseSchema
|
|
11
|
+
} from "./chunk-M37TP6U2.js";
|
|
12
|
+
import {
|
|
13
|
+
config
|
|
14
|
+
} from "./chunk-4ZDQXWBT.js";
|
|
15
|
+
import "./chunk-VNYE4R7N.js";
|
|
16
|
+
import "./chunk-OQKDBLOZ.js";
|
|
17
|
+
import "./chunk-4ORL4MST.js";
|
|
18
|
+
import {
|
|
19
|
+
output
|
|
20
|
+
} from "./chunk-T5HJUAWB.js";
|
|
21
|
+
import {
|
|
22
|
+
external_exports
|
|
23
|
+
} from "./chunk-IKT5F47M.js";
|
|
24
|
+
import "./chunk-3MZYUBJ6.js";
|
|
25
|
+
|
|
26
|
+
// src/domains/auth/login/action.ts
|
|
27
|
+
import as2 from "ansis";
|
|
28
|
+
|
|
29
|
+
// ../../packages/mongobase-client/dist/auth/node/exchange-callback-server.js
|
|
30
|
+
import getPort from "get-port";
|
|
31
|
+
var generateTokenCallbackEndpoint = async (exchangeUrl) => {
|
|
32
|
+
const http = await import("node:http");
|
|
33
|
+
const port = await getPort();
|
|
34
|
+
const server = http.createServer();
|
|
35
|
+
server.listen({ port, host: "127.0.0.1" });
|
|
36
|
+
const getTokens = async () => {
|
|
37
|
+
const resultPromise = new Promise((resolve) => {
|
|
38
|
+
server.on("request", async (req, res) => {
|
|
39
|
+
const corsOrigin = `http://127.0.0.1:${port}`;
|
|
40
|
+
const errorResponse = (message, code) => {
|
|
41
|
+
res.writeHead(code, {
|
|
42
|
+
"Content-Type": "application/json",
|
|
43
|
+
"Access-Control-Allow-Origin": corsOrigin
|
|
44
|
+
});
|
|
45
|
+
res.end(JSON.stringify({
|
|
46
|
+
success: false,
|
|
47
|
+
error: true,
|
|
48
|
+
message
|
|
49
|
+
}));
|
|
50
|
+
server.close();
|
|
51
|
+
return resolve({ data: null, error: true });
|
|
52
|
+
};
|
|
53
|
+
if (req.method !== "POST") {
|
|
54
|
+
return errorResponse("Method not allowed", 405);
|
|
55
|
+
}
|
|
56
|
+
const url = new URL(`http://localhost:${port}${req.url}`);
|
|
57
|
+
const exchangeToken = url.searchParams.get("exchangeToken");
|
|
58
|
+
if (!exchangeToken) {
|
|
59
|
+
return errorResponse("Missing exchange token", 400);
|
|
60
|
+
}
|
|
61
|
+
try {
|
|
62
|
+
const tokens = await exchangeTokenForAccess(exchangeUrl, exchangeToken);
|
|
63
|
+
if (tokens) {
|
|
64
|
+
res.writeHead(200, {
|
|
65
|
+
"Content-Type": "application/json",
|
|
66
|
+
"Access-Control-Allow-Origin": corsOrigin
|
|
67
|
+
});
|
|
68
|
+
res.end(JSON.stringify({
|
|
69
|
+
success: true,
|
|
70
|
+
error: false,
|
|
71
|
+
message: "Token exchanged. "
|
|
72
|
+
}));
|
|
73
|
+
server.close();
|
|
74
|
+
return resolve({ data: tokens, error: false });
|
|
75
|
+
}
|
|
76
|
+
return errorResponse("Failed to exchange token", 400);
|
|
77
|
+
} catch (err) {
|
|
78
|
+
console.error(err);
|
|
79
|
+
return errorResponse("Internal server error", 500);
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
const timeoutPromise = new Promise((resolve) => {
|
|
84
|
+
setTimeout(() => {
|
|
85
|
+
server.close();
|
|
86
|
+
resolve({ data: null, error: true });
|
|
87
|
+
}, 3 * 60 * 1e3);
|
|
88
|
+
});
|
|
89
|
+
return Promise.race([resultPromise, timeoutPromise]);
|
|
90
|
+
};
|
|
91
|
+
return {
|
|
92
|
+
port,
|
|
93
|
+
cancel: () => server.close(),
|
|
94
|
+
getTokens
|
|
95
|
+
};
|
|
96
|
+
};
|
|
97
|
+
var exchangeTokenForAccess = async (serverUrl, exchangeToken) => {
|
|
98
|
+
const result = await fetch(serverUrl, {
|
|
99
|
+
method: "POST",
|
|
100
|
+
headers: {
|
|
101
|
+
"Content-Type": "application/json"
|
|
102
|
+
},
|
|
103
|
+
body: JSON.stringify({
|
|
104
|
+
exchangeToken
|
|
105
|
+
})
|
|
106
|
+
});
|
|
107
|
+
if (result.ok) {
|
|
108
|
+
return tokenResponseSchema.parse(await result.json());
|
|
109
|
+
}
|
|
110
|
+
return null;
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
// src/domains/auth/login/helpers/messages.ts
|
|
114
|
+
import as from "ansis";
|
|
115
|
+
function loggedInMessage(userIdentifier) {
|
|
116
|
+
if (process.env.CI || !userIdentifier)
|
|
117
|
+
return "Successfully authenticated to Scalar CLI";
|
|
118
|
+
return `Successfully authenticated to Scalar CLI as ${as.cyan(userIdentifier)}`;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// src/domains/auth/login/helpers/email-pass-auth.ts
|
|
122
|
+
var tokenResponseSchema2 = external_exports.object({
|
|
123
|
+
accessToken: external_exports.string(),
|
|
124
|
+
refreshToken: external_exports.string()
|
|
125
|
+
});
|
|
126
|
+
var emailPasswordAuth = async ({
|
|
127
|
+
email,
|
|
128
|
+
password
|
|
129
|
+
}) => {
|
|
130
|
+
const result = await fetch(`${config.services.api}/core/login/email`, {
|
|
131
|
+
method: "POST",
|
|
132
|
+
headers: {
|
|
133
|
+
"Content-Type": "application/json"
|
|
134
|
+
},
|
|
135
|
+
credentials: "include",
|
|
136
|
+
body: JSON.stringify({
|
|
137
|
+
email,
|
|
138
|
+
password
|
|
139
|
+
})
|
|
140
|
+
});
|
|
141
|
+
if (!result.ok) {
|
|
142
|
+
const data = await result.json();
|
|
143
|
+
throw new Error(data.message ?? "Could not login with email");
|
|
144
|
+
}
|
|
145
|
+
return tokenResponseSchema2.parse(await result.json());
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
// src/domains/auth/login/action.ts
|
|
149
|
+
async function loginAction({
|
|
150
|
+
email,
|
|
151
|
+
password,
|
|
152
|
+
token: _token
|
|
153
|
+
}) {
|
|
154
|
+
const token = process.env.SCALAR_API_KEY || _token;
|
|
155
|
+
if (token) {
|
|
156
|
+
try {
|
|
157
|
+
const { accessToken } = await generateAccessByPersonalToken({
|
|
158
|
+
personalToken: token
|
|
159
|
+
});
|
|
160
|
+
const { email: userEmail } = decode(accessToken, accessTokenPayloadSchema);
|
|
161
|
+
output.info().message(loggedInMessage(userEmail)).print();
|
|
162
|
+
} catch (err) {
|
|
163
|
+
return output.error().title("Invalid token").message(err.message ?? "Please provide a valid personal token").exit("error");
|
|
164
|
+
}
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
if (email || password) {
|
|
168
|
+
if (!email || !password) {
|
|
169
|
+
return output.error().title("Please provide both email and password combination").message().exit("error");
|
|
170
|
+
}
|
|
171
|
+
try {
|
|
172
|
+
const { accessToken, refreshToken } = await emailPasswordAuth({
|
|
173
|
+
email,
|
|
174
|
+
password
|
|
175
|
+
});
|
|
176
|
+
await setAuthData({ accessToken, refreshToken });
|
|
177
|
+
output.info().message(loggedInMessage(email)).print();
|
|
178
|
+
} catch (err) {
|
|
179
|
+
output.error().title(err.message).print();
|
|
180
|
+
}
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
const { port, getTokens } = await generateTokenCallbackEndpoint(
|
|
184
|
+
`${config.services.api}/core/login/exchange`
|
|
185
|
+
);
|
|
186
|
+
const loginUrl = `${config.projects.dashboard}/login?externalRedirect=local&port=${port}`;
|
|
187
|
+
output.info().message(`Please follow the link to login: ${as2.cyan(loginUrl)}`).print();
|
|
188
|
+
openBrowser(loginUrl);
|
|
189
|
+
try {
|
|
190
|
+
const tokenResult = await getTokens();
|
|
191
|
+
if (tokenResult.error) throw Error("Unable to exchange token");
|
|
192
|
+
await setAuthData(tokenResult.data);
|
|
193
|
+
const { email: userEmail } = decode(
|
|
194
|
+
tokenResult.data.accessToken,
|
|
195
|
+
accessTokenPayloadSchema
|
|
196
|
+
);
|
|
197
|
+
return output.info().message(loggedInMessage(userEmail)).exit("success");
|
|
198
|
+
} catch {
|
|
199
|
+
return output.error().title("Something went wrong. Please try again.").exit("error");
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
export {
|
|
203
|
+
loginAction
|
|
204
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { createRequire as $$cR } from "node:module"; const require = $$cR(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
getFileOrUrl
|
|
4
|
+
} from "./chunk-24WAOKGG.js";
|
|
5
|
+
import {
|
|
6
|
+
require_dist
|
|
7
|
+
} from "./chunk-K74E42RV.js";
|
|
8
|
+
import "./chunk-CISTON3A.js";
|
|
9
|
+
import "./chunk-Q7DOQHZN.js";
|
|
10
|
+
import {
|
|
11
|
+
isYamlFileName
|
|
12
|
+
} from "./chunk-4ORL4MST.js";
|
|
13
|
+
import {
|
|
14
|
+
output
|
|
15
|
+
} from "./chunk-T5HJUAWB.js";
|
|
16
|
+
import "./chunk-GSGZHE26.js";
|
|
17
|
+
import "./chunk-IKT5F47M.js";
|
|
18
|
+
import {
|
|
19
|
+
__toESM
|
|
20
|
+
} from "./chunk-3MZYUBJ6.js";
|
|
21
|
+
|
|
22
|
+
// src/domains/document/postman/action.ts
|
|
23
|
+
var import_yaml = __toESM(require_dist(), 1);
|
|
24
|
+
import fs from "node:fs";
|
|
25
|
+
import as from "ansis";
|
|
26
|
+
import { convert } from "@scalar/postman-to-openapi";
|
|
27
|
+
async function convertAction(inputArgument, {
|
|
28
|
+
output: outputPath,
|
|
29
|
+
mergeOperations
|
|
30
|
+
}) {
|
|
31
|
+
const startTime = performance.now();
|
|
32
|
+
if (!inputArgument) {
|
|
33
|
+
return output.error().title("Invalid argument").message("Please provide a Postman collection file path or URL").exit("error");
|
|
34
|
+
}
|
|
35
|
+
const collection = await getFileOrUrl(inputArgument);
|
|
36
|
+
let specification;
|
|
37
|
+
try {
|
|
38
|
+
specification = convert(collection, {
|
|
39
|
+
mergeOperation: !!mergeOperations
|
|
40
|
+
});
|
|
41
|
+
} catch {
|
|
42
|
+
return output.error().title("Failed to convert Postman collection").message("The provided input is not a valid Postman collection").exit("error");
|
|
43
|
+
}
|
|
44
|
+
const openApiDocument = outputPath ? isYamlFileName(outputPath) ? import_yaml.default.stringify(specification) : JSON.stringify(specification, null, 2) : JSON.stringify(specification, null, 2);
|
|
45
|
+
if (outputPath) {
|
|
46
|
+
fs.writeFileSync(outputPath, openApiDocument, "utf8");
|
|
47
|
+
const endTime = performance.now();
|
|
48
|
+
output.info().line(
|
|
49
|
+
`${as.green("OpenAPI document generated")} ${as.grey(
|
|
50
|
+
`in ${as.white(`${as.bold(`${Math.round(endTime - startTime)}`)} ms`)}`
|
|
51
|
+
)}`
|
|
52
|
+
).line(`Written to ${as.cyan(outputPath)}`).print();
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
process.stdout.write(`${openApiDocument}
|
|
56
|
+
`);
|
|
57
|
+
}
|
|
58
|
+
export {
|
|
59
|
+
convertAction
|
|
60
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { createRequire as $$cR } from "node:module"; const require = $$cR(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
isAsyncApiDocument
|
|
4
|
+
} from "./chunk-24WAOKGG.js";
|
|
5
|
+
import "./chunk-CISTON3A.js";
|
|
6
|
+
import "./chunk-Q7DOQHZN.js";
|
|
7
|
+
import "./chunk-4ORL4MST.js";
|
|
8
|
+
import {
|
|
9
|
+
output
|
|
10
|
+
} from "./chunk-T5HJUAWB.js";
|
|
11
|
+
import "./chunk-GSGZHE26.js";
|
|
12
|
+
import "./chunk-IKT5F47M.js";
|
|
13
|
+
import "./chunk-3MZYUBJ6.js";
|
|
14
|
+
|
|
15
|
+
// src/domains/document/validate/action.ts
|
|
16
|
+
import as from "ansis";
|
|
17
|
+
import prettyjson from "prettyjson";
|
|
18
|
+
import { validate as validateAsyncApi } from "@scalar/asyncapi-validator";
|
|
19
|
+
import { bundle } from "@scalar/json-magic/bundle";
|
|
20
|
+
import { fetchUrls, readFiles } from "@scalar/json-magic/bundle/plugins/node";
|
|
21
|
+
import { validate as validateOpenApi } from "@scalar/openapi-validator";
|
|
22
|
+
async function validateAction(inputArgument) {
|
|
23
|
+
const startTime = performance.now();
|
|
24
|
+
if (!inputArgument) {
|
|
25
|
+
return output.error().title("Invalid argument").message("Please provide a file path").exit("error");
|
|
26
|
+
}
|
|
27
|
+
const document = await bundle(inputArgument, {
|
|
28
|
+
plugins: [readFiles(), fetchUrls()],
|
|
29
|
+
treeShake: false,
|
|
30
|
+
depth: -1
|
|
31
|
+
});
|
|
32
|
+
const isAsyncApi = isAsyncApiDocument(document);
|
|
33
|
+
const specification = isAsyncApi ? "AsyncAPI" : "OpenAPI";
|
|
34
|
+
const result = isAsyncApi ? validateAsyncApi(document) : validateOpenApi(document);
|
|
35
|
+
if (result.valid && result.version) {
|
|
36
|
+
const endTime = performance.now();
|
|
37
|
+
output.info().line(
|
|
38
|
+
as.green(
|
|
39
|
+
`Matches the ${specification} specification${as.white(` (${specification} ${as.bold(result.version)})`)}
|
|
40
|
+
`
|
|
41
|
+
)
|
|
42
|
+
).line(
|
|
43
|
+
`${as.green("File validated")} ${as.grey(
|
|
44
|
+
`in ${as.white(`${as.bold(`${Math.round(endTime - startTime)}`)} ms`)}
|
|
45
|
+
`
|
|
46
|
+
)}`
|
|
47
|
+
).print();
|
|
48
|
+
} else {
|
|
49
|
+
output.error().message(prettyjson.render(result.errors)).message(
|
|
50
|
+
as.red(
|
|
51
|
+
`File does not match the ${specification} ${result.version ? `${result.version} ` : ""}specification.`
|
|
52
|
+
)
|
|
53
|
+
).message(
|
|
54
|
+
as.red(
|
|
55
|
+
`${as.bold(
|
|
56
|
+
`${result.errors?.length} error${result.errors && result.errors.length > 1 ? "s" : ""}`
|
|
57
|
+
)} found.`
|
|
58
|
+
)
|
|
59
|
+
).exit("error");
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
export {
|
|
63
|
+
validateAction
|
|
64
|
+
};
|