@atomservice/functions-cli 0.1.10 → 0.1.12
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/package.json +2 -2
- package/src/commands/setup.ts +106 -0
- package/src/index.ts +2 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atomservice/functions-cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.12",
|
|
4
4
|
"description": "函数服务命令行工具(atomfunctions):项目脚手架、本地构建、部署、运维",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "openorson",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"atomfn": "./bin/functions.ts"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@atomservice/functions-sdk": "0.1.
|
|
33
|
+
"@atomservice/functions-sdk": "0.1.12",
|
|
34
34
|
"@clack/prompts": "1.5.0",
|
|
35
35
|
"change-case": "5.4.4",
|
|
36
36
|
"citty": "0.2.2",
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import path from "node:path"
|
|
2
|
+
import { intro, log, outro, password as passwordPrompt, spinner, text } from "@clack/prompts"
|
|
3
|
+
import { defineCommand } from "citty"
|
|
4
|
+
import pc from "picocolors"
|
|
5
|
+
import { ClientError } from "../client.ts"
|
|
6
|
+
import { MANIFEST_FILE } from "../consts.ts"
|
|
7
|
+
import type { Manifest } from "../types.ts"
|
|
8
|
+
import { readJson, unwrap } from "../utils.ts"
|
|
9
|
+
|
|
10
|
+
export const setupCommand = defineCommand({
|
|
11
|
+
meta: { name: "setup", description: "初始化函数服务,创建初始超管账号" },
|
|
12
|
+
args: {
|
|
13
|
+
server: { type: "string", description: "服务器地址(默认读取 atomfunctions.json)" },
|
|
14
|
+
name: { type: "string", description: "超管用户名" },
|
|
15
|
+
email: { type: "string", description: "超管邮箱" },
|
|
16
|
+
password: { type: "string", description: "超管密码" },
|
|
17
|
+
},
|
|
18
|
+
async run({ args }) {
|
|
19
|
+
intro(pc.cyan("atomfunctions 初始化"))
|
|
20
|
+
const root = process.cwd()
|
|
21
|
+
const manifest = await readJson<Manifest>(path.join(root, MANIFEST_FILE))
|
|
22
|
+
let server = args.server ?? manifest?.server
|
|
23
|
+
if (!server) {
|
|
24
|
+
server = unwrap(
|
|
25
|
+
await text({
|
|
26
|
+
message: "控制面服务器地址",
|
|
27
|
+
placeholder: "http://localhost:4922",
|
|
28
|
+
validate: (v) => (v?.trim() ? undefined : "请输入服务器地址"),
|
|
29
|
+
}),
|
|
30
|
+
).trim()
|
|
31
|
+
} else {
|
|
32
|
+
server = server.trim()
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
try {
|
|
36
|
+
new URL(server)
|
|
37
|
+
} catch {
|
|
38
|
+
log.error("请输入合法的 URL")
|
|
39
|
+
process.exit(1)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const name = args.name
|
|
43
|
+
? args.name
|
|
44
|
+
: unwrap(
|
|
45
|
+
await text({
|
|
46
|
+
message: "超管用户名",
|
|
47
|
+
placeholder: "admin",
|
|
48
|
+
validate: (v) => (v?.trim() ? undefined : "请输入用户名"),
|
|
49
|
+
}),
|
|
50
|
+
).trim()
|
|
51
|
+
|
|
52
|
+
const email = args.email
|
|
53
|
+
? args.email
|
|
54
|
+
: unwrap(
|
|
55
|
+
await text({
|
|
56
|
+
message: "超管邮箱",
|
|
57
|
+
validate: (v) => (v?.trim() ? undefined : "请输入邮箱"),
|
|
58
|
+
}),
|
|
59
|
+
).trim()
|
|
60
|
+
|
|
61
|
+
const pw = args.password
|
|
62
|
+
? args.password
|
|
63
|
+
: unwrap(
|
|
64
|
+
await passwordPrompt({
|
|
65
|
+
message: "超管密码(至少 8 位)",
|
|
66
|
+
validate: (v) => (v?.length >= 8 ? undefined : "密码至少 8 位"),
|
|
67
|
+
}),
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
const spin = spinner()
|
|
71
|
+
spin.start("正在初始化")
|
|
72
|
+
|
|
73
|
+
try {
|
|
74
|
+
const base = server.replace(/\/+$/, "")
|
|
75
|
+
const res = await fetch(`${base}/v1/setup`, {
|
|
76
|
+
method: "POST",
|
|
77
|
+
headers: { "Content-Type": "application/json" },
|
|
78
|
+
body: JSON.stringify({ name, email, password: pw }),
|
|
79
|
+
})
|
|
80
|
+
const body = (await res.json()) as { error?: { code: string; message: string } }
|
|
81
|
+
if (!res.ok) {
|
|
82
|
+
if (res.status === 409) {
|
|
83
|
+
spin.stop(pc.yellow("服务器已完成初始化(超管账号已存在)"))
|
|
84
|
+
outro("无需重复初始化")
|
|
85
|
+
return
|
|
86
|
+
}
|
|
87
|
+
throw new ClientError(
|
|
88
|
+
res.status,
|
|
89
|
+
body.error?.code ?? "error",
|
|
90
|
+
body.error?.message ?? `请求失败(${res.status})`,
|
|
91
|
+
)
|
|
92
|
+
}
|
|
93
|
+
spin.stop(pc.green("初始化成功"))
|
|
94
|
+
outro(`超管账号 ${email} 已创建,使用 atomfn login 登录`)
|
|
95
|
+
} catch (err) {
|
|
96
|
+
if (err instanceof ClientError) {
|
|
97
|
+
spin.stop(pc.red("初始化失败"))
|
|
98
|
+
log.error(err.message)
|
|
99
|
+
process.exit(1)
|
|
100
|
+
}
|
|
101
|
+
spin.stop(pc.red("初始化失败"))
|
|
102
|
+
log.error(err instanceof Error ? err.message : String(err))
|
|
103
|
+
process.exit(1)
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
})
|
package/src/index.ts
CHANGED
|
@@ -14,6 +14,7 @@ import { projectCommand } from "./commands/project.ts"
|
|
|
14
14
|
import { pullCommand } from "./commands/pull.ts"
|
|
15
15
|
import { pushCommand } from "./commands/push.ts"
|
|
16
16
|
import { rollbackCommand } from "./commands/rollback.ts"
|
|
17
|
+
import { setupCommand } from "./commands/setup.ts"
|
|
17
18
|
import { tokenCommand } from "./commands/token.ts"
|
|
18
19
|
import { userCommand } from "./commands/user.ts"
|
|
19
20
|
import { whoamiCommand } from "./commands/whoami.ts"
|
|
@@ -24,6 +25,7 @@ export const mainCommand = defineCommand({
|
|
|
24
25
|
init: initCommand,
|
|
25
26
|
login: loginCommand,
|
|
26
27
|
logout: logoutCommand,
|
|
28
|
+
setup: setupCommand,
|
|
27
29
|
whoami: whoamiCommand,
|
|
28
30
|
user: userCommand,
|
|
29
31
|
project: projectCommand,
|