@lark-apaas/miaoda-cli 0.1.3 → 0.1.4
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/dist/api/app/api.js +3 -3
- package/dist/api/app/schemas.js +43 -43
- package/dist/api/db/api.js +398 -55
- package/dist/api/db/client.js +155 -28
- package/dist/api/db/index.js +12 -1
- package/dist/api/db/parsers.js +20 -20
- package/dist/api/db/sql-keywords.js +87 -87
- package/dist/api/deploy/api.js +5 -5
- package/dist/api/deploy/schemas.js +32 -32
- package/dist/api/file/api.js +89 -87
- package/dist/api/file/client.js +62 -22
- package/dist/api/file/detect.js +3 -3
- package/dist/api/file/index.js +2 -1
- package/dist/api/file/parsers.js +18 -7
- package/dist/api/observability/api.js +6 -6
- package/dist/api/observability/schemas.js +14 -14
- package/dist/api/plugin/api.js +31 -31
- package/dist/cli/commands/app/index.js +12 -12
- package/dist/cli/commands/db/index.js +602 -54
- package/dist/cli/commands/deploy/index.js +28 -28
- package/dist/cli/commands/file/index.js +85 -58
- package/dist/cli/commands/observability/index.js +69 -69
- package/dist/cli/commands/plugin/index.js +27 -27
- package/dist/cli/commands/shared.js +10 -10
- package/dist/cli/handlers/app/update.js +2 -2
- package/dist/cli/handlers/db/_destructive.js +67 -0
- package/dist/cli/handlers/db/_env.js +26 -0
- package/dist/cli/handlers/db/_operator.js +35 -0
- package/dist/cli/handlers/db/audit.js +383 -0
- package/dist/cli/handlers/db/changelog.js +160 -0
- package/dist/cli/handlers/db/data.js +32 -31
- package/dist/cli/handlers/db/index.js +17 -1
- package/dist/cli/handlers/db/migration.js +234 -0
- package/dist/cli/handlers/db/quota.js +68 -0
- package/dist/cli/handlers/db/recovery.js +413 -0
- package/dist/cli/handlers/db/schema.js +33 -33
- package/dist/cli/handlers/db/sql.js +69 -69
- package/dist/cli/handlers/deploy/deploy.js +4 -4
- package/dist/cli/handlers/deploy/error-log.js +1 -1
- package/dist/cli/handlers/deploy/get.js +3 -3
- package/dist/cli/handlers/deploy/polling.js +11 -11
- package/dist/cli/handlers/file/cp.js +30 -30
- package/dist/cli/handlers/file/index.js +3 -1
- package/dist/cli/handlers/file/ls.js +5 -5
- package/dist/cli/handlers/file/quota.js +66 -0
- package/dist/cli/handlers/file/rm.js +32 -30
- package/dist/cli/handlers/file/sign.js +3 -3
- package/dist/cli/handlers/file/stat.js +10 -9
- package/dist/cli/handlers/observability/analytics.js +47 -47
- package/dist/cli/handlers/observability/helpers.js +2 -2
- package/dist/cli/handlers/observability/log.js +9 -9
- package/dist/cli/handlers/observability/metric.js +26 -26
- package/dist/cli/handlers/observability/trace.js +5 -5
- package/dist/cli/handlers/plugin/plugin-local.js +53 -53
- package/dist/cli/handlers/plugin/plugin.js +15 -15
- package/dist/cli/help.js +16 -16
- package/dist/main.js +12 -12
- package/dist/utils/args.js +1 -1
- package/dist/utils/colors.js +2 -2
- package/dist/utils/config.js +2 -2
- package/dist/utils/devops-error.js +9 -9
- package/dist/utils/error.js +2 -2
- package/dist/utils/git.js +4 -4
- package/dist/utils/http.js +19 -19
- package/dist/utils/index.js +3 -1
- package/dist/utils/output.js +67 -45
- package/dist/utils/poll.js +35 -0
- package/dist/utils/render.js +27 -27
- package/dist/utils/spinner.js +46 -0
- package/dist/utils/time.js +47 -42
- package/package.json +1 -1
package/dist/utils/time.js
CHANGED
|
@@ -10,45 +10,48 @@ exports.parseToSec = parseToSec;
|
|
|
10
10
|
exports.floorMsToBucket = floorMsToBucket;
|
|
11
11
|
exports.ceilMsToBucket = ceilMsToBucket;
|
|
12
12
|
const error_1 = require("./error");
|
|
13
|
-
exports.TIMESTAMP_HELP = "支持格式:" +
|
|
14
|
-
"相对时间 30m/1h/2d/1w;" +
|
|
15
|
-
"日期 2026-04-01(本地时区当日 00:00:00);" +
|
|
16
|
-
"本地日期+时间 2026-04-01T10:00:00(按本地时区,T 分隔);" +
|
|
17
|
-
"带时区 ISO 2026-04-01T10:00:00Z(UTC)或 2026-04-01T10:00:00+08:00(指定偏移)。" +
|
|
18
|
-
"禁止用空格分隔:'YYYY-MM-DD HH:mm:ss' 不带引号会被 shell 拆成两个参数。";
|
|
19
13
|
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* 时区约定(重要):
|
|
23
|
-
* - 不带显式时区的形式(YYYY-MM-DD、YYYY-MM-DDTHH:mm:ss)一律按
|
|
24
|
-
* **本地时区**解释,与 pretty 输出(output.ts:renderDate 用 getFullYear 等本地方法)形成
|
|
25
|
-
* 输入/输出闭环:用户复制输出文本作为 --since 不会差时区。
|
|
26
|
-
* - 带显式时区(结尾 Z 或 ±HH:MM / ±HHMM)按显式时区解析,跨机器一致。
|
|
27
|
-
* - 因此跨机器同步使用时建议带显式时区;同机器复制粘贴 pretty 输出更省事。
|
|
28
|
-
*
|
|
29
|
-
* 拒绝 Date.parse 松散接受的形式:YYYY/MM/DD、自然语言('April 1 2026')、单独年份等。
|
|
14
|
+
* 时间格式简短说明,对齐 Supabase / fly.io 等主流 CLI 的「简洁但严格」风格。
|
|
30
15
|
*
|
|
16
|
+
* - 不接受 YYYY/MM/DD、'April 1 2026' 这类松散 / 区域性形式(Date.parse 会误吞)
|
|
17
|
+
* - 不接受空格分隔的 'YYYY-MM-DD HH:mm:ss':不带引号会被 shell 拆成两个参数,
|
|
18
|
+
* 宁可拒绝也不让用户踩「看起来传了 since 实际只传了一半」的坑
|
|
19
|
+
* - 不带显式时区的 (YYYY-MM-DD / YYYY-MM-DDTHH:mm:ss) 一律按**本地时区**解释,
|
|
20
|
+
* 跟 pretty 输出(renderDate 用 getFullYear 等本地方法)形成输入/输出闭环
|
|
21
|
+
* ——用户复制 pretty 输出的时间字符串当 --since 不会差时区
|
|
22
|
+
*/
|
|
23
|
+
exports.TIMESTAMP_HELP = 'Accepted formats: ' +
|
|
24
|
+
'relative (30s / 5m / 2h / 3d / 1w); ' +
|
|
25
|
+
'date YYYY-MM-DD (local 00:00:00); ' +
|
|
26
|
+
'local datetime YYYY-MM-DDTHH:mm:ss (local timezone, T-separated); ' +
|
|
27
|
+
'ISO 8601 with timezone YYYY-MM-DDTHH:mm:ssZ or YYYY-MM-DDTHH:mm:ss+08:00.';
|
|
28
|
+
/**
|
|
29
|
+
* 解析时间字符串到毫秒时间戳;不匹配任一支持格式抛 ARGS_INVALID。
|
|
31
30
|
* 失败抛 AppError("ARGS_INVALID", ...);CLI 层用 withHelp 自动转 exit 2 + help。
|
|
32
31
|
*/
|
|
33
32
|
function parseTimeToMs(input, now = new Date()) {
|
|
34
|
-
// 1. 相对时间:30m / 1h / 2d / 1w
|
|
35
|
-
const relative = /^(\d+)([
|
|
33
|
+
// 1. 相对时间:30s / 30m / 1h / 2d / 1w
|
|
34
|
+
const relative = /^(\d+)([smhdw])$/.exec(input);
|
|
36
35
|
if (relative) {
|
|
37
36
|
const n = Number(relative[1]);
|
|
37
|
+
if (n <= 0)
|
|
38
|
+
failInvalidTimestamp(input);
|
|
38
39
|
const unit = relative[2];
|
|
39
|
-
const factor = unit ===
|
|
40
|
-
?
|
|
41
|
-
: unit ===
|
|
42
|
-
?
|
|
43
|
-
: unit ===
|
|
44
|
-
?
|
|
45
|
-
:
|
|
40
|
+
const factor = unit === 's'
|
|
41
|
+
? 1_000
|
|
42
|
+
: unit === 'm'
|
|
43
|
+
? 60_000
|
|
44
|
+
: unit === 'h'
|
|
45
|
+
? 3_600_000
|
|
46
|
+
: unit === 'd'
|
|
47
|
+
? 86_400_000
|
|
48
|
+
: /* w */ 604_800_000;
|
|
46
49
|
return now.getTime() - n * factor;
|
|
47
50
|
}
|
|
48
51
|
// 2. 纯日期:YYYY-MM-DD → 本地当日 00:00:00
|
|
49
52
|
const date = /^(\d{4})-(\d{2})-(\d{2})$/.exec(input);
|
|
50
53
|
if (date) {
|
|
51
|
-
return localDateMs(input, date[1], date[2], date[3],
|
|
54
|
+
return localDateMs(input, date[1], date[2], date[3], '00', '00', '00', '0');
|
|
52
55
|
}
|
|
53
56
|
// 3. 本地日期+时间:YYYY-MM-DDTHH:mm:ss[.SSS](不带时区,T 分隔)。
|
|
54
57
|
// 不接受空格分隔——'YYYY-MM-DD HH:mm:ss' 不带引号会被 shell 拆成两个参数,
|
|
@@ -57,14 +60,14 @@ function parseTimeToMs(input, now = new Date()) {
|
|
|
57
60
|
if (localDt) {
|
|
58
61
|
// capture 7 是可选 .SSS 组,运行时可能 undefined;TS lib 的 RegExp match 索引
|
|
59
62
|
// 类型把它标成 string,所以这里显式 cast 让 ?? 在 lint 视角下也"必要"。
|
|
60
|
-
const msPart = localDt[7] ??
|
|
63
|
+
const msPart = localDt[7] ?? '0';
|
|
61
64
|
return localDateMs(input, localDt[1], localDt[2], localDt[3], localDt[4], localDt[5], localDt[6], msPart);
|
|
62
65
|
}
|
|
63
66
|
// 4. 带显式时区的 ISO 8601:YYYY-MM-DDTHH:mm:ss[.SSS](Z|±HH:MM|±HHMM)
|
|
64
67
|
const iso = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.\d{1,9})?(Z|[+-](\d{2}):?(\d{2}))$/.exec(input);
|
|
65
68
|
if (iso) {
|
|
66
69
|
validateDateTimeParts(input, iso[1], iso[2], iso[3], iso[4], iso[5], iso[6]);
|
|
67
|
-
if (iso[7] !==
|
|
70
|
+
if (iso[7] !== 'Z')
|
|
68
71
|
validateOffset(input, iso[8], iso[9]);
|
|
69
72
|
const ms = Date.parse(input);
|
|
70
73
|
if (Number.isNaN(ms))
|
|
@@ -76,7 +79,7 @@ function parseTimeToMs(input, now = new Date()) {
|
|
|
76
79
|
function localDateMs(input, y, mo, d, h, mi, s, msPart) {
|
|
77
80
|
validateDateTimeParts(input, y, mo, d, h, mi, s);
|
|
78
81
|
// 毫秒位补齐到 3 位再截断("5" → 500,"12" → 120,"123" → 123)
|
|
79
|
-
const ms = Number(msPart.padEnd(3,
|
|
82
|
+
const ms = Number(msPart.padEnd(3, '0').slice(0, 3));
|
|
80
83
|
const date = new Date(Number(y), Number(mo) - 1, Number(d), Number(h), Number(mi), Number(s), ms);
|
|
81
84
|
if (date.getFullYear() !== Number(y) ||
|
|
82
85
|
date.getMonth() !== Number(mo) - 1 ||
|
|
@@ -115,7 +118,9 @@ function validateOffset(input, h, mi) {
|
|
|
115
118
|
failInvalidTimestamp(input);
|
|
116
119
|
}
|
|
117
120
|
function failInvalidTimestamp(input) {
|
|
118
|
-
throw new error_1.AppError(
|
|
121
|
+
throw new error_1.AppError('ARGS_INVALID', `Invalid timestamp '${input}'`, {
|
|
122
|
+
next_actions: [exports.TIMESTAMP_HELP],
|
|
123
|
+
});
|
|
119
124
|
}
|
|
120
125
|
/** 毫秒 → 纳秒(字符串,避免 JS Number 精度丢失) */
|
|
121
126
|
function msToNs(ms) {
|
|
@@ -156,21 +161,21 @@ const MS_DAY = 86_400_000;
|
|
|
156
161
|
/** 把 ms 向下对齐到桶起点(UTC)。未识别的 bucket 原样返回。 */
|
|
157
162
|
function floorMsToBucket(ms, bucket) {
|
|
158
163
|
switch (bucket) {
|
|
159
|
-
case
|
|
164
|
+
case '1m':
|
|
160
165
|
return Math.floor(ms / MS_MIN) * MS_MIN;
|
|
161
|
-
case
|
|
166
|
+
case '1h':
|
|
162
167
|
return Math.floor(ms / MS_HOUR) * MS_HOUR;
|
|
163
|
-
case
|
|
164
|
-
case
|
|
168
|
+
case '1d':
|
|
169
|
+
case 'DAY': {
|
|
165
170
|
const d = new Date(ms);
|
|
166
171
|
return Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate());
|
|
167
172
|
}
|
|
168
|
-
case
|
|
173
|
+
case 'WEEK': {
|
|
169
174
|
const d = new Date(ms);
|
|
170
175
|
const offsetDays = (d.getUTCDay() + 6) % 7; // 距上一个周一的天数
|
|
171
176
|
return Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate() - offsetDays);
|
|
172
177
|
}
|
|
173
|
-
case
|
|
178
|
+
case 'MONTH': {
|
|
174
179
|
const d = new Date(ms);
|
|
175
180
|
return Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), 1);
|
|
176
181
|
}
|
|
@@ -184,16 +189,16 @@ function ceilMsToBucket(ms, bucket) {
|
|
|
184
189
|
if (floor === ms)
|
|
185
190
|
return ms;
|
|
186
191
|
switch (bucket) {
|
|
187
|
-
case
|
|
192
|
+
case '1m':
|
|
188
193
|
return floor + MS_MIN;
|
|
189
|
-
case
|
|
194
|
+
case '1h':
|
|
190
195
|
return floor + MS_HOUR;
|
|
191
|
-
case
|
|
192
|
-
case
|
|
196
|
+
case '1d':
|
|
197
|
+
case 'DAY':
|
|
193
198
|
return floor + MS_DAY;
|
|
194
|
-
case
|
|
199
|
+
case 'WEEK':
|
|
195
200
|
return floor + 7 * MS_DAY;
|
|
196
|
-
case
|
|
201
|
+
case 'MONTH': {
|
|
197
202
|
const d = new Date(floor);
|
|
198
203
|
return Date.UTC(d.getUTCFullYear(), d.getUTCMonth() + 1, 1);
|
|
199
204
|
}
|