@scalar/cli 2.0.0 → 2.1.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 (80) hide show
  1. package/README.md +42 -2
  2. package/chunks/action-45OGQB2M.js +138 -0
  3. package/chunks/action-5R5FDF6S.js +2097 -0
  4. package/chunks/action-ANU5HGC4.js +34 -0
  5. package/chunks/action-BMFXENMX.js +176 -0
  6. package/chunks/action-BNEGJBUH.js +38 -0
  7. package/chunks/action-BYZUBXVB.js +82 -0
  8. package/chunks/action-C5VB4ITT.js +132 -0
  9. package/chunks/action-CCW66QJN.js +72 -0
  10. package/chunks/action-CLSD7O2R.js +60 -0
  11. package/chunks/action-CQ56FVES.js +65 -0
  12. package/chunks/action-CYP4VDK3.js +148 -0
  13. package/chunks/action-DFKHSDFV.js +36 -0
  14. package/chunks/action-F4Y6Q2VB.js +92 -0
  15. package/chunks/action-GB6DM53B.js +70 -0
  16. package/chunks/action-GEBRPNRT.js +87 -0
  17. package/chunks/action-H5OHT2GV.js +56 -0
  18. package/chunks/action-HD2T6BFJ.js +54 -0
  19. package/chunks/action-HNKM3Q65.js +65 -0
  20. package/chunks/action-JOSVV6YA.js +71 -0
  21. package/chunks/action-MENXFJH3.js +204 -0
  22. package/chunks/action-P7LN6FGY.js +13 -0
  23. package/chunks/action-PVDDRIM6.js +130 -0
  24. package/chunks/action-Q5UJ32D6.js +46 -0
  25. package/chunks/action-R6ZZO26F.js +299 -0
  26. package/chunks/action-STIEAXOE.js +53 -0
  27. package/chunks/action-TPBKPHNS.js +110 -0
  28. package/chunks/action-TWFJNQ2R.js +95 -0
  29. package/chunks/action-TZ5KGAQT.js +64 -0
  30. package/chunks/action-UDZUUJSI.js +49 -0
  31. package/chunks/action-W5BATF4Q.js +197 -0
  32. package/chunks/agent-XGLOHXNA.js +112 -0
  33. package/chunks/build.action-LKOILPA6.js +108 -0
  34. package/chunks/chunk-23I5PKZZ.js +78 -0
  35. package/chunks/chunk-2BSG2QHO.js +455 -0
  36. package/chunks/chunk-3MZYUBJ6.js +49 -0
  37. package/chunks/chunk-47Y4L5IT.js +63361 -0
  38. package/chunks/chunk-4DGQIAJX.js +359 -0
  39. package/chunks/chunk-4QS7SJTG.js +138 -0
  40. package/chunks/chunk-5BISXQX4.js +447 -0
  41. package/chunks/chunk-5BPPGTUU.js +463 -0
  42. package/chunks/chunk-AEFPCC4U.js +16 -0
  43. package/chunks/chunk-AHWWJ3MD.js +32 -0
  44. package/chunks/chunk-ASMHW5AY.js +19 -0
  45. package/chunks/chunk-B6QZJWCQ.js +92 -0
  46. package/chunks/chunk-DOVIWNKQ.js +108 -0
  47. package/chunks/chunk-H2WRMLYY.js +13780 -0
  48. package/chunks/chunk-HQKBZOYU.js +34 -0
  49. package/chunks/chunk-ISGLWBXZ.js +4265 -0
  50. package/chunks/chunk-IX7LJ3AD.js +17 -0
  51. package/chunks/chunk-JFIXNSPP.js +26 -0
  52. package/chunks/chunk-K74E42RV.js +7311 -0
  53. package/chunks/chunk-KHDYYVYF.js +16 -0
  54. package/chunks/chunk-KWOL7A6J.js +23 -0
  55. package/chunks/chunk-NUXPNUSS.js +38 -0
  56. package/chunks/chunk-OAXFCOJV.js +25 -0
  57. package/chunks/chunk-P2VH7DOC.js +107 -0
  58. package/chunks/chunk-P646T2WH.js +1608 -0
  59. package/chunks/chunk-SHSHFGA7.js +297 -0
  60. package/chunks/chunk-SXYALPYK.js +2709 -0
  61. package/chunks/chunk-T7B6WNZC.js +18 -0
  62. package/chunks/chunk-T7MDADON.js +17 -0
  63. package/chunks/chunk-TLFMATXR.js +344 -0
  64. package/chunks/chunk-TQ5XC2E3.js +284 -0
  65. package/chunks/chunk-UPUTMFD4.js +465 -0
  66. package/chunks/chunk-VTYTPSXO.js +161 -0
  67. package/chunks/chunk-X4QLDBB5.js +221 -0
  68. package/chunks/chunk-ZTVWAKNJ.js +21 -0
  69. package/chunks/create.action-FFQLBSJH.js +108 -0
  70. package/chunks/delete.action-QNN3LC2F.js +96 -0
  71. package/chunks/delete.action-STHQHP4F.js +88 -0
  72. package/chunks/get.action-OTKYOP3Z.js +87 -0
  73. package/chunks/list.action-6I5EZAVB.js +95 -0
  74. package/chunks/list.action-KDM5RHEH.js +116 -0
  75. package/chunks/publish.action-PODTVRXS.js +182 -0
  76. package/chunks/update.action-4F6STTEQ.js +101 -0
  77. package/chunks/update.action-KMD4ZM75.js +95 -0
  78. package/docs.html +393 -230
  79. package/index.js +645 -98865
  80. package/package.json +16 -14
