@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.
Files changed (71) hide show
  1. package/dist/api/app/api.js +3 -3
  2. package/dist/api/app/schemas.js +43 -43
  3. package/dist/api/db/api.js +398 -55
  4. package/dist/api/db/client.js +155 -28
  5. package/dist/api/db/index.js +12 -1
  6. package/dist/api/db/parsers.js +20 -20
  7. package/dist/api/db/sql-keywords.js +87 -87
  8. package/dist/api/deploy/api.js +5 -5
  9. package/dist/api/deploy/schemas.js +32 -32
  10. package/dist/api/file/api.js +89 -87
  11. package/dist/api/file/client.js +62 -22
  12. package/dist/api/file/detect.js +3 -3
  13. package/dist/api/file/index.js +2 -1
  14. package/dist/api/file/parsers.js +18 -7
  15. package/dist/api/observability/api.js +6 -6
  16. package/dist/api/observability/schemas.js +14 -14
  17. package/dist/api/plugin/api.js +31 -31
  18. package/dist/cli/commands/app/index.js +12 -12
  19. package/dist/cli/commands/db/index.js +602 -54
  20. package/dist/cli/commands/deploy/index.js +28 -28
  21. package/dist/cli/commands/file/index.js +85 -58
  22. package/dist/cli/commands/observability/index.js +69 -69
  23. package/dist/cli/commands/plugin/index.js +27 -27
  24. package/dist/cli/commands/shared.js +10 -10
  25. package/dist/cli/handlers/app/update.js +2 -2
  26. package/dist/cli/handlers/db/_destructive.js +67 -0
  27. package/dist/cli/handlers/db/_env.js +26 -0
  28. package/dist/cli/handlers/db/_operator.js +35 -0
  29. package/dist/cli/handlers/db/audit.js +383 -0
  30. package/dist/cli/handlers/db/changelog.js +160 -0
  31. package/dist/cli/handlers/db/data.js +32 -31
  32. package/dist/cli/handlers/db/index.js +17 -1
  33. package/dist/cli/handlers/db/migration.js +234 -0
  34. package/dist/cli/handlers/db/quota.js +68 -0
  35. package/dist/cli/handlers/db/recovery.js +413 -0
  36. package/dist/cli/handlers/db/schema.js +33 -33
  37. package/dist/cli/handlers/db/sql.js +69 -69
  38. package/dist/cli/handlers/deploy/deploy.js +4 -4
  39. package/dist/cli/handlers/deploy/error-log.js +1 -1
  40. package/dist/cli/handlers/deploy/get.js +3 -3
  41. package/dist/cli/handlers/deploy/polling.js +11 -11
  42. package/dist/cli/handlers/file/cp.js +30 -30
  43. package/dist/cli/handlers/file/index.js +3 -1
  44. package/dist/cli/handlers/file/ls.js +5 -5
  45. package/dist/cli/handlers/file/quota.js +66 -0
  46. package/dist/cli/handlers/file/rm.js +32 -30
  47. package/dist/cli/handlers/file/sign.js +3 -3
  48. package/dist/cli/handlers/file/stat.js +10 -9
  49. package/dist/cli/handlers/observability/analytics.js +47 -47
  50. package/dist/cli/handlers/observability/helpers.js +2 -2
  51. package/dist/cli/handlers/observability/log.js +9 -9
  52. package/dist/cli/handlers/observability/metric.js +26 -26
  53. package/dist/cli/handlers/observability/trace.js +5 -5
  54. package/dist/cli/handlers/plugin/plugin-local.js +53 -53
  55. package/dist/cli/handlers/plugin/plugin.js +15 -15
  56. package/dist/cli/help.js +16 -16
  57. package/dist/main.js +12 -12
  58. package/dist/utils/args.js +1 -1
  59. package/dist/utils/colors.js +2 -2
  60. package/dist/utils/config.js +2 -2
  61. package/dist/utils/devops-error.js +9 -9
  62. package/dist/utils/error.js +2 -2
  63. package/dist/utils/git.js +4 -4
  64. package/dist/utils/http.js +19 -19
  65. package/dist/utils/index.js +3 -1
  66. package/dist/utils/output.js +67 -45
  67. package/dist/utils/poll.js +35 -0
  68. package/dist/utils/render.js +27 -27
  69. package/dist/utils/spinner.js +46 -0
  70. package/dist/utils/time.js +47 -42
  71. package/package.json +1 -1
@@ -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
- * 解析时间字符串到毫秒时间戳;不匹配任一支持格式抛 ARGS_INVALID。
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+)([mhdw])$/.exec(input);
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 === "m"
40
- ? 60_000
41
- : unit === "h"
42
- ? 3_600_000
43
- : unit === "d"
44
- ? 86_400_000
45
- : /* w */ 604_800_000;
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], "00", "00", "00", "0");
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] ?? "0";
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] !== "Z")
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, "0").slice(0, 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("ARGS_INVALID", `无法解析时间 '${input}'。${exports.TIMESTAMP_HELP}`);
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 "1m":
164
+ case '1m':
160
165
  return Math.floor(ms / MS_MIN) * MS_MIN;
161
- case "1h":
166
+ case '1h':
162
167
  return Math.floor(ms / MS_HOUR) * MS_HOUR;
163
- case "1d":
164
- case "DAY": {
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 "WEEK": {
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 "MONTH": {
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 "1m":
192
+ case '1m':
188
193
  return floor + MS_MIN;
189
- case "1h":
194
+ case '1h':
190
195
  return floor + MS_HOUR;
191
- case "1d":
192
- case "DAY":
196
+ case '1d':
197
+ case 'DAY':
193
198
  return floor + MS_DAY;
194
- case "WEEK":
199
+ case 'WEEK':
195
200
  return floor + 7 * MS_DAY;
196
- case "MONTH": {
201
+ case 'MONTH': {
197
202
  const d = new Date(floor);
198
203
  return Date.UTC(d.getUTCFullYear(), d.getUTCMonth() + 1, 1);
199
204
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lark-apaas/miaoda-cli",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "Miaoda 平台命令行工具,面向 Agent 调用",
5
5
  "type": "commonjs",
6
6
  "bin": {