@scalar/cli 2.0.1 → 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.
- package/README.md +40 -0
- package/chunks/action-45OGQB2M.js +138 -0
- package/chunks/action-5R5FDF6S.js +2097 -0
- package/chunks/action-ANU5HGC4.js +34 -0
- package/chunks/action-BMFXENMX.js +176 -0
- package/chunks/action-BNEGJBUH.js +38 -0
- package/chunks/action-BYZUBXVB.js +82 -0
- package/chunks/action-C5VB4ITT.js +132 -0
- package/chunks/action-CCW66QJN.js +72 -0
- package/chunks/action-CLSD7O2R.js +60 -0
- package/chunks/action-CQ56FVES.js +65 -0
- package/chunks/action-CYP4VDK3.js +148 -0
- package/chunks/action-DFKHSDFV.js +36 -0
- package/chunks/action-F4Y6Q2VB.js +92 -0
- package/chunks/action-GB6DM53B.js +70 -0
- package/chunks/action-GEBRPNRT.js +87 -0
- package/chunks/action-H5OHT2GV.js +56 -0
- package/chunks/action-HD2T6BFJ.js +54 -0
- package/chunks/action-HNKM3Q65.js +65 -0
- package/chunks/action-JOSVV6YA.js +71 -0
- package/chunks/action-MENXFJH3.js +204 -0
- package/chunks/action-P7LN6FGY.js +13 -0
- package/chunks/action-PVDDRIM6.js +130 -0
- package/chunks/action-Q5UJ32D6.js +46 -0
- package/chunks/action-R6ZZO26F.js +299 -0
- package/chunks/action-STIEAXOE.js +53 -0
- package/chunks/action-TPBKPHNS.js +110 -0
- package/chunks/action-TWFJNQ2R.js +95 -0
- package/chunks/action-TZ5KGAQT.js +64 -0
- package/chunks/action-UDZUUJSI.js +49 -0
- package/chunks/action-W5BATF4Q.js +197 -0
- package/chunks/agent-XGLOHXNA.js +112 -0
- package/chunks/build.action-LKOILPA6.js +108 -0
- package/chunks/chunk-23I5PKZZ.js +78 -0
- package/chunks/chunk-2BSG2QHO.js +455 -0
- package/chunks/chunk-3MZYUBJ6.js +49 -0
- package/chunks/chunk-47Y4L5IT.js +63361 -0
- package/chunks/chunk-4DGQIAJX.js +359 -0
- package/chunks/chunk-4QS7SJTG.js +138 -0
- package/chunks/chunk-5BISXQX4.js +447 -0
- package/chunks/chunk-5BPPGTUU.js +463 -0
- package/chunks/chunk-AEFPCC4U.js +16 -0
- package/chunks/chunk-AHWWJ3MD.js +32 -0
- package/chunks/chunk-ASMHW5AY.js +19 -0
- package/chunks/chunk-B6QZJWCQ.js +92 -0
- package/chunks/chunk-DOVIWNKQ.js +108 -0
- package/chunks/chunk-H2WRMLYY.js +13780 -0
- package/chunks/chunk-HQKBZOYU.js +34 -0
- package/chunks/chunk-ISGLWBXZ.js +4265 -0
- package/chunks/chunk-IX7LJ3AD.js +17 -0
- package/chunks/chunk-JFIXNSPP.js +26 -0
- package/chunks/chunk-K74E42RV.js +7311 -0
- package/chunks/chunk-KHDYYVYF.js +16 -0
- package/chunks/chunk-KWOL7A6J.js +23 -0
- package/chunks/chunk-NUXPNUSS.js +38 -0
- package/chunks/chunk-OAXFCOJV.js +25 -0
- package/chunks/chunk-P2VH7DOC.js +107 -0
- package/chunks/chunk-P646T2WH.js +1608 -0
- package/chunks/chunk-SHSHFGA7.js +297 -0
- package/chunks/chunk-SXYALPYK.js +2709 -0
- package/chunks/chunk-T7B6WNZC.js +18 -0
- package/chunks/chunk-T7MDADON.js +17 -0
- package/chunks/chunk-TLFMATXR.js +344 -0
- package/chunks/chunk-TQ5XC2E3.js +284 -0
- package/chunks/chunk-UPUTMFD4.js +465 -0
- package/chunks/chunk-VTYTPSXO.js +161 -0
- package/chunks/chunk-X4QLDBB5.js +221 -0
- package/chunks/chunk-ZTVWAKNJ.js +21 -0
- package/chunks/create.action-FFQLBSJH.js +108 -0
- package/chunks/delete.action-QNN3LC2F.js +96 -0
- package/chunks/delete.action-STHQHP4F.js +88 -0
- package/chunks/get.action-OTKYOP3Z.js +87 -0
- package/chunks/list.action-6I5EZAVB.js +95 -0
- package/chunks/list.action-KDM5RHEH.js +116 -0
- package/chunks/publish.action-PODTVRXS.js +182 -0
- package/chunks/update.action-4F6STTEQ.js +101 -0
- package/chunks/update.action-KMD4ZM75.js +95 -0
- package/docs.html +310 -209
- package/index.js +645 -99061
- package/package.json +13 -11
|
@@ -0,0 +1,53 @@
|
|
|
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/validate/action.ts
|
|
8
|
+
import as from "ansis";
|
|
9
|
+
import prettyjson from "prettyjson";
|
|
10
|
+
import { bundle } from "@scalar/json-magic/bundle";
|
|
11
|
+
import { fetchUrls, readFiles } from "@scalar/json-magic/bundle/plugins/node";
|
|
12
|
+
import { validate } from "@scalar/openapi-parser";
|
|
13
|
+
async function validateAction(inputArgument) {
|
|
14
|
+
const startTime = performance.now();
|
|
15
|
+
if (!inputArgument) {
|
|
16
|
+
return output.error().title("Invalid argument").message("Please provide a file path").exit("error");
|
|
17
|
+
}
|
|
18
|
+
const document = await bundle(inputArgument, {
|
|
19
|
+
plugins: [readFiles(), fetchUrls()],
|
|
20
|
+
treeShake: false,
|
|
21
|
+
depth: -1
|
|
22
|
+
});
|
|
23
|
+
const result = await validate(document);
|
|
24
|
+
if (result.valid && result.version) {
|
|
25
|
+
const endTime = performance.now();
|
|
26
|
+
output.info().line(
|
|
27
|
+
as.green(
|
|
28
|
+
`Matches the OpenAPI specification${as.white(` (OpenAPI ${as.bold(result.version)})`)}
|
|
29
|
+
`
|
|
30
|
+
)
|
|
31
|
+
).line(
|
|
32
|
+
`${as.green("File validated")} ${as.grey(
|
|
33
|
+
`in ${as.white(`${as.bold(`${Math.round(endTime - startTime)}`)} ms`)}
|
|
34
|
+
`
|
|
35
|
+
)}`
|
|
36
|
+
).print();
|
|
37
|
+
} else {
|
|
38
|
+
output.error().message(prettyjson.render(result.errors)).message(
|
|
39
|
+
as.red(
|
|
40
|
+
`File does not match the OpenAPI ${result.version ? `${result.version} ` : ""}specification.`
|
|
41
|
+
)
|
|
42
|
+
).message(
|
|
43
|
+
as.red(
|
|
44
|
+
`${as.bold(
|
|
45
|
+
`${result.errors?.length} error${result.errors && result.errors.length > 1 ? "s" : ""}`
|
|
46
|
+
)} found.`
|
|
47
|
+
)
|
|
48
|
+
).exit("error");
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
export {
|
|
52
|
+
validateAction
|
|
53
|
+
};
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { createRequire as $$cR } from "node:module"; const require = $$cR(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
getProjectDeployments
|
|
4
|
+
} from "./chunk-HQKBZOYU.js";
|
|
5
|
+
import {
|
|
6
|
+
resolveProject
|
|
7
|
+
} from "./chunk-T7B6WNZC.js";
|
|
8
|
+
import {
|
|
9
|
+
formatAbsoluteTime
|
|
10
|
+
} from "./chunk-AEFPCC4U.js";
|
|
11
|
+
import {
|
|
12
|
+
apiService
|
|
13
|
+
} from "./chunk-SXYALPYK.js";
|
|
14
|
+
import "./chunk-2BSG2QHO.js";
|
|
15
|
+
import "./chunk-SHSHFGA7.js";
|
|
16
|
+
import "./chunk-UPUTMFD4.js";
|
|
17
|
+
import "./chunk-B6QZJWCQ.js";
|
|
18
|
+
import "./chunk-5BPPGTUU.js";
|
|
19
|
+
import "./chunk-P646T2WH.js";
|
|
20
|
+
import "./chunk-4QS7SJTG.js";
|
|
21
|
+
import "./chunk-VTYTPSXO.js";
|
|
22
|
+
import {
|
|
23
|
+
getAuthData
|
|
24
|
+
} from "./chunk-5BISXQX4.js";
|
|
25
|
+
import "./chunk-OAXFCOJV.js";
|
|
26
|
+
import "./chunk-TLFMATXR.js";
|
|
27
|
+
import "./chunk-4DGQIAJX.js";
|
|
28
|
+
import {
|
|
29
|
+
slugSchema
|
|
30
|
+
} from "./chunk-ISGLWBXZ.js";
|
|
31
|
+
import {
|
|
32
|
+
external_exports
|
|
33
|
+
} from "./chunk-H2WRMLYY.js";
|
|
34
|
+
import "./chunk-K74E42RV.js";
|
|
35
|
+
import "./chunk-IX7LJ3AD.js";
|
|
36
|
+
import {
|
|
37
|
+
output,
|
|
38
|
+
printTable
|
|
39
|
+
} from "./chunk-X4QLDBB5.js";
|
|
40
|
+
import "./chunk-3MZYUBJ6.js";
|
|
41
|
+
|
|
42
|
+
// src/domains/project/deployments/list/action.ts
|
|
43
|
+
import as from "ansis";
|
|
44
|
+
function colorStatus(status) {
|
|
45
|
+
switch (status) {
|
|
46
|
+
case "deployed":
|
|
47
|
+
return as.green(status);
|
|
48
|
+
case "error":
|
|
49
|
+
case "cancelled":
|
|
50
|
+
return as.red(status);
|
|
51
|
+
case "pending":
|
|
52
|
+
case "building":
|
|
53
|
+
return as.yellow(status);
|
|
54
|
+
default:
|
|
55
|
+
return as.dim(status);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
async function listAction(args) {
|
|
59
|
+
const argsParseResult = external_exports.object({ slug: slugSchema.optional() }).safeParse(args);
|
|
60
|
+
if (argsParseResult.error) {
|
|
61
|
+
return output.error().title("Invalid Arguments").message(argsParseResult.error.issues[0].message).exit("error");
|
|
62
|
+
}
|
|
63
|
+
const { slug } = argsParseResult.data;
|
|
64
|
+
if (!slug) {
|
|
65
|
+
return output.error().title("Invalid argument").message("Slug is required. Try passing --slug flag.").exit("error");
|
|
66
|
+
}
|
|
67
|
+
const apiClient = await apiService();
|
|
68
|
+
const auth = await getAuthData();
|
|
69
|
+
auth.addEventListener((state) => Object.assign(auth, state));
|
|
70
|
+
const resolved = await resolveProject(slug, apiClient);
|
|
71
|
+
if (resolved.kind === "not-found") {
|
|
72
|
+
return output.error().title("Project not found").message(`No project with slug "${slug}" was found for your team.`).exit("error");
|
|
73
|
+
}
|
|
74
|
+
const { project } = resolved;
|
|
75
|
+
const activeUid = project.activeDeployment?.uid ?? null;
|
|
76
|
+
const deploymentsResult = await getProjectDeployments({
|
|
77
|
+
teamUid: auth.teamUid,
|
|
78
|
+
projectUid: project.uid
|
|
79
|
+
});
|
|
80
|
+
if (!deploymentsResult.success) {
|
|
81
|
+
return output.error().title("Could not load deployment history").message(deploymentsResult.error).exit("error");
|
|
82
|
+
}
|
|
83
|
+
if (deploymentsResult.deployments.length === 0) {
|
|
84
|
+
output.info().title(`No deployments found for project "${slug}".`).print();
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
printTable(
|
|
88
|
+
[
|
|
89
|
+
{ name: "current", title: " ", alignment: "center" },
|
|
90
|
+
{ name: "id", title: "Build ID", alignment: "left" },
|
|
91
|
+
{ name: "status", title: "Status", alignment: "left" },
|
|
92
|
+
{ name: "deployed", title: "Deployed", alignment: "left" },
|
|
93
|
+
{ name: "commit", title: "Commit", alignment: "left" }
|
|
94
|
+
],
|
|
95
|
+
deploymentsResult.deployments.map((record) => {
|
|
96
|
+
const isLive = record.uid === activeUid;
|
|
97
|
+
const deployedAt = record.deployedAt ?? (record.status === "deployed" ? record.createdAt : null);
|
|
98
|
+
return {
|
|
99
|
+
current: isLive ? as.green("\u279C") : " ",
|
|
100
|
+
id: isLive ? as.green(record.uid) : record.uid,
|
|
101
|
+
status: colorStatus(record.status),
|
|
102
|
+
deployed: deployedAt ? formatAbsoluteTime(deployedAt * 1e3) : as.dim("\u2014"),
|
|
103
|
+
commit: record.commitSha ? record.commitSha.slice(0, 7) : as.dim("\u2014")
|
|
104
|
+
};
|
|
105
|
+
})
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
export {
|
|
109
|
+
listAction
|
|
110
|
+
};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { createRequire as $$cR } from "node:module"; const require = $$cR(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
measureTime
|
|
4
|
+
} from "./chunk-KHDYYVYF.js";
|
|
5
|
+
import "./chunk-23I5PKZZ.js";
|
|
6
|
+
import {
|
|
7
|
+
external_exports
|
|
8
|
+
} from "./chunk-H2WRMLYY.js";
|
|
9
|
+
import {
|
|
10
|
+
require_dist
|
|
11
|
+
} from "./chunk-K74E42RV.js";
|
|
12
|
+
import {
|
|
13
|
+
isYamlFileName
|
|
14
|
+
} from "./chunk-IX7LJ3AD.js";
|
|
15
|
+
import {
|
|
16
|
+
output
|
|
17
|
+
} from "./chunk-X4QLDBB5.js";
|
|
18
|
+
import {
|
|
19
|
+
__toESM
|
|
20
|
+
} from "./chunk-3MZYUBJ6.js";
|
|
21
|
+
|
|
22
|
+
// src/domains/document/join/action.ts
|
|
23
|
+
var import_yaml = __toESM(require_dist(), 1);
|
|
24
|
+
import fs from "node:fs/promises";
|
|
25
|
+
import as from "ansis";
|
|
26
|
+
import { join, normalize } from "@scalar/openapi-parser";
|
|
27
|
+
|
|
28
|
+
// src/domains/document/join/helpers.ts
|
|
29
|
+
var getValueByPath = (input, path) => {
|
|
30
|
+
return path.reduce((acc, segment) => {
|
|
31
|
+
if (acc && typeof acc === "object" && acc !== null && segment in acc) {
|
|
32
|
+
return acc[segment];
|
|
33
|
+
}
|
|
34
|
+
return void 0;
|
|
35
|
+
}, input);
|
|
36
|
+
};
|
|
37
|
+
var getPrefixes = (documents, path) => {
|
|
38
|
+
const segments = path.split(".");
|
|
39
|
+
return documents.map((doc) => {
|
|
40
|
+
const value = getValueByPath(doc, segments);
|
|
41
|
+
if (value === void 0) {
|
|
42
|
+
return "";
|
|
43
|
+
}
|
|
44
|
+
return String(value);
|
|
45
|
+
});
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
// src/domains/document/join/action.ts
|
|
49
|
+
var formatErrorMessage = (conflicts) => {
|
|
50
|
+
return conflicts.map((conflict) => {
|
|
51
|
+
if (conflict.type === "component") {
|
|
52
|
+
return `Component '/${conflict.componentType}/${conflict.name}' has conflicts`;
|
|
53
|
+
}
|
|
54
|
+
if (conflict.type === "path") {
|
|
55
|
+
return `Path '${conflict.path} ${conflict.method}' has conflicts`;
|
|
56
|
+
}
|
|
57
|
+
return `Webhook '${conflict.path} ${conflict.method}' has conflicts`;
|
|
58
|
+
});
|
|
59
|
+
};
|
|
60
|
+
async function joinAction(rawInput, rawOpt) {
|
|
61
|
+
const { error, data: input } = external_exports.array(external_exports.string()).safeParse(rawInput);
|
|
62
|
+
if (error) {
|
|
63
|
+
return output.error().title("Invalid input").message(error.issues[0].message).exit("error");
|
|
64
|
+
}
|
|
65
|
+
const { error: optsError, data: opts } = external_exports.object({
|
|
66
|
+
output: external_exports.string(),
|
|
67
|
+
prefixComponentsWithPathValue: external_exports.string().optional()
|
|
68
|
+
}).safeParse(rawOpt);
|
|
69
|
+
if (optsError) {
|
|
70
|
+
return output.error().title("Invalid options").line("").line(
|
|
71
|
+
optsError.issues.map((e) => `${e.message} property: '${e.path}'`).join("\n")
|
|
72
|
+
).line("").exit("error");
|
|
73
|
+
}
|
|
74
|
+
const files = (await Promise.all(input.map((file) => fs.readFile(file, "utf-8")))).map((it) => normalize(it));
|
|
75
|
+
const prefixes = opts.prefixComponentsWithPathValue ? getPrefixes(files, opts.prefixComponentsWithPathValue) : [];
|
|
76
|
+
const { executionTimeMs, result } = await measureTime(
|
|
77
|
+
() => join(files, { prefixComponents: prefixes })
|
|
78
|
+
);
|
|
79
|
+
if (!result.ok) {
|
|
80
|
+
return output.error().title("Failed to join OpenAPI documents").line().line(`Conflicts:
|
|
81
|
+
${formatErrorMessage(result.conflicts).join("\n")}`).line().exit("error");
|
|
82
|
+
}
|
|
83
|
+
const isYaml = isYamlFileName(opts.output);
|
|
84
|
+
await fs.writeFile(
|
|
85
|
+
opts.output,
|
|
86
|
+
isYaml ? import_yaml.default.stringify(result.document) : JSON.stringify(result.document, null, 2),
|
|
87
|
+
"utf8"
|
|
88
|
+
);
|
|
89
|
+
output.info().message(
|
|
90
|
+
`${as.green("\u{1F91D} OpenAPI Documents joined")} in ${as.white(`${as.bold(`${Math.round(executionTimeMs)}`)} ms`)}`
|
|
91
|
+
).print();
|
|
92
|
+
}
|
|
93
|
+
export {
|
|
94
|
+
joinAction
|
|
95
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { createRequire as $$cR } from "node:module"; const require = $$cR(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
apiService
|
|
4
|
+
} from "./chunk-SXYALPYK.js";
|
|
5
|
+
import "./chunk-UPUTMFD4.js";
|
|
6
|
+
import "./chunk-B6QZJWCQ.js";
|
|
7
|
+
import "./chunk-P646T2WH.js";
|
|
8
|
+
import "./chunk-4QS7SJTG.js";
|
|
9
|
+
import "./chunk-VTYTPSXO.js";
|
|
10
|
+
import "./chunk-5BISXQX4.js";
|
|
11
|
+
import "./chunk-OAXFCOJV.js";
|
|
12
|
+
import "./chunk-TLFMATXR.js";
|
|
13
|
+
import "./chunk-4DGQIAJX.js";
|
|
14
|
+
import "./chunk-ISGLWBXZ.js";
|
|
15
|
+
import "./chunk-H2WRMLYY.js";
|
|
16
|
+
import "./chunk-IX7LJ3AD.js";
|
|
17
|
+
import {
|
|
18
|
+
output
|
|
19
|
+
} from "./chunk-X4QLDBB5.js";
|
|
20
|
+
import "./chunk-3MZYUBJ6.js";
|
|
21
|
+
|
|
22
|
+
// src/domains/registry/update/action.ts
|
|
23
|
+
import { text } from "@clack/prompts";
|
|
24
|
+
import as from "ansis";
|
|
25
|
+
async function updateAction(namespace, slug, { title, description }) {
|
|
26
|
+
const client = await apiService();
|
|
27
|
+
if (!namespace) {
|
|
28
|
+
return output.error().title("Invalid input").message("Please provide namespace of the document").exit("error");
|
|
29
|
+
}
|
|
30
|
+
if (!slug) {
|
|
31
|
+
return output.error().title("Invalid input").message("Please provide slug of the document").exit("error");
|
|
32
|
+
}
|
|
33
|
+
let titleValue = title;
|
|
34
|
+
let descriptionValue = description;
|
|
35
|
+
const shouldPrompt = ![title, description].some((it) => it !== void 0);
|
|
36
|
+
if (!titleValue && shouldPrompt) {
|
|
37
|
+
titleValue = await text({
|
|
38
|
+
message: `What is the new title of your document? ${as.grey("(Optional)")}`
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
if (!descriptionValue && shouldPrompt) {
|
|
42
|
+
descriptionValue = await text({
|
|
43
|
+
message: `What is the new description of your document? ${as.grey("(Optional)")}`
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
if (!titleValue && !descriptionValue) {
|
|
47
|
+
return output.error().title("Invalid input").message("Please provide any field to update").exit("error");
|
|
48
|
+
}
|
|
49
|
+
const logger = output.info().line().loader("Updating the api document");
|
|
50
|
+
const updateDocument = await client.managedDocs.update(namespace, slug, {
|
|
51
|
+
title: titleValue,
|
|
52
|
+
description: descriptionValue,
|
|
53
|
+
isPrivate: false
|
|
54
|
+
});
|
|
55
|
+
if (updateDocument.error) {
|
|
56
|
+
return output.error().title(updateDocument.message).exit("error");
|
|
57
|
+
}
|
|
58
|
+
logger.update("loader", 0, {
|
|
59
|
+
content: "Successfully updated document metadata."
|
|
60
|
+
}).print();
|
|
61
|
+
}
|
|
62
|
+
export {
|
|
63
|
+
updateAction
|
|
64
|
+
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { createRequire as $$cR } from "node:module"; const require = $$cR(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
getFileOrUrl
|
|
4
|
+
} from "./chunk-23I5PKZZ.js";
|
|
5
|
+
import {
|
|
6
|
+
require_dist
|
|
7
|
+
} from "./chunk-K74E42RV.js";
|
|
8
|
+
import {
|
|
9
|
+
isUrl,
|
|
10
|
+
isYamlFileName
|
|
11
|
+
} from "./chunk-IX7LJ3AD.js";
|
|
12
|
+
import {
|
|
13
|
+
output
|
|
14
|
+
} from "./chunk-X4QLDBB5.js";
|
|
15
|
+
import {
|
|
16
|
+
__toESM
|
|
17
|
+
} from "./chunk-3MZYUBJ6.js";
|
|
18
|
+
|
|
19
|
+
// src/domains/document/format/action.ts
|
|
20
|
+
var import_yaml = __toESM(require_dist(), 1);
|
|
21
|
+
import fs from "node:fs";
|
|
22
|
+
import as from "ansis";
|
|
23
|
+
import { normalize, toJson } from "@scalar/openapi-parser";
|
|
24
|
+
async function formatAction(inputArgument, { output: outputPath }) {
|
|
25
|
+
const startTime = performance.now();
|
|
26
|
+
if (!inputArgument) {
|
|
27
|
+
return output.error().title("Invalid argument").message("Please provide a file path").exit("error");
|
|
28
|
+
}
|
|
29
|
+
const specification = await getFileOrUrl(inputArgument);
|
|
30
|
+
const newContent = isYamlFileName(outputPath || inputArgument) ? (0, import_yaml.stringify)(normalize(specification)) : toJson(normalize(specification));
|
|
31
|
+
if (outputPath) {
|
|
32
|
+
fs.writeFileSync(outputPath, newContent, "utf8");
|
|
33
|
+
} else if (!isUrl(inputArgument)) {
|
|
34
|
+
fs.writeFileSync(inputArgument, newContent, "utf8");
|
|
35
|
+
} else {
|
|
36
|
+
return output.error().title("Invalid argument").message().message(
|
|
37
|
+
"Output file is required for URLs. Try passing --output file flag."
|
|
38
|
+
).exit("error");
|
|
39
|
+
}
|
|
40
|
+
const endTime = performance.now();
|
|
41
|
+
output.info().line(
|
|
42
|
+
`${as.green("File formatted")} ${as.grey(
|
|
43
|
+
`in ${as.white(`${as.bold(`${Math.round(endTime - startTime)}`)} ms`)}`
|
|
44
|
+
)}`
|
|
45
|
+
).print();
|
|
46
|
+
}
|
|
47
|
+
export {
|
|
48
|
+
formatAction
|
|
49
|
+
};
|
|
@@ -0,0 +1,197 @@
|
|
|
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
|
+
getProjectDeployments
|
|
7
|
+
} from "./chunk-HQKBZOYU.js";
|
|
8
|
+
import {
|
|
9
|
+
resolveProject
|
|
10
|
+
} from "./chunk-T7B6WNZC.js";
|
|
11
|
+
import {
|
|
12
|
+
formatAbsoluteTime
|
|
13
|
+
} from "./chunk-AEFPCC4U.js";
|
|
14
|
+
import "./chunk-DOVIWNKQ.js";
|
|
15
|
+
import {
|
|
16
|
+
apiService
|
|
17
|
+
} from "./chunk-SXYALPYK.js";
|
|
18
|
+
import "./chunk-2BSG2QHO.js";
|
|
19
|
+
import "./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
|
+
slugSchema
|
|
34
|
+
} from "./chunk-ISGLWBXZ.js";
|
|
35
|
+
import {
|
|
36
|
+
external_exports
|
|
37
|
+
} from "./chunk-H2WRMLYY.js";
|
|
38
|
+
import "./chunk-K74E42RV.js";
|
|
39
|
+
import "./chunk-IX7LJ3AD.js";
|
|
40
|
+
import {
|
|
41
|
+
output
|
|
42
|
+
} from "./chunk-X4QLDBB5.js";
|
|
43
|
+
import "./chunk-3MZYUBJ6.js";
|
|
44
|
+
|
|
45
|
+
// src/domains/project/rollback/action.ts
|
|
46
|
+
import { confirm } from "@clack/prompts";
|
|
47
|
+
|
|
48
|
+
// src/domains/project/rollback/select-rollback-target.ts
|
|
49
|
+
function selectRollbackTarget({
|
|
50
|
+
deployments,
|
|
51
|
+
activeUid,
|
|
52
|
+
to
|
|
53
|
+
}) {
|
|
54
|
+
const deployed = deployments.filter((record) => record.status === "deployed");
|
|
55
|
+
if (to) {
|
|
56
|
+
const target = deployed.find((record) => record.uid === to);
|
|
57
|
+
if (!target) {
|
|
58
|
+
const existing = deployments.find((record) => record.uid === to);
|
|
59
|
+
if (existing) {
|
|
60
|
+
return {
|
|
61
|
+
success: false,
|
|
62
|
+
error: {
|
|
63
|
+
code: "target-not-deployable",
|
|
64
|
+
uid: to,
|
|
65
|
+
status: existing.status
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
return { success: false, error: { code: "target-not-found", uid: to } };
|
|
70
|
+
}
|
|
71
|
+
if (target.uid === activeUid) {
|
|
72
|
+
return { success: false, error: { code: "already-live", uid: to } };
|
|
73
|
+
}
|
|
74
|
+
return { success: true, target };
|
|
75
|
+
}
|
|
76
|
+
if (deployed.length === 0) {
|
|
77
|
+
return { success: false, error: { code: "no-history" } };
|
|
78
|
+
}
|
|
79
|
+
if (!activeUid) {
|
|
80
|
+
return { success: false, error: { code: "no-live-deployment" } };
|
|
81
|
+
}
|
|
82
|
+
const liveIndex = deployed.findIndex((record) => record.uid === activeUid);
|
|
83
|
+
if (liveIndex === -1) {
|
|
84
|
+
return { success: false, error: { code: "no-live-deployment" } };
|
|
85
|
+
}
|
|
86
|
+
const previous = deployed[liveIndex + 1];
|
|
87
|
+
if (!previous) {
|
|
88
|
+
return { success: false, error: { code: "no-previous" } };
|
|
89
|
+
}
|
|
90
|
+
return { success: true, target: previous };
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// src/domains/project/rollback/action.ts
|
|
94
|
+
var rollbackArgsSchema = external_exports.object({
|
|
95
|
+
slug: slugSchema.optional(),
|
|
96
|
+
to: external_exports.string().trim().min(1, "A build id is required for --to").optional(),
|
|
97
|
+
yes: external_exports.coerce.boolean().default(false)
|
|
98
|
+
});
|
|
99
|
+
async function rollbackAction(args) {
|
|
100
|
+
const argsParseResult = rollbackArgsSchema.safeParse(args);
|
|
101
|
+
if (argsParseResult.error) {
|
|
102
|
+
return output.error().title("Invalid Arguments").message(argsParseResult.error.issues[0].message).exit("error");
|
|
103
|
+
}
|
|
104
|
+
const { slug, to, yes } = argsParseResult.data;
|
|
105
|
+
if (!slug) {
|
|
106
|
+
return output.error().title("Invalid argument").message("Slug is required. Try passing --slug flag.").exit("error");
|
|
107
|
+
}
|
|
108
|
+
const apiClient = await apiService();
|
|
109
|
+
const auth = await getAuthData();
|
|
110
|
+
auth.addEventListener((state) => Object.assign(auth, state));
|
|
111
|
+
const resolved = await resolveProject(slug, apiClient);
|
|
112
|
+
if (resolved.kind === "not-found") {
|
|
113
|
+
return output.error().title("Project not found").message(`No project with slug "${slug}" was found for your team.`).exit("error");
|
|
114
|
+
}
|
|
115
|
+
const { project } = resolved;
|
|
116
|
+
const activeUid = project.activeDeployment?.uid ?? null;
|
|
117
|
+
const deploymentsResult = await getProjectDeployments({
|
|
118
|
+
teamUid: auth.teamUid,
|
|
119
|
+
projectUid: project.uid
|
|
120
|
+
});
|
|
121
|
+
if (!deploymentsResult.success) {
|
|
122
|
+
return output.error().title("Could not load deployment history").message(deploymentsResult.error).exit("error");
|
|
123
|
+
}
|
|
124
|
+
const targetResult = selectRollbackTarget({
|
|
125
|
+
deployments: deploymentsResult.deployments,
|
|
126
|
+
activeUid,
|
|
127
|
+
to
|
|
128
|
+
});
|
|
129
|
+
if (!targetResult.success) {
|
|
130
|
+
if (targetResult.error.code === "already-live") {
|
|
131
|
+
output.info().title("Already live").message(
|
|
132
|
+
`Build "${targetResult.error.uid}" is already the live deployment.`
|
|
133
|
+
).print();
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
return renderRollbackError(targetResult.error, slug);
|
|
137
|
+
}
|
|
138
|
+
const { target } = targetResult;
|
|
139
|
+
const deployedLabel = formatAbsoluteTime(
|
|
140
|
+
(target.deployedAt ?? target.createdAt) * 1e3
|
|
141
|
+
);
|
|
142
|
+
if (!yes) {
|
|
143
|
+
const shouldContinue = await confirm({
|
|
144
|
+
message: `Roll back the live deployment of "${slug}" to build ${target.uid} (${deployedLabel})?`,
|
|
145
|
+
initialValue: false
|
|
146
|
+
});
|
|
147
|
+
if (shouldContinue !== true) {
|
|
148
|
+
output.info().title("Rollback cancelled.").print();
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
const logger = output.info({ animate: true }).loader(`Rolling back to build ${target.uid} (${deployedLabel})`);
|
|
153
|
+
const redeployResult = await apiClient.publish.redeploy(target.uid);
|
|
154
|
+
if (redeployResult.error) {
|
|
155
|
+
logger.update("loader", 0, {
|
|
156
|
+
content: `Rollback to build ${target.uid} failed`
|
|
157
|
+
});
|
|
158
|
+
logger.finish();
|
|
159
|
+
return output.error().title("Rollback failed").message(redeployResult.message).exit("error");
|
|
160
|
+
}
|
|
161
|
+
logger.update("loader", 0, {
|
|
162
|
+
content: `Rolled back to build ${target.uid} (${deployedLabel})`
|
|
163
|
+
});
|
|
164
|
+
logger.finish();
|
|
165
|
+
const deploymentUrl = getPublishDeploymentUrl(target);
|
|
166
|
+
if (deploymentUrl) {
|
|
167
|
+
output.info().line(`Deployment URL: ${deploymentUrl}`).print();
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
function renderRollbackError(error, slug) {
|
|
171
|
+
switch (error.code) {
|
|
172
|
+
case "no-history":
|
|
173
|
+
return output.error().title("Nothing to roll back to").message(
|
|
174
|
+
`Project "${slug}" has no previous deployed builds. Publish a build first.`
|
|
175
|
+
).exit("error");
|
|
176
|
+
case "no-previous":
|
|
177
|
+
return output.error().title("Nothing to roll back to").message(
|
|
178
|
+
`Project "${slug}" is already on its oldest deployed build, so there is no earlier build to roll back to. Run "scalar project deployments list --slug ${slug}" to see all builds, then pass --to <buildId> to deploy a specific one.`
|
|
179
|
+
).exit("error");
|
|
180
|
+
case "no-live-deployment":
|
|
181
|
+
return output.error().title("No live deployment").message(
|
|
182
|
+
`Project "${slug}" has no build currently live, so there is no default to roll back to. Pass --to <buildId> to pick a specific build. Run "scalar project deployments list --slug ${slug}" to see available builds.`
|
|
183
|
+
).exit("error");
|
|
184
|
+
case "target-not-found":
|
|
185
|
+
return output.error().title("Build not found").message(
|
|
186
|
+
`No deployed build with id "${error.uid}" was found. Run "scalar project deployments list --slug ${slug}" to see available builds.`
|
|
187
|
+
).exit("error");
|
|
188
|
+
case "target-not-deployable":
|
|
189
|
+
return output.error().title("Build cannot be made live").message(
|
|
190
|
+
`Build "${error.uid}" has status "${error.status}", so it never finished deploying and cannot be rolled back to. Only builds with status "deployed" can be made live.`
|
|
191
|
+
).exit("error");
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
export {
|
|
195
|
+
rollbackAction,
|
|
196
|
+
rollbackArgsSchema
|
|
197
|
+
};
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { createRequire as $$cR } from "node:module"; const require = $$cR(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
agentApi,
|
|
4
|
+
agentApiErrorSchema,
|
|
5
|
+
analyticsGranularitySchema,
|
|
6
|
+
analyticsRangeSchema,
|
|
7
|
+
analyticsRoutes,
|
|
8
|
+
bumpKindSchema,
|
|
9
|
+
bumpStrategySchema,
|
|
10
|
+
docsProjectAgentInfoSchema,
|
|
11
|
+
docsRoutes,
|
|
12
|
+
editorChatBodySchema,
|
|
13
|
+
editorRoutes,
|
|
14
|
+
installationParamSchema,
|
|
15
|
+
installationSummarySchema,
|
|
16
|
+
installationToolSchema,
|
|
17
|
+
internalRoutes,
|
|
18
|
+
mcpAnalyticsParamsSchema,
|
|
19
|
+
mcpCategoryTotalsSchema,
|
|
20
|
+
mcpConsumerKindSchema,
|
|
21
|
+
mcpConsumerStatSchema,
|
|
22
|
+
mcpConsumersResultSchema,
|
|
23
|
+
mcpDocsPageToolDetailSchema,
|
|
24
|
+
mcpErrorEntrySchema,
|
|
25
|
+
mcpErrorsResultSchema,
|
|
26
|
+
mcpExportDatasetSchema,
|
|
27
|
+
mcpInstallationRoutes,
|
|
28
|
+
mcpLatencyByToolEntrySchema,
|
|
29
|
+
mcpLatencyResultSchema,
|
|
30
|
+
mcpOperationToolDetailSchema,
|
|
31
|
+
mcpOverviewResultSchema,
|
|
32
|
+
mcpOverviewTotalsSchema,
|
|
33
|
+
mcpServerRoutes,
|
|
34
|
+
mcpServerWithInstallationsSchema,
|
|
35
|
+
mcpTimeseriesPointSchema,
|
|
36
|
+
mcpToolCategorySchema,
|
|
37
|
+
mcpToolKindSchema,
|
|
38
|
+
mcpToolStatSchema,
|
|
39
|
+
mcpToolsResultSchema,
|
|
40
|
+
mcpVersionRoutes,
|
|
41
|
+
mcpVersionToolsSchema,
|
|
42
|
+
openapiRoutes,
|
|
43
|
+
pubsubPushMessageSchema,
|
|
44
|
+
pubsubRoutes,
|
|
45
|
+
pullRequestDescriptionBodySchema,
|
|
46
|
+
registryDocumentSchema,
|
|
47
|
+
registryRoutes,
|
|
48
|
+
registrySearchResultSchema,
|
|
49
|
+
registryVersionOperationSchema,
|
|
50
|
+
semverParamSchema,
|
|
51
|
+
teamUsageResponseSchema,
|
|
52
|
+
usageRecordSchema,
|
|
53
|
+
usageRoutes
|
|
54
|
+
} from "./chunk-P646T2WH.js";
|
|
55
|
+
import "./chunk-TLFMATXR.js";
|
|
56
|
+
import "./chunk-4DGQIAJX.js";
|
|
57
|
+
import "./chunk-ISGLWBXZ.js";
|
|
58
|
+
import "./chunk-H2WRMLYY.js";
|
|
59
|
+
import "./chunk-3MZYUBJ6.js";
|
|
60
|
+
export {
|
|
61
|
+
agentApi,
|
|
62
|
+
agentApiErrorSchema,
|
|
63
|
+
analyticsGranularitySchema,
|
|
64
|
+
analyticsRangeSchema,
|
|
65
|
+
analyticsRoutes,
|
|
66
|
+
bumpKindSchema,
|
|
67
|
+
bumpStrategySchema,
|
|
68
|
+
docsProjectAgentInfoSchema,
|
|
69
|
+
docsRoutes,
|
|
70
|
+
editorChatBodySchema,
|
|
71
|
+
editorRoutes,
|
|
72
|
+
installationParamSchema,
|
|
73
|
+
installationSummarySchema,
|
|
74
|
+
installationToolSchema,
|
|
75
|
+
internalRoutes,
|
|
76
|
+
mcpAnalyticsParamsSchema,
|
|
77
|
+
mcpCategoryTotalsSchema,
|
|
78
|
+
mcpConsumerKindSchema,
|
|
79
|
+
mcpConsumerStatSchema,
|
|
80
|
+
mcpConsumersResultSchema,
|
|
81
|
+
mcpDocsPageToolDetailSchema,
|
|
82
|
+
mcpErrorEntrySchema,
|
|
83
|
+
mcpErrorsResultSchema,
|
|
84
|
+
mcpExportDatasetSchema,
|
|
85
|
+
mcpInstallationRoutes,
|
|
86
|
+
mcpLatencyByToolEntrySchema,
|
|
87
|
+
mcpLatencyResultSchema,
|
|
88
|
+
mcpOperationToolDetailSchema,
|
|
89
|
+
mcpOverviewResultSchema,
|
|
90
|
+
mcpOverviewTotalsSchema,
|
|
91
|
+
mcpServerRoutes,
|
|
92
|
+
mcpServerWithInstallationsSchema,
|
|
93
|
+
mcpTimeseriesPointSchema,
|
|
94
|
+
mcpToolCategorySchema,
|
|
95
|
+
mcpToolKindSchema,
|
|
96
|
+
mcpToolStatSchema,
|
|
97
|
+
mcpToolsResultSchema,
|
|
98
|
+
mcpVersionRoutes,
|
|
99
|
+
mcpVersionToolsSchema,
|
|
100
|
+
openapiRoutes,
|
|
101
|
+
pubsubPushMessageSchema,
|
|
102
|
+
pubsubRoutes,
|
|
103
|
+
pullRequestDescriptionBodySchema,
|
|
104
|
+
registryDocumentSchema,
|
|
105
|
+
registryRoutes,
|
|
106
|
+
registrySearchResultSchema,
|
|
107
|
+
registryVersionOperationSchema,
|
|
108
|
+
semverParamSchema,
|
|
109
|
+
teamUsageResponseSchema,
|
|
110
|
+
usageRecordSchema,
|
|
111
|
+
usageRoutes
|
|
112
|
+
};
|