@@ -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-5BISXQX4.js";
12
+ import {
13
+ config
14
+ } from "./chunk-OAXFCOJV.js";
15
+ import "./chunk-4DGQIAJX.js";
16
+ import "./chunk-ISGLWBXZ.js";
17
+ import {
18
+ external_exports
19
+ } from "./chunk-H2WRMLYY.js";
20
+ import "./chunk-IX7LJ3AD.js";
21
+ import {
22
+ output
23
+ } from "./chunk-X4QLDBB5.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,13 @@
1
+ import { createRequire as $$cR } from "node:module"; const require = $$cR(import.meta.url);
2
+ import {
3
+ downloadIsolate,
4
+ updateIsolate
5
+ } from "./chunk-TQ5XC2E3.js";
6
+ import "./chunk-KWOL7A6J.js";
7
+ import "./chunk-OAXFCOJV.js";
8
+ import "./chunk-X4QLDBB5.js";
9
+ import "./chunk-3MZYUBJ6.js";
10
+ export {
11
+ downloadIsolate,
12
+ updateIsolate
13
+ };
@@ -0,0 +1,130 @@
1
+ import { createRequire as $$cR } from "node:module"; const require = $$cR(import.meta.url);
2
+ import {
3
+ loadOpenApiFile,
4
+ printSpecificationBanner
5
+ } from "./chunk-23I5PKZZ.js";
6
+ import {
7
+ watchFile
8
+ } from "./chunk-5BISXQX4.js";
9
+ import "./chunk-OAXFCOJV.js";
10
+ import "./chunk-4DGQIAJX.js";
11
+ import "./chunk-ISGLWBXZ.js";
12
+ import "./chunk-H2WRMLYY.js";
13
+ import "./chunk-IX7LJ3AD.js";
14
+ import {
15
+ output
16
+ } from "./chunk-X4QLDBB5.js";
17
+ import "./chunk-3MZYUBJ6.js";
18
+
19
+ // src/domains/document/serve/action.ts
20
+ import { serve } from "@hono/node-server";
21
+ import as from "ansis";
22
+ import { Hono } from "hono";
23
+ import { stream } from "hono/streaming";
24
+ async function serveAction(inputArgument, { watch, once, port }) {
25
+ if (!inputArgument) {
26
+ return output.error().title("Invalid argument").message("Please provide a file path").exit("error");
27
+ }
28
+ const result = await loadOpenApiFile(inputArgument);
29
+ if (!result.valid) {
30
+ return;
31
+ }
32
+ let { specification } = result;
33
+ printSpecificationBanner({
34
+ version: result.version,
35
+ schema: result.schema
36
+ });
37
+ if (specification?.paths === void 0 || Object.keys(specification?.paths).length === 0) {
38
+ output.warn().title("Could not find any paths in the OpenAPI file.").print();
39
+ }
40
+ const app = new Hono();
41
+ app.get("/", (c) => {
42
+ return c.html(getHtmlDocument(specification ?? {}, watch));
43
+ });
44
+ app.use("/__watcher", async (c, next) => {
45
+ c.header("Content-Type", "text/event-stream");
46
+ c.header("Cache-Control", "no-cache");
47
+ c.header("Connection", "keep-alive");
48
+ await next();
49
+ });
50
+ app.get("/__watcher", (c) => {
51
+ return stream(c, async (s) => {
52
+ if (watch) {
53
+ const subscription = await watchFile(inputArgument, async () => {
54
+ const newResult = await loadOpenApiFile(inputArgument);
55
+ const specificationHasChanged = newResult?.specification && JSON.stringify(specification) !== JSON.stringify(newResult.specification);
56
+ if (specificationHasChanged && newResult.valid) {
57
+ output.info().title(as.grey("OpenAPI file modified")).print();
58
+ printSpecificationBanner({
59
+ version: newResult.version,
60
+ schema: newResult.schema
61
+ });
62
+ specification = newResult.specification;
63
+ s.write("data: file modified\n\n");
64
+ }
65
+ });
66
+ if (subscription) {
67
+ s.onAbort(() => subscription.unsubscribe());
68
+ }
69
+ }
70
+ while (true) {
71
+ await new Promise((resolve) => setTimeout(resolve, 100));
72
+ }
73
+ });
74
+ });
75
+ const server = serve(
76
+ {
77
+ fetch: app.fetch,
78
+ port: port ?? 3e3
79
+ },
80
+ (info) => {
81
+ output.info().line(
82
+ `${as.green.bold("\u279C API Reference Server")} ${as.white(
83
+ "listening on"
84
+ )} ${as.cyan(`http://localhost:${info.port}`)}`
85
+ ).print();
86
+ }
87
+ );
88
+ if (once) {
89
+ setTimeout(() => {
90
+ server.close();
91
+ }, 2e3);
92
+ }
93
+ }
94
+ var getHtmlDocument = (specification, watch = false) => {
95
+ return `<!doctype html>
96
+ <html>
97
+ <head>
98
+ <title>Scalar API Reference</title>
99
+ <meta charset="utf-8" />
100
+ <meta
101
+ name="viewport"
102
+ content="width=device-width, initial-scale=1" />
103
+ <style>
104
+ body {
105
+ margin: 0;
106
+ }
107
+ </style>
108
+ ${watch ? `
109
+ <script>
110
+ const evtSource = new EventSource('__watcher');
111
+ evtSource.onmessage = (event) => {
112
+ console.log(\`message: \${event.data}\`);
113
+ window.location.reload();
114
+ };
115
+ </script>
116
+ ` : ""}
117
+ </head>
118
+ <body>
119
+ <script
120
+ id="api-reference"
121
+ type="application/json"
122
+ data-proxy-url="https://proxy.scalar.com">${JSON.stringify(specification)}</script>
123
+ <script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference"></script>
124
+ </body>
125
+ </html>`;
126
+ };
127
+ export {
128
+ getHtmlDocument,
129
+ serveAction
130
+ };
@@ -0,0 +1,46 @@
1
+ import { createRequire as $$cR } from "node:module"; const require = $$cR(import.meta.url);
2
+ import {
3
+ output
4
+ } from "./chunk-X4QLDBB5.js";
5
+ import "./chunk-3MZYUBJ6.js";
6
+
7
+ // src/domains/document/void/action.ts
8
+ import { serve } from "@hono/node-server";
9
+ import as from "ansis";
10
+ import { createVoidServer } from "@scalar/void-server";
11
+ async function voidAction({
12
+ once,
13
+ port
14
+ }) {
15
+ const server = await bootServer({
16
+ port
17
+ });
18
+ if (once) {
19
+ setTimeout(() => {
20
+ server.close();
21
+ }, 2e3);
22
+ }
23
+ }
24
+ var bootServer = async ({
25
+ port
26
+ }) => {
27
+ const app = await createVoidServer();
28
+ return serve(
29
+ {
30
+ fetch: app.fetch,
31
+ port: port ?? 3e3
32
+ },
33
+ (info) => {
34
+ output.info().line(
35
+ `${as.green.bold("\u279C Void Server")} ${as.white(
36
+ "listening on"
37
+ )} ${as.cyan(`http://localhost:${info.port}`)}
38
+ `
39
+ ).print();
40
+ }
41
+ );
42
+ };
43
+ export {
44
+ bootServer,
45
+ voidAction
46
+ };
@@ -0,0 +1,299 @@
1
+ import { createRequire as $$cR } from "node:module"; const require = $$cR(import.meta.url);
2
+ import {
3
+ getPublishDeploymentUrl
4
+ } from "./chunk-ZTVWAKNJ.js";
5
+ import {
6
+ readAndParseConfig,
7
+ renderConfigError
8
+ } from "./chunk-P2VH7DOC.js";
9
+ import {
10
+ resolveProject
11
+ } from "./chunk-T7B6WNZC.js";
12
+ import "./chunk-47Y4L5IT.js";
13
+ import "./chunk-DOVIWNKQ.js";
14
+ import {
15
+ apiService
16
+ } from "./chunk-SXYALPYK.js";
17
+ import {
18
+ getDatabaseClient
19
+ } from "./chunk-SHSHFGA7.js";
20
+ import "./chunk-UPUTMFD4.js";
21
+ import "./chunk-B6QZJWCQ.js";
22
+ import "./chunk-5BPPGTUU.js";
23
+ import "./chunk-P646T2WH.js";
24
+ import "./chunk-4QS7SJTG.js";
25
+ import "./chunk-VTYTPSXO.js";
26
+ import {
27
+ getAuthData
28
+ } from "./chunk-5BISXQX4.js";
29
+ import "./chunk-OAXFCOJV.js";
30
+ import "./chunk-TLFMATXR.js";
31
+ import "./chunk-4DGQIAJX.js";
32
+ import {
33
+ isGithubBackedDocsProject,
34
+ publishRecordSchema,
35
+ slugSchema
36
+ } from "./chunk-ISGLWBXZ.js";
37
+ import {
38
+ zod_default
39
+ } from "./chunk-H2WRMLYY.js";
40
+ import "./chunk-K74E42RV.js";
41
+ import "./chunk-IX7LJ3AD.js";
42
+ import {
43
+ output
44
+ } from "./chunk-X4QLDBB5.js";
45
+ import "./chunk-3MZYUBJ6.js";
46
+
47
+ // src/domains/project/publish/action.ts
48
+ import { dirname } from "node:path";
49
+
50
+ // src/domains/project/publish/publish.ts
51
+ import fs from "node:fs";
52
+ import path from "node:path";
53
+ import { Readable } from "node:stream";
54
+ import ignore from "ignore";
55
+ import tar from "tar-fs";
56
+ var DEFAULT_IGNORED_FILES = ["node_modules", ".git"];
57
+ function isErrnoException(error) {
58
+ return error instanceof Error && "code" in error;
59
+ }
60
+ async function readGitIgnore(configDir) {
61
+ try {
62
+ const gitignore = await fs.promises.readFile(
63
+ path.resolve(configDir, ".gitignore"),
64
+ "utf8"
65
+ );
66
+ return gitignore;
67
+ } catch (err) {
68
+ if (isErrnoException(err) && err.code === "ENOENT") return null;
69
+ throw err;
70
+ }
71
+ }
72
+ async function createProjectTar(configDir) {
73
+ const ignorer = ignore({ allowRelativePaths: true });
74
+ const gitignore = await readGitIgnore(configDir);
75
+ if (gitignore) ignorer.add(gitignore);
76
+ ignorer.add(DEFAULT_IGNORED_FILES);
77
+ return Readable.from(
78
+ tar.pack(configDir, {
79
+ ignore: (name) => ignorer.ignores(name),
80
+ dereference: true
81
+ })
82
+ );
83
+ }
84
+ async function publishGithub({
85
+ slug,
86
+ preview,
87
+ apiClient
88
+ }) {
89
+ const publishGithubResult = await apiClient.publish.publishGithub({
90
+ slug,
91
+ preview
92
+ });
93
+ if (publishGithubResult.error) {
94
+ return {
95
+ success: false,
96
+ error: publishGithubResult.message
97
+ };
98
+ }
99
+ return {
100
+ success: true,
101
+ publishUid: publishGithubResult.data.publishUid
102
+ };
103
+ }
104
+ async function publishProject({
105
+ configDir,
106
+ configPath,
107
+ config,
108
+ slug,
109
+ mode
110
+ }) {
111
+ try {
112
+ const root = path.join(configDir, config.root ?? "./");
113
+ const relativeConfigPath = path.relative(root, configPath);
114
+ const apiClient = await apiService();
115
+ const projectTar = await createProjectTar(root);
116
+ const result = await apiClient.publish.publishCli({
117
+ tarStream: Readable.toWeb(projectTar),
118
+ slug,
119
+ configPath: relativeConfigPath,
120
+ mode
121
+ });
122
+ if (result.error)
123
+ return {
124
+ success: false,
125
+ error: result.originalError ?? result.message
126
+ };
127
+ return { success: true, publishUid: result.data.publishUid };
128
+ } catch (e) {
129
+ return { success: false, error: e };
130
+ }
131
+ }
132
+ async function publishUnifiedDocsProjectFromGithub({
133
+ slug,
134
+ preview,
135
+ apiClient
136
+ }) {
137
+ const result = await apiClient.publish.publishDocsProject({
138
+ slug,
139
+ preview
140
+ });
141
+ if (result.error) {
142
+ return {
143
+ success: false,
144
+ error: result.message
145
+ };
146
+ }
147
+ return {
148
+ success: true,
149
+ publishUid: result.data.publishUid
150
+ };
151
+ }
152
+
153
+ // src/helpers/utils.ts
154
+ var sleep = (ms) => {
155
+ return new Promise((resolve) => {
156
+ setTimeout(resolve, ms);
157
+ });
158
+ };
159
+
160
+ // src/domains/project/publish/action.ts
161
+ async function publishAction(args) {
162
+ const argsParseResult = zod_default.object({
163
+ slug: slugSchema,
164
+ config: zod_default.string().optional(),
165
+ preview: zod_default.coerce.boolean().default(false),
166
+ github: zod_default.coerce.boolean().default(false)
167
+ }).safeParse(args);
168
+ if (argsParseResult.error)
169
+ return output.error().title("Invalid Arguments").message(argsParseResult.error.issues[0].message).exit("error");
170
+ const {
171
+ config: configPathOption,
172
+ slug,
173
+ preview,
174
+ github
175
+ } = argsParseResult.data;
176
+ const apiClient = await apiService();
177
+ const auth = await getAuthData();
178
+ auth.addEventListener((state) => Object.assign(auth, state));
179
+ if (!slug) {
180
+ return output.error().title("Invalid argument").message("Slug is required. Try passing --slug flag.").exit("error");
181
+ }
182
+ if (github) {
183
+ const resolved = await resolveProject(slug, apiClient);
184
+ if (resolved.kind === "not-found") {
185
+ return output.error().title("Project not found").message(`No project with slug "${slug}" was found for your team.`).exit("error");
186
+ }
187
+ if (resolved.kind === "github") {
188
+ if (!resolved.project.repository) {
189
+ return output.error().title("Your project is not linked to a GitHub repository").message(
190
+ "For a sync publish, please configure your GitHub connection through the dashboard."
191
+ ).exit("error");
192
+ }
193
+ if (resolved.project.repository.expired) {
194
+ return output.error().title("Your GitHub repository access is expired.").message(
195
+ "Please reconnect your project through the Scalar Dashboard to publish via sync."
196
+ ).exit("error");
197
+ }
198
+ const publishResult3 = await publishGithub({ apiClient, slug, preview });
199
+ if (!publishResult3.success) {
200
+ return output.error().title("Could not publish sync project.").message(publishResult3.error).exit("error");
201
+ }
202
+ return await waitForPublish({
203
+ teamUid: auth.teamUid,
204
+ publishUid: publishResult3.publishUid
205
+ });
206
+ }
207
+ if (!isGithubBackedDocsProject(resolved.project)) {
208
+ return output.error().title("Your project is not linked to a GitHub repository").message(
209
+ "For a sync publish, please configure your GitHub connection through the dashboard."
210
+ ).exit("error");
211
+ }
212
+ if (resolved.project.repository.expired) {
213
+ return output.error().title("Your GitHub repository access is expired.").message(
214
+ "Please reconnect your project through the Scalar Dashboard to publish via sync."
215
+ ).exit("error");
216
+ }
217
+ const publishResult2 = await publishUnifiedDocsProjectFromGithub({
218
+ apiClient,
219
+ slug,
220
+ preview
221
+ });
222
+ if (!publishResult2.success) {
223
+ return output.error().title("Could not publish sync project.").message(publishResult2.error).exit("error");
224
+ }
225
+ return await waitForPublish({
226
+ teamUid: auth.teamUid,
227
+ publishUid: publishResult2.publishUid
228
+ });
229
+ }
230
+ const configResult = readAndParseConfig(configPathOption ?? "");
231
+ if (!configResult.success) {
232
+ renderConfigError(configResult.error);
233
+ }
234
+ const { config, filePath: configPath } = configResult;
235
+ const publishResult = await publishProject({
236
+ config,
237
+ slug,
238
+ configDir: dirname(configPath),
239
+ configPath,
240
+ ...preview && { mode: "preview" }
241
+ });
242
+ if (!publishResult.success) {
243
+ return output.error().title("Something went wrong while deploying the project").message(
244
+ publishResult.error instanceof Error ? publishResult.error.message : publishResult.error
245
+ ).exit("error");
246
+ }
247
+ return await waitForPublish({
248
+ teamUid: auth.teamUid,
249
+ publishUid: publishResult.publishUid
250
+ });
251
+ }
252
+ async function waitForPublish({
253
+ teamUid,
254
+ publishUid
255
+ }) {
256
+ const dbClient = await getDatabaseClient();
257
+ const logger = output.info({ animate: true }).loader("Deployment in progress");
258
+ while (true) {
259
+ const deployStatus = await getDeployStatus({
260
+ client: dbClient,
261
+ publishUid,
262
+ teamUid
263
+ });
264
+ if (deployStatus.error === true) {
265
+ return output.error().title(
266
+ "Something went wrong while getting information about the deployment"
267
+ ).exit("error");
268
+ }
269
+ logger.update("loader", 0, { content: deployStatus.data.message });
270
+ if (deployStatus.data.status === "deployed") {
271
+ const deploymentUrl = getPublishDeploymentUrl(deployStatus.data);
272
+ if (deploymentUrl) {
273
+ output.info().line(
274
+ `${deployStatus.data.preview ? "Preview URL" : "Deployment URL"}: ${deploymentUrl}`
275
+ ).print();
276
+ }
277
+ logger.exit("success");
278
+ return;
279
+ }
280
+ if (deployStatus.data.status === "error") {
281
+ logger.exit("error");
282
+ }
283
+ await sleep(3e3);
284
+ }
285
+ }
286
+ async function getDeployStatus({
287
+ client,
288
+ publishUid,
289
+ teamUid
290
+ }) {
291
+ return client.getOne({
292
+ collectionPath: `team/${teamUid}/publish`,
293
+ schema: publishRecordSchema,
294
+ query: { uid: publishUid }
295
+ });
296
+ }
297
+ export {
298
+ publishAction
299
+ };