@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
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { createRequire as $$cR } from "node:module"; const require = $$cR(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
getFileOrUrl,
|
|
4
|
+
isDocument,
|
|
5
|
+
safeNormalize
|
|
6
|
+
} from "./chunk-24WAOKGG.js";
|
|
7
|
+
import {
|
|
8
|
+
require_dist
|
|
9
|
+
} from "./chunk-K74E42RV.js";
|
|
10
|
+
import "./chunk-CISTON3A.js";
|
|
11
|
+
import "./chunk-Q7DOQHZN.js";
|
|
12
|
+
import {
|
|
13
|
+
isUrl,
|
|
14
|
+
isYamlFileName
|
|
15
|
+
} from "./chunk-4ORL4MST.js";
|
|
16
|
+
import {
|
|
17
|
+
output
|
|
18
|
+
} from "./chunk-T5HJUAWB.js";
|
|
19
|
+
import "./chunk-GSGZHE26.js";
|
|
20
|
+
import "./chunk-IKT5F47M.js";
|
|
21
|
+
import {
|
|
22
|
+
__toESM
|
|
23
|
+
} from "./chunk-3MZYUBJ6.js";
|
|
24
|
+
|
|
25
|
+
// src/domains/document/format/action.ts
|
|
26
|
+
var import_yaml = __toESM(require_dist(), 1);
|
|
27
|
+
import fs from "node:fs";
|
|
28
|
+
import as from "ansis";
|
|
29
|
+
async function formatAction(inputArgument, { output: outputPath }) {
|
|
30
|
+
const startTime = performance.now();
|
|
31
|
+
if (!inputArgument) {
|
|
32
|
+
return output.error().title("Invalid argument").message("Please provide a file path").exit("error");
|
|
33
|
+
}
|
|
34
|
+
const content = await getFileOrUrl(inputArgument);
|
|
35
|
+
const document = safeNormalize(content);
|
|
36
|
+
if (!isDocument(document)) {
|
|
37
|
+
return output.error().title("Invalid input").message(
|
|
38
|
+
"Could not read a document from the input. Please provide a valid JSON or YAML file."
|
|
39
|
+
).exit("error");
|
|
40
|
+
}
|
|
41
|
+
const newContent = isYamlFileName(outputPath || inputArgument) ? (0, import_yaml.stringify)(document) : JSON.stringify(document, null, 2);
|
|
42
|
+
if (outputPath) {
|
|
43
|
+
fs.writeFileSync(outputPath, newContent, "utf8");
|
|
44
|
+
} else if (!isUrl(inputArgument)) {
|
|
45
|
+
fs.writeFileSync(inputArgument, newContent, "utf8");
|
|
46
|
+
} else {
|
|
47
|
+
return output.error().title("Invalid argument").message().message(
|
|
48
|
+
"Output file is required for URLs. Try passing --output file flag."
|
|
49
|
+
).exit("error");
|
|
50
|
+
}
|
|
51
|
+
const endTime = performance.now();
|
|
52
|
+
output.info().line(
|
|
53
|
+
`${as.green("File formatted")} ${as.grey(
|
|
54
|
+
`in ${as.white(`${as.bold(`${Math.round(endTime - startTime)}`)} ms`)}`
|
|
55
|
+
)}`
|
|
56
|
+
).print();
|
|
57
|
+
}
|
|
58
|
+
export {
|
|
59
|
+
formatAction
|
|
60
|
+
};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { createRequire as $$cR } from "node:module"; const require = $$cR(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
getFileOrUrl,
|
|
4
|
+
isAsyncApiContent
|
|
5
|
+
} from "./chunk-24WAOKGG.js";
|
|
6
|
+
import {
|
|
7
|
+
config
|
|
8
|
+
} from "./chunk-4ZDQXWBT.js";
|
|
9
|
+
import "./chunk-CISTON3A.js";
|
|
10
|
+
import "./chunk-Q7DOQHZN.js";
|
|
11
|
+
import "./chunk-4ORL4MST.js";
|
|
12
|
+
import {
|
|
13
|
+
output
|
|
14
|
+
} from "./chunk-T5HJUAWB.js";
|
|
15
|
+
import "./chunk-GSGZHE26.js";
|
|
16
|
+
import "./chunk-IKT5F47M.js";
|
|
17
|
+
import "./chunk-3MZYUBJ6.js";
|
|
18
|
+
|
|
19
|
+
// src/domains/document/share/action.ts
|
|
20
|
+
import as from "ansis";
|
|
21
|
+
async function shareAction(fileArgument, { token }) {
|
|
22
|
+
if (!fileArgument) {
|
|
23
|
+
return output.error().title("Invalid argument").message("Please provide a file path").exit("error");
|
|
24
|
+
}
|
|
25
|
+
const content = await getFileOrUrl(fileArgument);
|
|
26
|
+
const specification = isAsyncApiContent(content) ? "AsyncAPI" : "OpenAPI";
|
|
27
|
+
const sandboxUrl = new URL(config.projects.sandbox);
|
|
28
|
+
const url = new URL("/api/share", sandboxUrl);
|
|
29
|
+
url.pathname = "/api/share";
|
|
30
|
+
if (token) {
|
|
31
|
+
url.searchParams.append("token", token);
|
|
32
|
+
}
|
|
33
|
+
return fetch(url.toString(), {
|
|
34
|
+
method: "POST",
|
|
35
|
+
headers: {
|
|
36
|
+
"Content-Type": "application/json"
|
|
37
|
+
},
|
|
38
|
+
body: JSON.stringify({
|
|
39
|
+
content
|
|
40
|
+
})
|
|
41
|
+
}).then(async (response) => {
|
|
42
|
+
if (!response.ok)
|
|
43
|
+
throw new Error(`Sandbox returned HTTP ${response.status}`);
|
|
44
|
+
return response.json();
|
|
45
|
+
}).then((data) => {
|
|
46
|
+
if (data === null || typeof data !== "object" || Array.isArray(data)) {
|
|
47
|
+
throw new Error("Invalid sandbox response");
|
|
48
|
+
}
|
|
49
|
+
if (data.error || typeof data.id !== "string" || typeof data.token !== "string") {
|
|
50
|
+
throw new Error(data.message || "Invalid sandbox response");
|
|
51
|
+
}
|
|
52
|
+
const { id, token: newToken } = data;
|
|
53
|
+
const link = (pathname) => new URL(pathname, sandboxUrl).toString();
|
|
54
|
+
output.info().line(as.green.bold(`Your ${specification} file is public.`)).line().table(
|
|
55
|
+
[
|
|
56
|
+
[
|
|
57
|
+
`${as.green("\u279C")} ${as.white.bold("API Reference:")}`,
|
|
58
|
+
as.cyan(link(`/p/${id}`))
|
|
59
|
+
],
|
|
60
|
+
[
|
|
61
|
+
`${as.grey("\u279C")} ${as.grey.bold("Editor:")}`,
|
|
62
|
+
as.cyan(link(`/e/${id}`))
|
|
63
|
+
],
|
|
64
|
+
[],
|
|
65
|
+
[
|
|
66
|
+
`${as.grey("\u279C")} ${as.grey.bold(`${specification} JSON:`)}`,
|
|
67
|
+
as.cyan(link(`/files/${id}/openapi.json`))
|
|
68
|
+
],
|
|
69
|
+
[
|
|
70
|
+
`${as.grey("\u279C")} ${as.grey.bold(`${specification} YAML:`)}`,
|
|
71
|
+
as.cyan(link(`/files/${id}/openapi.yaml`))
|
|
72
|
+
]
|
|
73
|
+
],
|
|
74
|
+
{ padding: 1 }
|
|
75
|
+
).line().line("Use the token to update the existing sandbox:").line().line(
|
|
76
|
+
`${as.grey("$")} ${as.white.bold("scalar document share --token=")}${as.cyan.bold(`${newToken}`)} `
|
|
77
|
+
).line().print();
|
|
78
|
+
}).catch((error) => {
|
|
79
|
+
output.error().title("Failed to share the file.").message(`Details: ${error}`).exit("error");
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
export {
|
|
83
|
+
shareAction
|
|
84
|
+
};
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { createRequire as $$cR } from "node:module"; const require = $$cR(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
downloadIsolate
|
|
4
|
+
} from "./chunk-LFU5ZUAP.js";
|
|
5
|
+
import "./chunk-3ZJYGGAA.js";
|
|
6
|
+
import {
|
|
7
|
+
readAndParseConfig,
|
|
8
|
+
renderConfigError
|
|
9
|
+
} from "./chunk-7AGLC7WV.js";
|
|
10
|
+
import {
|
|
11
|
+
CONFIG_FILE_DEFAULT,
|
|
12
|
+
findConfig
|
|
13
|
+
} from "./chunk-PBXZN65A.js";
|
|
14
|
+
import {
|
|
15
|
+
ISOLATE_DIR
|
|
16
|
+
} from "./chunk-X5T526CE.js";
|
|
17
|
+
import {
|
|
18
|
+
getAuthData
|
|
19
|
+
} from "./chunk-M37TP6U2.js";
|
|
20
|
+
import {
|
|
21
|
+
config
|
|
22
|
+
} from "./chunk-4ZDQXWBT.js";
|
|
23
|
+
import "./chunk-VNYE4R7N.js";
|
|
24
|
+
import {
|
|
25
|
+
ConfigVersion
|
|
26
|
+
} from "./chunk-OQKDBLOZ.js";
|
|
27
|
+
import "./chunk-K74E42RV.js";
|
|
28
|
+
import "./chunk-CISTON3A.js";
|
|
29
|
+
import "./chunk-Q7DOQHZN.js";
|
|
30
|
+
import "./chunk-4ORL4MST.js";
|
|
31
|
+
import {
|
|
32
|
+
output
|
|
33
|
+
} from "./chunk-T5HJUAWB.js";
|
|
34
|
+
import "./chunk-GSGZHE26.js";
|
|
35
|
+
import "./chunk-IKT5F47M.js";
|
|
36
|
+
import "./chunk-3MZYUBJ6.js";
|
|
37
|
+
|
|
38
|
+
// src/domains/project/preview/action.ts
|
|
39
|
+
import { text } from "@clack/prompts";
|
|
40
|
+
import as from "ansis";
|
|
41
|
+
|
|
42
|
+
// src/domains/project/preview/v2.ts
|
|
43
|
+
import { spawn } from "node:child_process";
|
|
44
|
+
import path from "node:path";
|
|
45
|
+
async function runIsolate(isolateOptions) {
|
|
46
|
+
const executable = process.env.SCALAR_CLI_DISTRIBUTION === "portable" ? path.join(
|
|
47
|
+
path.dirname(process.execPath),
|
|
48
|
+
"runtime",
|
|
49
|
+
process.platform === "win32" ? "node.exe" : "node"
|
|
50
|
+
) : process.execPath;
|
|
51
|
+
const child = spawn(executable, ["dist/isolate-entry.js"], {
|
|
52
|
+
cwd: ISOLATE_DIR,
|
|
53
|
+
env: {
|
|
54
|
+
...process.env,
|
|
55
|
+
PATH: `${path.dirname(executable)}${path.delimiter}${process.env.PATH ?? ""}`
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
child.stdin.write(JSON.stringify(isolateOptions));
|
|
59
|
+
child.stdin.end();
|
|
60
|
+
child.stdout.pipe(process.stdout);
|
|
61
|
+
child.stderr.pipe(process.stderr);
|
|
62
|
+
child.on("error", (error) => {
|
|
63
|
+
console.error(`Could not start docs preview: ${error.message}`);
|
|
64
|
+
process.exitCode = 1;
|
|
65
|
+
});
|
|
66
|
+
child.on("close", (code, signal) => {
|
|
67
|
+
console.log(
|
|
68
|
+
`Process exited with code ${code}${signal ? ` (signal ${signal})` : ""}.`
|
|
69
|
+
);
|
|
70
|
+
process.exitCode = code ?? 1;
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
async function getAccessToken() {
|
|
74
|
+
try {
|
|
75
|
+
const { accessToken } = await getAuthData({ noExit: true });
|
|
76
|
+
return accessToken;
|
|
77
|
+
} catch {
|
|
78
|
+
output.info().message(
|
|
79
|
+
"You're not signed in. Private Scalar content will not be fetched."
|
|
80
|
+
).print();
|
|
81
|
+
return "";
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
async function previewV2Project({
|
|
85
|
+
logLevel,
|
|
86
|
+
configPath,
|
|
87
|
+
port,
|
|
88
|
+
config: config2,
|
|
89
|
+
host
|
|
90
|
+
}) {
|
|
91
|
+
const root = path.resolve(path.dirname(configPath), config2.root ?? "./");
|
|
92
|
+
const relativeConfigPath = path.relative(root, configPath);
|
|
93
|
+
const accessToken = await getAccessToken();
|
|
94
|
+
await downloadIsolate();
|
|
95
|
+
output.info().message("Starting preview...").print();
|
|
96
|
+
await runIsolate({
|
|
97
|
+
configPath: relativeConfigPath,
|
|
98
|
+
projectDir: root,
|
|
99
|
+
logLevel,
|
|
100
|
+
domain: "localhost",
|
|
101
|
+
mode: "preview",
|
|
102
|
+
previewServerPort: port,
|
|
103
|
+
registryBaseUrl: config.projects.registry,
|
|
104
|
+
baseUrl: config.services.api,
|
|
105
|
+
token: accessToken,
|
|
106
|
+
host
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// src/domains/project/preview/action.ts
|
|
111
|
+
async function previewAction(__configPath, options) {
|
|
112
|
+
const _port = Number.parseInt(options.port || "7970", 10);
|
|
113
|
+
if (Number.isNaN(_port)) {
|
|
114
|
+
return output.error().title("Invalid port").message("Please provide a valid port number").exit("error");
|
|
115
|
+
}
|
|
116
|
+
if (_port < 0 || _port > 65535) {
|
|
117
|
+
return output.error().title("Invalid port").message("Port number must be between 0 and 65535").exit("error");
|
|
118
|
+
}
|
|
119
|
+
const configPath = __configPath || findConfig() || await text({
|
|
120
|
+
message: "Where is your configuration file located?",
|
|
121
|
+
defaultValue: CONFIG_FILE_DEFAULT,
|
|
122
|
+
placeholder: CONFIG_FILE_DEFAULT
|
|
123
|
+
});
|
|
124
|
+
const parseConfigResult = readAndParseConfig(configPath);
|
|
125
|
+
if (!parseConfigResult.success) {
|
|
126
|
+
renderConfigError(parseConfigResult.error);
|
|
127
|
+
}
|
|
128
|
+
if (parseConfigResult.success) {
|
|
129
|
+
output.info().line(
|
|
130
|
+
`${as.green("[SUCCESS]")} ${as.green("Configuration is valid:")} ${as.green(parseConfigResult.filePath)}`
|
|
131
|
+
).print();
|
|
132
|
+
}
|
|
133
|
+
const { config: config2 } = parseConfigResult;
|
|
134
|
+
if (config2.version === ConfigVersion.V1) {
|
|
135
|
+
return output.error().title("V1 Preview is no longer supported.").message("Please upgrade your project with `scalar project upgrade`").exit("error");
|
|
136
|
+
}
|
|
137
|
+
if (config2.version === ConfigVersion.V2) {
|
|
138
|
+
await previewV2Project({
|
|
139
|
+
logLevel: options.logLevel,
|
|
140
|
+
configPath,
|
|
141
|
+
config: config2,
|
|
142
|
+
port: _port,
|
|
143
|
+
host: options.host
|
|
144
|
+
});
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
export {
|
|
149
|
+
previewAction
|
|
150
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { createRequire as $$cR } from "node:module"; const require = $$cR(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
IsolateDownloadError,
|
|
4
|
+
downloadIsolate,
|
|
5
|
+
isDiskWriteError,
|
|
6
|
+
updateIsolate
|
|
7
|
+
} from "./chunk-LFU5ZUAP.js";
|
|
8
|
+
import "./chunk-3ZJYGGAA.js";
|
|
9
|
+
import "./chunk-X5T526CE.js";
|
|
10
|
+
import "./chunk-4ZDQXWBT.js";
|
|
11
|
+
import "./chunk-T5HJUAWB.js";
|
|
12
|
+
import "./chunk-3MZYUBJ6.js";
|
|
13
|
+
export {
|
|
14
|
+
IsolateDownloadError,
|
|
15
|
+
downloadIsolate,
|
|
16
|
+
isDiskWriteError,
|
|
17
|
+
updateIsolate
|
|
18
|
+
};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { createRequire as $$cR } from "node:module"; const require = $$cR(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
apiService
|
|
4
|
+
} from "./chunk-AO3F5XWR.js";
|
|
5
|
+
import "./chunk-HCPN3KNF.js";
|
|
6
|
+
import "./chunk-B2MHTD3R.js";
|
|
7
|
+
import "./chunk-3L6DLIXJ.js";
|
|
8
|
+
import "./chunk-P7H7GY5A.js";
|
|
9
|
+
import "./chunk-HPL3ZZ2P.js";
|
|
10
|
+
import "./chunk-M37TP6U2.js";
|
|
11
|
+
import "./chunk-4ZDQXWBT.js";
|
|
12
|
+
import "./chunk-VNYE4R7N.js";
|
|
13
|
+
import "./chunk-OQKDBLOZ.js";
|
|
14
|
+
import "./chunk-K74E42RV.js";
|
|
15
|
+
import "./chunk-CISTON3A.js";
|
|
16
|
+
import "./chunk-Q7DOQHZN.js";
|
|
17
|
+
import "./chunk-4ORL4MST.js";
|
|
18
|
+
import {
|
|
19
|
+
output
|
|
20
|
+
} from "./chunk-T5HJUAWB.js";
|
|
21
|
+
import "./chunk-GSGZHE26.js";
|
|
22
|
+
import "./chunk-IKT5F47M.js";
|
|
23
|
+
import "./chunk-3MZYUBJ6.js";
|
|
24
|
+
|
|
25
|
+
// src/domains/project/create/action.ts
|
|
26
|
+
import { text } from "@clack/prompts";
|
|
27
|
+
import as from "ansis";
|
|
28
|
+
async function createAction({
|
|
29
|
+
name,
|
|
30
|
+
slug
|
|
31
|
+
}) {
|
|
32
|
+
const apiClient = await apiService();
|
|
33
|
+
let nameValue = name;
|
|
34
|
+
let slugValue = slug;
|
|
35
|
+
if (!nameValue) {
|
|
36
|
+
nameValue = await text({
|
|
37
|
+
message: "What is the name of your project?",
|
|
38
|
+
validate(value) {
|
|
39
|
+
if (value.trim().length === 0) {
|
|
40
|
+
return "You did not provide a project name. Please provide a name!";
|
|
41
|
+
}
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
if (!slugValue) {
|
|
47
|
+
slugValue = await text({
|
|
48
|
+
message: "What is the slug of your project? (Optional)",
|
|
49
|
+
defaultValue: void 0
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
const logger = output.info().loader("Creating the project");
|
|
53
|
+
const response = await apiClient.github.createProject({
|
|
54
|
+
name: nameValue,
|
|
55
|
+
slug: slugValue
|
|
56
|
+
});
|
|
57
|
+
if (response.error) {
|
|
58
|
+
return output.error().title("Something went wrong").message(response.message).exit("error");
|
|
59
|
+
}
|
|
60
|
+
logger.update("loader", 0, { content: "Project created successfully!" });
|
|
61
|
+
logger.message(
|
|
62
|
+
`Project uid: ${as.cyan(response.data.uid)}
|
|
63
|
+
Project slug: ${as.cyan(response.data.slug)}`
|
|
64
|
+
).exit("success");
|
|
65
|
+
}
|
|
66
|
+
export {
|
|
67
|
+
createAction
|
|
68
|
+
};
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { createRequire as $$cR } from "node:module"; const require = $$cR(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
dashboardUrl,
|
|
4
|
+
registryUrl
|
|
5
|
+
} from "./chunk-COBPBRQF.js";
|
|
6
|
+
import {
|
|
7
|
+
registry
|
|
8
|
+
} from "./chunk-XCSR4RIT.js";
|
|
9
|
+
import {
|
|
10
|
+
getFileOrUrl,
|
|
11
|
+
isDocument,
|
|
12
|
+
safeNormalize
|
|
13
|
+
} from "./chunk-24WAOKGG.js";
|
|
14
|
+
import {
|
|
15
|
+
DEFAULT_FETCH_CONCURRENCY
|
|
16
|
+
} from "./chunk-K4DTP5TV.js";
|
|
17
|
+
import {
|
|
18
|
+
apiService
|
|
19
|
+
} from "./chunk-AO3F5XWR.js";
|
|
20
|
+
import {
|
|
21
|
+
BaseCollections
|
|
22
|
+
} from "./chunk-F467BYYR.js";
|
|
23
|
+
import {
|
|
24
|
+
getDatabaseClient
|
|
25
|
+
} from "./chunk-Z2KMGFE6.js";
|
|
26
|
+
import "./chunk-HCPN3KNF.js";
|
|
27
|
+
import "./chunk-B2MHTD3R.js";
|
|
28
|
+
import "./chunk-3L6DLIXJ.js";
|
|
29
|
+
import "./chunk-P7H7GY5A.js";
|
|
30
|
+
import "./chunk-HPL3ZZ2P.js";
|
|
31
|
+
import {
|
|
32
|
+
getAuthData
|
|
33
|
+
} from "./chunk-M37TP6U2.js";
|
|
34
|
+
import "./chunk-4ZDQXWBT.js";
|
|
35
|
+
import {
|
|
36
|
+
teamSchema
|
|
37
|
+
} from "./chunk-VNYE4R7N.js";
|
|
38
|
+
import "./chunk-OQKDBLOZ.js";
|
|
39
|
+
import "./chunk-K74E42RV.js";
|
|
40
|
+
import {
|
|
41
|
+
RegistryAsset
|
|
42
|
+
} from "./chunk-CISTON3A.js";
|
|
43
|
+
import "./chunk-Q7DOQHZN.js";
|
|
44
|
+
import {
|
|
45
|
+
isUrl
|
|
46
|
+
} from "./chunk-4ORL4MST.js";
|
|
47
|
+
import {
|
|
48
|
+
output
|
|
49
|
+
} from "./chunk-T5HJUAWB.js";
|
|
50
|
+
import "./chunk-GSGZHE26.js";
|
|
51
|
+
import {
|
|
52
|
+
docVersionSchema,
|
|
53
|
+
external_exports,
|
|
54
|
+
namespaceSchema,
|
|
55
|
+
slugSchema,
|
|
56
|
+
toAsciiSlug
|
|
57
|
+
} from "./chunk-IKT5F47M.js";
|
|
58
|
+
import "./chunk-3MZYUBJ6.js";
|
|
59
|
+
|
|
60
|
+
// src/domains/registry/publish/action.ts
|
|
61
|
+
import { text } from "@clack/prompts";
|
|
62
|
+
import as from "ansis";
|
|
63
|
+
import { bundle } from "@scalar/json-magic/bundle";
|
|
64
|
+
import { fetchUrls, readFiles } from "@scalar/json-magic/bundle/plugins/node";
|
|
65
|
+
async function publishAction(file, args) {
|
|
66
|
+
const { error, data } = external_exports.object({
|
|
67
|
+
slug: slugSchema.optional(),
|
|
68
|
+
file: external_exports.string().min(1, "Please provide a valid file path or URL for your document.").optional(),
|
|
69
|
+
namespace: namespaceSchema.optional(),
|
|
70
|
+
version: docVersionSchema.optional(),
|
|
71
|
+
private: external_exports.coerce.boolean(),
|
|
72
|
+
current: external_exports.coerce.boolean(),
|
|
73
|
+
force: external_exports.coerce.boolean(),
|
|
74
|
+
bundle: external_exports.coerce.boolean().optional(),
|
|
75
|
+
fetchLimit: external_exports.coerce.number().optional(),
|
|
76
|
+
urlMap: external_exports.coerce.boolean().default(false),
|
|
77
|
+
treeShake: external_exports.coerce.boolean().default(false)
|
|
78
|
+
}).safeParse({
|
|
79
|
+
file,
|
|
80
|
+
slug: args.slug,
|
|
81
|
+
namespace: args.namespace,
|
|
82
|
+
version: args.version,
|
|
83
|
+
private: args.private,
|
|
84
|
+
current: args.current,
|
|
85
|
+
force: args.force
|
|
86
|
+
});
|
|
87
|
+
if (error)
|
|
88
|
+
return output.error().title("Invalid input").message(error.issues[0].message).exit("error");
|
|
89
|
+
const auth = await getAuthData();
|
|
90
|
+
auth.addEventListener((state) => Object.assign(auth, state));
|
|
91
|
+
const db = await getDatabaseClient();
|
|
92
|
+
const team = await db.getOne({
|
|
93
|
+
collectionPath: BaseCollections.Teams,
|
|
94
|
+
query: {
|
|
95
|
+
uid: auth.teamUid
|
|
96
|
+
},
|
|
97
|
+
schema: teamSchema
|
|
98
|
+
});
|
|
99
|
+
if (team.error)
|
|
100
|
+
return output.error().title("An error occurred when fetching your team.").message(team.message).exit("error");
|
|
101
|
+
const namespace = data.namespace || team.data.namespaces.at(0);
|
|
102
|
+
if (!namespace) {
|
|
103
|
+
return output.error().title("Missing namespace").message(
|
|
104
|
+
"Could not find a valid namespace for your API. Please specify a namespace or contact support."
|
|
105
|
+
).exit("error");
|
|
106
|
+
}
|
|
107
|
+
const client = await apiService();
|
|
108
|
+
const namespaceApisRes = await client.managedDocs.getApiDocs(namespace);
|
|
109
|
+
if (namespaceApisRes.error)
|
|
110
|
+
return output.error().title(namespaceApisRes.message).exit("error");
|
|
111
|
+
const apiFile = data.file || (await text({
|
|
112
|
+
message: "Please enter a file path or URL for your document",
|
|
113
|
+
placeholder: "./api.yaml",
|
|
114
|
+
validate(value) {
|
|
115
|
+
if (value.length === 0) return "File path or URL is required!";
|
|
116
|
+
}
|
|
117
|
+
})).toString();
|
|
118
|
+
const content = await getFileOrUrl(apiFile);
|
|
119
|
+
const parsed = safeNormalize(content);
|
|
120
|
+
if (!isDocument(parsed)) {
|
|
121
|
+
return output.error().title("Invalid file").message(
|
|
122
|
+
isUrl(apiFile) ? "Could not fetch or parse the document from the URL." : "Could not read or parse the document file."
|
|
123
|
+
).exit("error");
|
|
124
|
+
}
|
|
125
|
+
const bundlingPlugins = [readFiles()];
|
|
126
|
+
if (data.bundle) {
|
|
127
|
+
bundlingPlugins.push(
|
|
128
|
+
fetchUrls({
|
|
129
|
+
limit: data.fetchLimit ?? DEFAULT_FETCH_CONCURRENCY
|
|
130
|
+
})
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
const bundledDocument = await bundle(parsed, {
|
|
134
|
+
plugins: bundlingPlugins,
|
|
135
|
+
treeShake: data.treeShake,
|
|
136
|
+
urlMap: data.urlMap
|
|
137
|
+
});
|
|
138
|
+
const specification = bundledDocument;
|
|
139
|
+
const apiSlug = data.slug || toAsciiSlug(specification.info?.title ?? "");
|
|
140
|
+
const parsedVersion = docVersionSchema.safeParse(
|
|
141
|
+
data.version || specification.info?.version
|
|
142
|
+
);
|
|
143
|
+
const version = parsedVersion.data || (await text({
|
|
144
|
+
message: "What is the version of your document (e.g. 0.1.0)?",
|
|
145
|
+
validate(value) {
|
|
146
|
+
if (value.length === 0) return "Version is required.";
|
|
147
|
+
if (docVersionSchema.safeParse(value)?.error)
|
|
148
|
+
return "Version must be a non-empty string";
|
|
149
|
+
}
|
|
150
|
+
})).toString();
|
|
151
|
+
const logger = output.info().line().loader(`Publishing ${apiSlug} to Scalar registry...`);
|
|
152
|
+
const matchingApi = namespaceApisRes.data.find((api2) => api2.slug === apiSlug);
|
|
153
|
+
const document = JSON.stringify(bundledDocument);
|
|
154
|
+
const publishRes = matchingApi ? await client.managedDocs.addVersion(namespace, apiSlug, {
|
|
155
|
+
document,
|
|
156
|
+
version,
|
|
157
|
+
force: data.force,
|
|
158
|
+
isCurrent: data.current
|
|
159
|
+
}) : await client.managedDocs.create(namespace, {
|
|
160
|
+
title: specification.info?.title || "My API",
|
|
161
|
+
description: specification.info?.description,
|
|
162
|
+
version,
|
|
163
|
+
slug: apiSlug,
|
|
164
|
+
isPrivate: data.private,
|
|
165
|
+
document
|
|
166
|
+
});
|
|
167
|
+
if (publishRes.error)
|
|
168
|
+
return output.error().title(publishRes.message).exit("error");
|
|
169
|
+
logger.update("loader", 0, {
|
|
170
|
+
content: `Successfully published v${version} for ${apiSlug}.`
|
|
171
|
+
}).line().print();
|
|
172
|
+
const api = registry(namespace).apis(apiSlug);
|
|
173
|
+
const apiUrl = dashboardUrl(
|
|
174
|
+
RegistryAsset.Apis,
|
|
175
|
+
matchingApi?.uid ?? publishRes.data.uid
|
|
176
|
+
);
|
|
177
|
+
output.info().line(`${as.green("\u279C")} ${as.white.bold("View in dashboard:")}`).line(as.cyan(apiUrl)).line().line(`${as.green("\u279C")} ${as.white.bold("Registry Preview:")}`).line(as.cyan(registryUrl(api.url({ version })))).line().line(`${as.green("\u279C")} ${as.white.bold("Registry YAML:")}`).line(as.cyan(registryUrl(api.url({ version, format: "yaml" })))).line().line(`${as.green("\u279C")} ${as.white.bold("Registry JSON:")}`).line(as.cyan(registryUrl(api.url({ version, format: "json" })))).print();
|
|
178
|
+
}
|
|
179
|
+
export {
|
|
180
|
+
publishAction
|
|
181
|
+
};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { createRequire as $$cR } from "node:module"; const require = $$cR(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
apiService
|
|
4
|
+
} from "./chunk-AO3F5XWR.js";
|
|
5
|
+
import "./chunk-HCPN3KNF.js";
|
|
6
|
+
import "./chunk-B2MHTD3R.js";
|
|
7
|
+
import "./chunk-3L6DLIXJ.js";
|
|
8
|
+
import "./chunk-P7H7GY5A.js";
|
|
9
|
+
import "./chunk-HPL3ZZ2P.js";
|
|
10
|
+
import "./chunk-M37TP6U2.js";
|
|
11
|
+
import "./chunk-4ZDQXWBT.js";
|
|
12
|
+
import "./chunk-VNYE4R7N.js";
|
|
13
|
+
import "./chunk-OQKDBLOZ.js";
|
|
14
|
+
import "./chunk-K74E42RV.js";
|
|
15
|
+
import "./chunk-CISTON3A.js";
|
|
16
|
+
import "./chunk-Q7DOQHZN.js";
|
|
17
|
+
import "./chunk-4ORL4MST.js";
|
|
18
|
+
import {
|
|
19
|
+
output
|
|
20
|
+
} from "./chunk-T5HJUAWB.js";
|
|
21
|
+
import "./chunk-GSGZHE26.js";
|
|
22
|
+
import "./chunk-IKT5F47M.js";
|
|
23
|
+
import "./chunk-3MZYUBJ6.js";
|
|
24
|
+
|
|
25
|
+
// src/domains/registry/update/action.ts
|
|
26
|
+
import { text } from "@clack/prompts";
|
|
27
|
+
import as from "ansis";
|
|
28
|
+
async function updateAction(namespace, slug, { title, description }) {
|
|
29
|
+
const client = await apiService();
|
|
30
|
+
if (!namespace) {
|
|
31
|
+
return output.error().title("Invalid input").message("Please provide namespace of the document").exit("error");
|
|
32
|
+
}
|
|
33
|
+
if (!slug) {
|
|
34
|
+
return output.error().title("Invalid input").message("Please provide slug of the document").exit("error");
|
|
35
|
+
}
|
|
36
|
+
let titleValue = title;
|
|
37
|
+
let descriptionValue = description;
|
|
38
|
+
const shouldPrompt = ![title, description].some((it) => it !== void 0);
|
|
39
|
+
if (!titleValue && shouldPrompt) {
|
|
40
|
+
titleValue = await text({
|
|
41
|
+
message: `What is the new title of your document? ${as.grey("(Optional)")}`
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
if (!descriptionValue && shouldPrompt) {
|
|
45
|
+
descriptionValue = await text({
|
|
46
|
+
message: `What is the new description of your document? ${as.grey("(Optional)")}`
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
if (!titleValue && !descriptionValue) {
|
|
50
|
+
return output.error().title("Invalid input").message("Please provide any field to update").exit("error");
|
|
51
|
+
}
|
|
52
|
+
const logger = output.info().line().loader("Updating the api document");
|
|
53
|
+
const updateDocument = await client.managedDocs.update(namespace, slug, {
|
|
54
|
+
title: titleValue,
|
|
55
|
+
description: descriptionValue,
|
|
56
|
+
isPrivate: false
|
|
57
|
+
});
|
|
58
|
+
if (updateDocument.error) {
|
|
59
|
+
return output.error().title(updateDocument.message).exit("error");
|
|
60
|
+
}
|
|
61
|
+
logger.update("loader", 0, {
|
|
62
|
+
content: "Successfully updated document metadata."
|
|
63
|
+
}).print();
|
|
64
|
+
}
|
|
65
|
+
export {
|
|
66
|
+
updateAction
|
|
67
|
+
};
|