@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,34 @@
|
|
|
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/delete/action.ts
|
|
23
|
+
async function deleteAction(namespace, slug) {
|
|
24
|
+
const client = await apiService();
|
|
25
|
+
const logger = output.info().line().loader("Deleting the api document");
|
|
26
|
+
const deleteDocument = await client.managedDocs.delete(namespace, slug);
|
|
27
|
+
if (deleteDocument.error) {
|
|
28
|
+
return output.error().title(deleteDocument.message).exit("error");
|
|
29
|
+
}
|
|
30
|
+
logger.update("loader", 0, { content: "Successfully deleted document." }).print();
|
|
31
|
+
}
|
|
32
|
+
export {
|
|
33
|
+
deleteAction
|
|
34
|
+
};
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { createRequire as $$cR } from "node:module"; const require = $$cR(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
dashboardUrl,
|
|
4
|
+
registryUrl
|
|
5
|
+
} from "./chunk-T7MDADON.js";
|
|
6
|
+
import {
|
|
7
|
+
registry
|
|
8
|
+
} from "./chunk-DOVIWNKQ.js";
|
|
9
|
+
import {
|
|
10
|
+
getFileOrUrl
|
|
11
|
+
} from "./chunk-23I5PKZZ.js";
|
|
12
|
+
import {
|
|
13
|
+
DEFAULT_FETCH_CONCURRENCY
|
|
14
|
+
} from "./chunk-AHWWJ3MD.js";
|
|
15
|
+
import {
|
|
16
|
+
apiService
|
|
17
|
+
} from "./chunk-SXYALPYK.js";
|
|
18
|
+
import {
|
|
19
|
+
BaseCollections
|
|
20
|
+
} from "./chunk-2BSG2QHO.js";
|
|
21
|
+
import {
|
|
22
|
+
getDatabaseClient
|
|
23
|
+
} from "./chunk-SHSHFGA7.js";
|
|
24
|
+
import "./chunk-UPUTMFD4.js";
|
|
25
|
+
import "./chunk-B6QZJWCQ.js";
|
|
26
|
+
import "./chunk-5BPPGTUU.js";
|
|
27
|
+
import "./chunk-P646T2WH.js";
|
|
28
|
+
import {
|
|
29
|
+
RegistryAsset
|
|
30
|
+
} from "./chunk-4QS7SJTG.js";
|
|
31
|
+
import "./chunk-VTYTPSXO.js";
|
|
32
|
+
import {
|
|
33
|
+
getAuthData
|
|
34
|
+
} from "./chunk-5BISXQX4.js";
|
|
35
|
+
import "./chunk-OAXFCOJV.js";
|
|
36
|
+
import "./chunk-TLFMATXR.js";
|
|
37
|
+
import {
|
|
38
|
+
teamSchema
|
|
39
|
+
} from "./chunk-4DGQIAJX.js";
|
|
40
|
+
import {
|
|
41
|
+
docVersionSchema,
|
|
42
|
+
namespaceSchema,
|
|
43
|
+
slugSchema,
|
|
44
|
+
toAsciiSlug
|
|
45
|
+
} from "./chunk-ISGLWBXZ.js";
|
|
46
|
+
import {
|
|
47
|
+
external_exports
|
|
48
|
+
} from "./chunk-H2WRMLYY.js";
|
|
49
|
+
import "./chunk-K74E42RV.js";
|
|
50
|
+
import "./chunk-IX7LJ3AD.js";
|
|
51
|
+
import {
|
|
52
|
+
output
|
|
53
|
+
} from "./chunk-X4QLDBB5.js";
|
|
54
|
+
import "./chunk-3MZYUBJ6.js";
|
|
55
|
+
|
|
56
|
+
// src/domains/registry/publish/action.ts
|
|
57
|
+
import { text } from "@clack/prompts";
|
|
58
|
+
import as from "ansis";
|
|
59
|
+
import { bundle } from "@scalar/json-magic/bundle";
|
|
60
|
+
import { fetchUrls, readFiles } from "@scalar/json-magic/bundle/plugins/node";
|
|
61
|
+
import { parseJsonOrYaml } from "@scalar/oas-utils/helpers";
|
|
62
|
+
async function publishAction(file, args) {
|
|
63
|
+
const { error, data } = external_exports.object({
|
|
64
|
+
slug: slugSchema.optional(),
|
|
65
|
+
file: external_exports.string().min(1, "Please provide a valid file path or URL for your document.").optional(),
|
|
66
|
+
namespace: namespaceSchema.optional(),
|
|
67
|
+
version: docVersionSchema.optional(),
|
|
68
|
+
private: external_exports.coerce.boolean(),
|
|
69
|
+
current: external_exports.coerce.boolean(),
|
|
70
|
+
force: external_exports.coerce.boolean(),
|
|
71
|
+
bundle: external_exports.coerce.boolean().optional(),
|
|
72
|
+
fetchLimit: external_exports.coerce.number().optional(),
|
|
73
|
+
urlMap: external_exports.coerce.boolean().default(false),
|
|
74
|
+
treeShake: external_exports.coerce.boolean().default(false)
|
|
75
|
+
}).safeParse({
|
|
76
|
+
file,
|
|
77
|
+
slug: args.slug,
|
|
78
|
+
namespace: args.namespace,
|
|
79
|
+
version: args.version,
|
|
80
|
+
private: args.private,
|
|
81
|
+
current: args.current,
|
|
82
|
+
force: args.force
|
|
83
|
+
});
|
|
84
|
+
if (error)
|
|
85
|
+
return output.error().title("Invalid input").message(error.issues[0].message).exit("error");
|
|
86
|
+
const auth = await getAuthData();
|
|
87
|
+
auth.addEventListener((state) => Object.assign(auth, state));
|
|
88
|
+
const db = await getDatabaseClient();
|
|
89
|
+
const team = await db.getOne({
|
|
90
|
+
collectionPath: BaseCollections.Teams,
|
|
91
|
+
query: {
|
|
92
|
+
uid: auth.teamUid
|
|
93
|
+
},
|
|
94
|
+
schema: teamSchema
|
|
95
|
+
});
|
|
96
|
+
if (team.error)
|
|
97
|
+
return output.error().title("An error occurred when fetching your team.").message(team.message).exit("error");
|
|
98
|
+
const namespace = data.namespace || team.data.namespaces.at(0);
|
|
99
|
+
if (!namespace) {
|
|
100
|
+
return output.error().title("Missing namespace").message(
|
|
101
|
+
"Could not find a valid namespace for your API. Please specify a namespace or contact support."
|
|
102
|
+
).exit("error");
|
|
103
|
+
}
|
|
104
|
+
const client = await apiService();
|
|
105
|
+
const namespaceApisRes = await client.managedDocs.getApiDocs(namespace);
|
|
106
|
+
if (namespaceApisRes.error)
|
|
107
|
+
return output.error().title(namespaceApisRes.message).exit("error");
|
|
108
|
+
const apiFile = data.file || (await text({
|
|
109
|
+
message: "Please enter a file path or URL for your document",
|
|
110
|
+
placeholder: "./api.yaml",
|
|
111
|
+
validate(value) {
|
|
112
|
+
if (value.length === 0) return "File path or URL is required!";
|
|
113
|
+
}
|
|
114
|
+
})).toString();
|
|
115
|
+
const rawDocument = await getFileOrUrl(apiFile);
|
|
116
|
+
const parsed = parseJsonOrYaml(rawDocument);
|
|
117
|
+
if (!rawDocument) {
|
|
118
|
+
return output.error().title("Invalid file").message("Please provide a valid file path for your document.").exit("error");
|
|
119
|
+
}
|
|
120
|
+
const bundlingPlugins = [readFiles()];
|
|
121
|
+
if (data.bundle) {
|
|
122
|
+
bundlingPlugins.push(
|
|
123
|
+
fetchUrls({
|
|
124
|
+
limit: data.fetchLimit ?? DEFAULT_FETCH_CONCURRENCY
|
|
125
|
+
})
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
const bundledDocument = await bundle(parsed, {
|
|
129
|
+
plugins: bundlingPlugins,
|
|
130
|
+
treeShake: data.treeShake,
|
|
131
|
+
urlMap: data.urlMap
|
|
132
|
+
});
|
|
133
|
+
const specification = bundledDocument;
|
|
134
|
+
const apiSlug = data.slug || toAsciiSlug(specification.info?.title ?? "");
|
|
135
|
+
const parsedVersion = docVersionSchema.safeParse(
|
|
136
|
+
data.version || specification.info?.version
|
|
137
|
+
);
|
|
138
|
+
const version = parsedVersion.data || (await text({
|
|
139
|
+
message: "What is the version of your document (e.g. 0.1.0)?",
|
|
140
|
+
validate(value) {
|
|
141
|
+
if (value.length === 0) return "Version is required.";
|
|
142
|
+
if (docVersionSchema.safeParse(value)?.error)
|
|
143
|
+
return "Version must be a non-empty string";
|
|
144
|
+
}
|
|
145
|
+
})).toString();
|
|
146
|
+
const logger = output.info().line().loader(`Publishing ${apiSlug} to Scalar registry...`);
|
|
147
|
+
const matchingApi = namespaceApisRes.data.find((api2) => api2.slug === apiSlug);
|
|
148
|
+
const document = JSON.stringify(bundledDocument);
|
|
149
|
+
const publishRes = matchingApi ? await client.managedDocs.addVersion(namespace, apiSlug, {
|
|
150
|
+
document,
|
|
151
|
+
version,
|
|
152
|
+
force: data.force,
|
|
153
|
+
isCurrent: data.current
|
|
154
|
+
}) : await client.managedDocs.create(namespace, {
|
|
155
|
+
title: specification.info?.title || "My API",
|
|
156
|
+
description: specification.info?.description,
|
|
157
|
+
version,
|
|
158
|
+
slug: apiSlug,
|
|
159
|
+
isPrivate: data.private,
|
|
160
|
+
document
|
|
161
|
+
});
|
|
162
|
+
if (publishRes.error)
|
|
163
|
+
return output.error().title(publishRes.message).exit("error");
|
|
164
|
+
logger.update("loader", 0, {
|
|
165
|
+
content: `Successfully published v${version} for ${apiSlug}.`
|
|
166
|
+
}).line().print();
|
|
167
|
+
const api = registry(namespace).apis(apiSlug);
|
|
168
|
+
const apiUrl = dashboardUrl(
|
|
169
|
+
RegistryAsset.Apis,
|
|
170
|
+
matchingApi?.uid ?? publishRes.data.uid
|
|
171
|
+
);
|
|
172
|
+
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();
|
|
173
|
+
}
|
|
174
|
+
export {
|
|
175
|
+
publishAction
|
|
176
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { createRequire as $$cR } from "node:module"; const require = $$cR(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
readAndParseConfig,
|
|
4
|
+
renderConfigError
|
|
5
|
+
} from "./chunk-P2VH7DOC.js";
|
|
6
|
+
import "./chunk-47Y4L5IT.js";
|
|
7
|
+
import "./chunk-5BPPGTUU.js";
|
|
8
|
+
import "./chunk-4QS7SJTG.js";
|
|
9
|
+
import "./chunk-VTYTPSXO.js";
|
|
10
|
+
import "./chunk-TLFMATXR.js";
|
|
11
|
+
import "./chunk-ISGLWBXZ.js";
|
|
12
|
+
import "./chunk-H2WRMLYY.js";
|
|
13
|
+
import "./chunk-K74E42RV.js";
|
|
14
|
+
import {
|
|
15
|
+
output
|
|
16
|
+
} from "./chunk-X4QLDBB5.js";
|
|
17
|
+
import "./chunk-3MZYUBJ6.js";
|
|
18
|
+
|
|
19
|
+
// src/domains/project/check-config/action.ts
|
|
20
|
+
import as from "ansis";
|
|
21
|
+
async function checkConfigAction(inputArgument) {
|
|
22
|
+
const result = readAndParseConfig(inputArgument);
|
|
23
|
+
if (result.success) {
|
|
24
|
+
output.info().line(
|
|
25
|
+
`${as.green("[SUCCESS]")} ${as.green("The Scalar Configuration is valid:")} ${as.green(result.filePath)}`
|
|
26
|
+
).line(
|
|
27
|
+
`${as.green("Scalar Configuration validated")} ${as.grey(
|
|
28
|
+
`in ${as.white.bold(`${result.validationTime} ms`)}`
|
|
29
|
+
)}
|
|
30
|
+
`
|
|
31
|
+
).print();
|
|
32
|
+
} else {
|
|
33
|
+
renderConfigError(result.error);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
export {
|
|
37
|
+
checkConfigAction
|
|
38
|
+
};
|
|
@@ -0,0 +1,82 @@
|
|
|
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
|
+
DEFAULT_FETCH_CONCURRENCY
|
|
8
|
+
} from "./chunk-AHWWJ3MD.js";
|
|
9
|
+
import {
|
|
10
|
+
require_dist
|
|
11
|
+
} from "./chunk-K74E42RV.js";
|
|
12
|
+
import {
|
|
13
|
+
isUrl,
|
|
14
|
+
isYamlFileName
|
|
15
|
+
} from "./chunk-IX7LJ3AD.js";
|
|
16
|
+
import {
|
|
17
|
+
output
|
|
18
|
+
} from "./chunk-X4QLDBB5.js";
|
|
19
|
+
import {
|
|
20
|
+
__toESM
|
|
21
|
+
} from "./chunk-3MZYUBJ6.js";
|
|
22
|
+
|
|
23
|
+
// src/domains/document/bundle/action.ts
|
|
24
|
+
var import_yaml = __toESM(require_dist(), 1);
|
|
25
|
+
import fs from "node:fs/promises";
|
|
26
|
+
import path from "node:path";
|
|
27
|
+
import { cwd } from "node:process";
|
|
28
|
+
import { confirm } from "@clack/prompts";
|
|
29
|
+
import as from "ansis";
|
|
30
|
+
import { bundle } from "@scalar/json-magic/bundle";
|
|
31
|
+
import { fetchUrls, readFiles } from "@scalar/json-magic/bundle/plugins/node";
|
|
32
|
+
async function bundleAction(input, {
|
|
33
|
+
output: outputFilePath,
|
|
34
|
+
treeShake,
|
|
35
|
+
urlMap,
|
|
36
|
+
fetchLimit
|
|
37
|
+
}) {
|
|
38
|
+
if (!input) {
|
|
39
|
+
return output.error().title("Missing input").message("Please provide a file path or URL to bundle").exit("error");
|
|
40
|
+
}
|
|
41
|
+
const isUrlInput = isUrl(input);
|
|
42
|
+
if (!outputFilePath) {
|
|
43
|
+
if (isUrlInput) {
|
|
44
|
+
return output.error().message(
|
|
45
|
+
"Please provide an output file using the -o flag when bundling from a URL."
|
|
46
|
+
).exit("error");
|
|
47
|
+
}
|
|
48
|
+
const shouldContinue = await confirm({
|
|
49
|
+
message: "No output file specified - this will overwrite the input file. Continue?",
|
|
50
|
+
initialValue: false
|
|
51
|
+
});
|
|
52
|
+
if (shouldContinue !== true) {
|
|
53
|
+
return output.error().message("Operation cancelled by user").exit("error");
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
const outputFileName = outputFilePath ?? input;
|
|
57
|
+
const isYaml = isYamlFileName(outputFileName);
|
|
58
|
+
const resolvedInput = isUrlInput ? input : path.resolve(cwd(), input);
|
|
59
|
+
const { result, executionTimeMs } = await measureTime(
|
|
60
|
+
() => bundle(resolvedInput, {
|
|
61
|
+
plugins: [
|
|
62
|
+
readFiles(),
|
|
63
|
+
fetchUrls({
|
|
64
|
+
limit: fetchLimit ?? DEFAULT_FETCH_CONCURRENCY
|
|
65
|
+
})
|
|
66
|
+
],
|
|
67
|
+
treeShake: !!treeShake,
|
|
68
|
+
urlMap: !!urlMap
|
|
69
|
+
})
|
|
70
|
+
);
|
|
71
|
+
await fs.writeFile(
|
|
72
|
+
outputFilePath ?? input,
|
|
73
|
+
isYaml ? import_yaml.default.stringify(result) : JSON.stringify(result),
|
|
74
|
+
"utf8"
|
|
75
|
+
);
|
|
76
|
+
output.info().message(
|
|
77
|
+
`${as.green("\u{1F4E6} OpenAPI Schema bundled")} in ${as.white(`${as.bold(`${Math.round(executionTimeMs)}`)} ms`)}`
|
|
78
|
+
).print();
|
|
79
|
+
}
|
|
80
|
+
export {
|
|
81
|
+
bundleAction
|
|
82
|
+
};
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { createRequire as $$cR } from "node:module"; const require = $$cR(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
downloadIsolate
|
|
4
|
+
} from "./chunk-TQ5XC2E3.js";
|
|
5
|
+
import {
|
|
6
|
+
readAndParseConfig,
|
|
7
|
+
renderConfigError
|
|
8
|
+
} from "./chunk-P2VH7DOC.js";
|
|
9
|
+
import {
|
|
10
|
+
CONFIG_FILE_DEFAULT,
|
|
11
|
+
findConfig
|
|
12
|
+
} from "./chunk-47Y4L5IT.js";
|
|
13
|
+
import {
|
|
14
|
+
ISOLATE_DIR
|
|
15
|
+
} from "./chunk-KWOL7A6J.js";
|
|
16
|
+
import "./chunk-5BPPGTUU.js";
|
|
17
|
+
import "./chunk-4QS7SJTG.js";
|
|
18
|
+
import "./chunk-VTYTPSXO.js";
|
|
19
|
+
import {
|
|
20
|
+
getAuthData
|
|
21
|
+
} from "./chunk-5BISXQX4.js";
|
|
22
|
+
import {
|
|
23
|
+
config
|
|
24
|
+
} from "./chunk-OAXFCOJV.js";
|
|
25
|
+
import "./chunk-TLFMATXR.js";
|
|
26
|
+
import "./chunk-4DGQIAJX.js";
|
|
27
|
+
import {
|
|
28
|
+
ConfigVersion
|
|
29
|
+
} from "./chunk-ISGLWBXZ.js";
|
|
30
|
+
import "./chunk-H2WRMLYY.js";
|
|
31
|
+
import "./chunk-K74E42RV.js";
|
|
32
|
+
import "./chunk-IX7LJ3AD.js";
|
|
33
|
+
import {
|
|
34
|
+
output
|
|
35
|
+
} from "./chunk-X4QLDBB5.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 child = spawn("node", ["dist/isolate-entry.js"], { cwd: ISOLATE_DIR });
|
|
47
|
+
child.stdin.write(JSON.stringify(isolateOptions));
|
|
48
|
+
child.stdin.end();
|
|
49
|
+
child.stdout.pipe(process.stdout);
|
|
50
|
+
child.stderr.pipe(process.stderr);
|
|
51
|
+
child.on("close", (code) => {
|
|
52
|
+
console.log(`Process exited with code ${code}.`);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
async function getAccessToken() {
|
|
56
|
+
try {
|
|
57
|
+
const { accessToken } = await getAuthData({ noExit: true });
|
|
58
|
+
return accessToken;
|
|
59
|
+
} catch {
|
|
60
|
+
output.info().message(
|
|
61
|
+
"You're not signed in. Private Scalar content will not be fetched."
|
|
62
|
+
).print();
|
|
63
|
+
return "";
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
async function previewV2Project({
|
|
67
|
+
logLevel,
|
|
68
|
+
configPath,
|
|
69
|
+
port,
|
|
70
|
+
config: config2,
|
|
71
|
+
host
|
|
72
|
+
}) {
|
|
73
|
+
const root = path.resolve(path.dirname(configPath), config2.root ?? "./");
|
|
74
|
+
const relativeConfigPath = path.relative(root, configPath);
|
|
75
|
+
const accessToken = await getAccessToken();
|
|
76
|
+
await downloadIsolate();
|
|
77
|
+
output.info().message("Starting preview...").print();
|
|
78
|
+
await runIsolate({
|
|
79
|
+
configPath: relativeConfigPath,
|
|
80
|
+
projectDir: root,
|
|
81
|
+
logLevel,
|
|
82
|
+
domain: "localhost",
|
|
83
|
+
mode: "preview",
|
|
84
|
+
previewServerPort: port,
|
|
85
|
+
registryBaseUrl: config.projects.registry,
|
|
86
|
+
baseUrl: config.services.api,
|
|
87
|
+
token: accessToken,
|
|
88
|
+
host
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// src/domains/project/preview/action.ts
|
|
93
|
+
async function previewAction(__configPath, options) {
|
|
94
|
+
const _port = Number.parseInt(options.port || "7970", 10);
|
|
95
|
+
if (Number.isNaN(_port)) {
|
|
96
|
+
return output.error().title("Invalid port").message("Please provide a valid port number").exit("error");
|
|
97
|
+
}
|
|
98
|
+
if (_port < 0 || _port > 65535) {
|
|
99
|
+
return output.error().title("Invalid port").message("Port number must be between 0 and 65535").exit("error");
|
|
100
|
+
}
|
|
101
|
+
const configPath = __configPath || findConfig() || await text({
|
|
102
|
+
message: "Where is your configuration file located?",
|
|
103
|
+
defaultValue: CONFIG_FILE_DEFAULT,
|
|
104
|
+
placeholder: CONFIG_FILE_DEFAULT
|
|
105
|
+
});
|
|
106
|
+
const parseConfigResult = readAndParseConfig(configPath);
|
|
107
|
+
if (!parseConfigResult.success) {
|
|
108
|
+
renderConfigError(parseConfigResult.error);
|
|
109
|
+
}
|
|
110
|
+
if (parseConfigResult.success) {
|
|
111
|
+
output.info().line(
|
|
112
|
+
`${as.green("[SUCCESS]")} ${as.green("Configuration is valid:")} ${as.green(parseConfigResult.filePath)}`
|
|
113
|
+
).print();
|
|
114
|
+
}
|
|
115
|
+
const { config: config2 } = parseConfigResult;
|
|
116
|
+
if (config2.version === ConfigVersion.V1) {
|
|
117
|
+
return output.error().title("V1 Preview is no longer supported.").message("Please upgrade your project with `scalar project upgrade`").exit("error");
|
|
118
|
+
}
|
|
119
|
+
if (config2.version === ConfigVersion.V2) {
|
|
120
|
+
await previewV2Project({
|
|
121
|
+
logLevel: options.logLevel,
|
|
122
|
+
configPath,
|
|
123
|
+
config: config2,
|
|
124
|
+
port: _port,
|
|
125
|
+
host: options.host
|
|
126
|
+
});
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
export {
|
|
131
|
+
previewAction
|
|
132
|
+
};
|
|
@@ -0,0 +1,72 @@
|
|
|
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 {
|
|
6
|
+
getFileOrUrl
|
|
7
|
+
} from "./chunk-23I5PKZZ.js";
|
|
8
|
+
import "./chunk-IX7LJ3AD.js";
|
|
9
|
+
import {
|
|
10
|
+
output
|
|
11
|
+
} from "./chunk-X4QLDBB5.js";
|
|
12
|
+
import "./chunk-3MZYUBJ6.js";
|
|
13
|
+
|
|
14
|
+
// src/domains/document/split/action.ts
|
|
15
|
+
import fs from "node:fs/promises";
|
|
16
|
+
import path from "node:path";
|
|
17
|
+
import { text } from "@clack/prompts";
|
|
18
|
+
import as from "ansis";
|
|
19
|
+
import { normalize } from "@scalar/openapi-parser";
|
|
20
|
+
import {
|
|
21
|
+
createServerWorkspaceStore,
|
|
22
|
+
WORKSPACE_FILE_NAME
|
|
23
|
+
} from "@scalar/workspace-store/server";
|
|
24
|
+
async function splitAction(input, { output: __outputPath }) {
|
|
25
|
+
if (!input) {
|
|
26
|
+
return output.error().title("Missing input").message("Please provide a file path or URL to split").exit("error");
|
|
27
|
+
}
|
|
28
|
+
const getOutputPath = async () => {
|
|
29
|
+
if (__outputPath !== void 0 && typeof __outputPath === "string") {
|
|
30
|
+
return __outputPath;
|
|
31
|
+
}
|
|
32
|
+
const outputPath2 = await text({
|
|
33
|
+
message: "Where should the chunks be written?",
|
|
34
|
+
defaultValue: "./assets",
|
|
35
|
+
placeholder: "./assets"
|
|
36
|
+
});
|
|
37
|
+
if (typeof outputPath2 !== "string") {
|
|
38
|
+
return output.error().message("Operation cancelled by user").exit("error");
|
|
39
|
+
}
|
|
40
|
+
return outputPath2;
|
|
41
|
+
};
|
|
42
|
+
const outputPath = await getOutputPath();
|
|
43
|
+
const fileContents = await getFileOrUrl(input);
|
|
44
|
+
const documentName = "default";
|
|
45
|
+
const store = await createServerWorkspaceStore({
|
|
46
|
+
mode: "static",
|
|
47
|
+
documents: [
|
|
48
|
+
{
|
|
49
|
+
name: documentName,
|
|
50
|
+
// Todo: remove the type casting
|
|
51
|
+
document: normalize(fileContents)
|
|
52
|
+
}
|
|
53
|
+
],
|
|
54
|
+
directory: outputPath
|
|
55
|
+
});
|
|
56
|
+
const { executionTimeMs } = await measureTime(async () => {
|
|
57
|
+
await store.generateWorkspaceChunks();
|
|
58
|
+
const workspaceFilePath = path.join(outputPath, WORKSPACE_FILE_NAME);
|
|
59
|
+
const sparseDocument = JSON.parse(
|
|
60
|
+
await fs.readFile(workspaceFilePath, { encoding: "utf-8" })
|
|
61
|
+
);
|
|
62
|
+
await fs.writeFile(
|
|
63
|
+
path.join(outputPath, "out.json"),
|
|
64
|
+
JSON.stringify(sparseDocument.documents[documentName])
|
|
65
|
+
);
|
|
66
|
+
await fs.rm(workspaceFilePath);
|
|
67
|
+
});
|
|
68
|
+
output.info().line().title(as.green("Document Split Successfully! \u{1F389}")).line().message(`\u2728 Chunks have been generated at: ${as.blue(outputPath)}`).line(`\u23F1\uFE0F Split completed in ${as.yellow(executionTimeMs.toFixed(2))}ms`).line("").print();
|
|
69
|
+
}
|
|
70
|
+
export {
|
|
71
|
+
splitAction
|
|
72
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { createRequire as $$cR } from "node:module"; const require = $$cR(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
getUserTeams
|
|
4
|
+
} from "./chunk-ASMHW5AY.js";
|
|
5
|
+
import {
|
|
6
|
+
getDatabaseClient
|
|
7
|
+
} from "./chunk-SHSHFGA7.js";
|
|
8
|
+
import "./chunk-B6QZJWCQ.js";
|
|
9
|
+
import {
|
|
10
|
+
getAuthData,
|
|
11
|
+
refreshToken
|
|
12
|
+
} from "./chunk-5BISXQX4.js";
|
|
13
|
+
import "./chunk-OAXFCOJV.js";
|
|
14
|
+
import "./chunk-4DGQIAJX.js";
|
|
15
|
+
import "./chunk-ISGLWBXZ.js";
|
|
16
|
+
import "./chunk-H2WRMLYY.js";
|
|
17
|
+
import "./chunk-IX7LJ3AD.js";
|
|
18
|
+
import {
|
|
19
|
+
output
|
|
20
|
+
} from "./chunk-X4QLDBB5.js";
|
|
21
|
+
import "./chunk-3MZYUBJ6.js";
|
|
22
|
+
|
|
23
|
+
// src/domains/team/set/action.ts
|
|
24
|
+
import { select } from "@clack/prompts";
|
|
25
|
+
import as from "ansis";
|
|
26
|
+
async function setAction({ team }) {
|
|
27
|
+
const auth = await getAuthData();
|
|
28
|
+
auth.addEventListener((state) => Object.assign(auth, state));
|
|
29
|
+
if (!("refreshToken" in auth)) {
|
|
30
|
+
return output.error().title("Unsupported operation").message(
|
|
31
|
+
"You can not change the selected team because you are using a personal token, which is related to a specific team. \nTo be able to perform actions on other teams you need to generate a new personal token and login with the new token."
|
|
32
|
+
).exit("error");
|
|
33
|
+
}
|
|
34
|
+
const client = await getDatabaseClient();
|
|
35
|
+
const userTeams = await getUserTeams(client, auth.email ?? "");
|
|
36
|
+
if (userTeams.error) {
|
|
37
|
+
return output.error().title("An error occurred while getting list of teams.").exit("error");
|
|
38
|
+
}
|
|
39
|
+
let teamValue = team;
|
|
40
|
+
if (!teamValue) {
|
|
41
|
+
teamValue = await select({
|
|
42
|
+
message: "Please select one of the teams",
|
|
43
|
+
options: userTeams.data.map((it) => ({
|
|
44
|
+
value: it.teamUid,
|
|
45
|
+
label: it.teamName
|
|
46
|
+
}))
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
const selectedTeam = userTeams.data.find((it) => it.teamUid === teamValue);
|
|
50
|
+
if (!selectedTeam) {
|
|
51
|
+
return output.error().title("Invalid team").message("Please choose a valid team id").exit("error");
|
|
52
|
+
}
|
|
53
|
+
await refreshToken(auth.refreshToken, teamValue);
|
|
54
|
+
output.info().message(
|
|
55
|
+
`Operation ${as.green("successful")}. Selected team: ${as.cyan(selectedTeam.teamName)}`
|
|
56
|
+
).print();
|
|
57
|
+
}
|
|
58
|
+
export {
|
|
59
|
+
setAction
|
|
60
|
+
};
|
|
@@ -0,0 +1,65 @@
|
|
|
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
|
+
config
|
|
7
|
+
} from "./chunk-OAXFCOJV.js";
|
|
8
|
+
import "./chunk-IX7LJ3AD.js";
|
|
9
|
+
import {
|
|
10
|
+
output
|
|
11
|
+
} from "./chunk-X4QLDBB5.js";
|
|
12
|
+
import "./chunk-3MZYUBJ6.js";
|
|
13
|
+
|
|
14
|
+
// src/domains/document/share/action.ts
|
|
15
|
+
import as from "ansis";
|
|
16
|
+
async function shareAction(fileArgument, { token }) {
|
|
17
|
+
if (!fileArgument) {
|
|
18
|
+
return output.error().title("Invalid argument").message("Please provide a file path").exit("error");
|
|
19
|
+
}
|
|
20
|
+
const url = new URL(config.projects.sandbox);
|
|
21
|
+
url.pathname = "/api/share";
|
|
22
|
+
if (token) {
|
|
23
|
+
url.searchParams.append("token", token);
|
|
24
|
+
}
|
|
25
|
+
fetch(url.toString(), {
|
|
26
|
+
method: "POST",
|
|
27
|
+
headers: {
|
|
28
|
+
"Content-Type": "application/json"
|
|
29
|
+
},
|
|
30
|
+
body: JSON.stringify({
|
|
31
|
+
content: await getFileOrUrl(fileArgument)
|
|
32
|
+
})
|
|
33
|
+
}).then((response) => response.json()).then((data) => {
|
|
34
|
+
const { id, token: newToken } = data;
|
|
35
|
+
output.info().line(as.green.bold("Your OpenAPI file is public.")).line().table(
|
|
36
|
+
[
|
|
37
|
+
[
|
|
38
|
+
`${as.green("\u279C")} ${as.white.bold("API Reference:")}`,
|
|
39
|
+
as.cyan(`https://sandbox.scalar.com/p/${id}`)
|
|
40
|
+
],
|
|
41
|
+
[
|
|
42
|
+
`${as.grey("\u279C")} ${as.grey.bold("Editor:")}`,
|
|
43
|
+
as.cyan(`https://sandbox.scalar.com/e/${id}`)
|
|
44
|
+
],
|
|
45
|
+
[],
|
|
46
|
+
[
|
|
47
|
+
`${as.grey("\u279C")} ${as.grey.bold("OpenAPI JSON:")}`,
|
|
48
|
+
as.cyan(`https://sandbox.scalar.com/files/${id}/openapi.json`)
|
|
49
|
+
],
|
|
50
|
+
[
|
|
51
|
+
`${as.grey("\u279C")} ${as.grey.bold("OpenAPI YAML:")}`,
|
|
52
|
+
as.cyan(`https://sandbox.scalar.com/files/${id}/openapi.yaml`)
|
|
53
|
+
]
|
|
54
|
+
],
|
|
55
|
+
{ padding: 1 }
|
|
56
|
+
).line().line("Use the token to update the existing sandbox:").line().line(
|
|
57
|
+
`${as.grey("$")} ${as.white.bold("scalar document share --token=")}${as.cyan.bold(`${newToken}`)} `
|
|
58
|
+
).line().print();
|
|
59
|
+
}).catch((error) => {
|
|
60
|
+
output.error().title("Failed to share the file.").message(`Details: ${error}`).exit("error");
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
export {
|
|
64
|
+
shareAction
|
|
65
|
+
};
|