nx-sk 0.27.0 → 0.29.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/CHANGELOG.md +46 -0
- package/README.md +18 -5
- package/assets/nx-sk/references/15-special-fields.md +25 -1
- package/bin/nx-sk.mjs +21 -3
- package/{src → dist}/core/argsafe.js +24 -24
- package/dist/core/attachments.js +463 -0
- package/dist/core/crypto.js +71 -0
- package/{src → dist}/core/errors.js +27 -29
- package/dist/core/fields/behaviors/bool.js +24 -0
- package/dist/core/fields/behaviors/common.js +37 -0
- package/dist/core/fields/behaviors/date.js +12 -0
- package/dist/core/fields/behaviors/entrylist.js +112 -0
- package/dist/core/fields/behaviors/file.js +38 -0
- package/dist/core/fields/behaviors/md.js +21 -0
- package/dist/core/fields/behaviors/month.js +12 -0
- package/dist/core/fields/behaviors/number.js +18 -0
- package/dist/core/fields/behaviors/secret.js +12 -0
- package/dist/core/fields/behaviors/select.js +12 -0
- package/dist/core/fields/behaviors/shortcut.js +41 -0
- package/dist/core/fields/behaviors/source.js +71 -0
- package/dist/core/fields/behaviors/table.js +185 -0
- package/dist/core/fields/behaviors/tags.js +20 -0
- package/dist/core/fields/behaviors/text.js +12 -0
- package/dist/core/fields/behaviors/textarea.js +12 -0
- package/dist/core/fields/registry.js +87 -0
- package/dist/core/fields/seal/common.js +39 -0
- package/dist/core/fields/seal/entrylist.js +46 -0
- package/dist/core/fields/seal/index.js +24 -0
- package/dist/core/fields/seal/table.js +86 -0
- package/dist/core/fields.js +861 -0
- package/dist/core/fsx.js +119 -0
- package/dist/core/ids.js +16 -0
- package/{src → dist}/core/mdimages.js +35 -35
- package/dist/core/open.js +36 -0
- package/{src → dist}/core/paths.js +57 -71
- package/dist/core/render.js +167 -0
- package/dist/core/securezip.js +68 -0
- package/dist/core/sensitive.js +27 -0
- package/{src → dist}/core/serve-port.js +59 -61
- package/dist/core/source.js +261 -0
- package/dist/core/store.js +296 -0
- package/dist/core/values.js +42 -0
- package/dist/core/vault.js +131 -0
- package/dist/core/zip.js +198 -0
- package/dist/index.js +12 -0
- package/dist/modules/entries/index.js +280 -0
- package/dist/modules/entries/service.js +1239 -0
- package/dist/modules/files/index.js +123 -0
- package/dist/modules/files/service.js +328 -0
- package/dist/modules/sections/index.js +142 -0
- package/dist/modules/sections/service.js +806 -0
- package/dist/modules/settings/index.js +32 -0
- package/dist/modules/settings/service.js +234 -0
- package/dist/modules/skill/index.js +50 -0
- package/dist/modules/skill/service.js +238 -0
- package/dist/modules/system/index.js +40 -0
- package/dist/modules/system/service.js +157 -0
- package/dist/modules/transfer/index.js +112 -0
- package/dist/modules/transfer/service.js +1004 -0
- package/dist/runtime/api.js +139 -0
- package/dist/runtime/cli.js +388 -0
- package/dist/runtime/module-registry.js +88 -0
- package/dist/runtime/registry.js +62 -0
- package/dist/runtime/server.js +78 -0
- package/dist/runtime/spec.js +193 -0
- package/dist/shared/blockLayout.js +383 -0
- package/dist/shared/fields/types.js +37 -0
- package/dist/shared/model.js +1 -0
- package/dist/shared/shortcut.js +196 -0
- package/dist/shared/table.js +957 -0
- package/{src/web/public/assets/files--kTIDQLp.js → dist/web/public/assets/files-BYzv5zCz.js} +1 -1
- package/{src/web/public/assets/index-DDEmDb0K.css → dist/web/public/assets/index-Cj8L_sM4.css} +1 -1
- package/dist/web/public/assets/index-j1zkCXw9.js +41 -0
- package/dist/web/public/assets/view---Z6RLHC.js +46 -0
- package/{src/web/public/assets/view-ChbT0W1t.js → dist/web/public/assets/view-D1AQI5qu.js} +2 -2
- package/dist/web/public/assets/view-Do1fJzAq.js +1 -0
- package/dist/web/public/assets/view-WSb7GgJa.js +3 -0
- package/{src/web/public/assets/view-Bji535Kc.js → dist/web/public/assets/view-ZBbb0ceb.js} +1 -1
- package/{src/web/frontend → dist/web/public}/index.html +2 -1
- package/package.json +15 -8
- package/src/core/attachments.js +0 -446
- package/src/core/crypto.js +0 -73
- package/src/core/fields.js +0 -895
- package/src/core/fsx.js +0 -103
- package/src/core/ids.js +0 -19
- package/src/core/open.js +0 -32
- package/src/core/render.js +0 -239
- package/src/core/securezip.js +0 -72
- package/src/core/source.js +0 -230
- package/src/core/store.js +0 -297
- package/src/core/vault.js +0 -125
- package/src/core/zip.js +0 -198
- package/src/index.js +0 -13
- package/src/modules/entries/index.js +0 -286
- package/src/modules/entries/kvTable.jsx +0 -165
- package/src/modules/entries/service.js +0 -1508
- package/src/modules/entries/view.jsx +0 -666
- package/src/modules/export/index.js +0 -14
- package/src/modules/export/view.jsx +0 -25
- package/src/modules/files/index.js +0 -125
- package/src/modules/files/service.js +0 -327
- package/src/modules/files/view.jsx +0 -400
- package/src/modules/sections/index.js +0 -144
- package/src/modules/sections/service.js +0 -815
- package/src/modules/sections/view.jsx +0 -1199
- package/src/modules/settings/index.js +0 -34
- package/src/modules/settings/navManager.jsx +0 -213
- package/src/modules/settings/service.js +0 -221
- package/src/modules/settings/view.jsx +0 -224
- package/src/modules/skill/index.js +0 -52
- package/src/modules/skill/service.js +0 -237
- package/src/modules/system/index.js +0 -42
- package/src/modules/system/service.js +0 -163
- package/src/modules/transfer/index.js +0 -113
- package/src/modules/transfer/service.js +0 -958
- package/src/runtime/api.js +0 -140
- package/src/runtime/cli.js +0 -352
- package/src/runtime/registry.js +0 -67
- package/src/runtime/server.js +0 -80
- package/src/runtime/spec.js +0 -169
- package/src/shared/blockLayout.js +0 -367
- package/src/shared/table.js +0 -884
- package/src/web/frontend/App.jsx +0 -274
- package/src/web/frontend/activeView.js +0 -42
- package/src/web/frontend/api/client.js +0 -26
- package/src/web/frontend/api/files.js +0 -49
- package/src/web/frontend/api/zip.js +0 -34
- package/src/web/frontend/components/blockBoard.jsx +0 -307
- package/src/web/frontend/components/fieldEditor.jsx +0 -737
- package/src/web/frontend/components/lightbox.jsx +0 -96
- package/src/web/frontend/components/listDrag.jsx +0 -82
- package/src/web/frontend/components/mdView.jsx +0 -193
- package/src/web/frontend/components/navModel.js +0 -293
- package/src/web/frontend/components/sourcePanel.jsx +0 -558
- package/src/web/frontend/components/tableField.jsx +0 -635
- package/src/web/frontend/components/transferPanel.jsx +0 -494
- package/src/web/frontend/components/ui.jsx +0 -152
- package/src/web/frontend/listSort.js +0 -18
- package/src/web/frontend/main.jsx +0 -13
- package/src/web/frontend/mdInline.js +0 -185
- package/src/web/frontend/mdSmart.js +0 -164
- package/src/web/frontend/mdSource.js +0 -41
- package/src/web/frontend/registry.js +0 -21
- package/src/web/frontend/store.jsx +0 -107
- package/src/web/frontend/styles.css +0 -1535
- package/src/web/public/assets/index-Dk-VfQfE.js +0 -41
- package/src/web/public/assets/view-BaXP_gJq.js +0 -1
- package/src/web/public/assets/view-Bcy062Uw.js +0 -3
- package/src/web/public/assets/view-D_mRuEro.js +0 -46
- package/src/web/public/favicon-16.png +0 -0
- package/src/web/public/favicon-32.png +0 -0
- package/src/web/public/favicon-48.png +0 -0
- package/src/web/public/favicon.ico +0 -0
- package/src/web/public/index.html +0 -17
- package/src/web/public/logo-rounded.png +0 -0
- package/src/web/public/logo.png +0 -0
- /package/{src → dist}/web/public/assets/view-CgLZr6WS.css +0 -0
- /package/{src → dist}/web/public/assets/zip-gQ69BVQr.js +0 -0
- /package/{src/web/frontend → dist/web}/public/favicon-16.png +0 -0
- /package/{src/web/frontend → dist/web}/public/favicon-32.png +0 -0
- /package/{src/web/frontend → dist/web}/public/favicon-48.png +0 -0
- /package/{src/web/frontend → dist/web}/public/favicon.ico +0 -0
- /package/{src/web/frontend → dist/web}/public/logo-rounded.png +0 -0
- /package/{src/web/frontend → dist/web}/public/logo.png +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,52 @@
|
|
|
2
2
|
|
|
3
3
|
本文件格式参考 [Keep a Changelog](https://keepachangelog.com/),中文正文。
|
|
4
4
|
|
|
5
|
+
## 0.29.0 (2026-11-10)
|
|
6
|
+
|
|
7
|
+
**新增 `shortcut` 字段与 `peek` 三态外壳;`source` 迁到同一外壳。三种形态、焦点与 reduced-motion 均经真实浏览器走查(57 项断言全过,控制台/网络 0 错误)。**
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **快捷键字段(`shortcut`)**:值按「组 → 条目 → 按键」三层存;折叠条只报组数/条数,
|
|
12
|
+
点「详细」打开键位面板(默认全屏,可切侧边/居中)——左侧分组目录、右侧说明表、底部键盘图,
|
|
13
|
+
录入时直接按组合键、悬停条目点亮对应键。`combo` 存 `KeyboardEvent.code`,写入接受
|
|
14
|
+
`"Ctrl+R"` / `["Ctrl","R"]` / `[{code,label}]` 三种写法。
|
|
15
|
+
- **`peek` 三态外壳**:同一份内容可在 side / center / fullpage 之间切换。center/fullpage 补遮罩、
|
|
16
|
+
`aria-modal`、焦点陷阱、Esc 关闭与 reduced-motion;side 保持原右侧栏的宽度、断点与动画不变。
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- 原始资料(`source`)迁移到 `peek` 外壳:默认仍是原来的右侧栏,视觉与交互不变,新增三态切换按钮。
|
|
21
|
+
|
|
22
|
+
### 说明
|
|
23
|
+
|
|
24
|
+
- 走查修掉三处问题:三态选择器与 JSX 类名不一致导致面板尺寸/定位全部失效;点遮罩关闭后焦点掉到
|
|
25
|
+
`body`(现先 `preventDefault` 再关);窄栏下快捷键表格逐字换行、全屏下表格与键盘图之间留大片空洞。
|
|
26
|
+
|
|
27
|
+
## 0.28.0 (2026-11-10)
|
|
28
|
+
|
|
29
|
+
**全量 TypeScript 化:后端与前端源码统一为 `.ts/.tsx`;字段与模块改为注册表驱动。对外行为不变。**
|
|
30
|
+
|
|
31
|
+
### Changed
|
|
32
|
+
|
|
33
|
+
- **源码全量 TypeScript**:`src/**` 不再有 `.js/.jsx`;`pnpm build` 先用 `tsc -p tsconfig.build.json`
|
|
34
|
+
产出 `dist/**/*.js`(`.ts` 导入后缀在 emit 时改写),再把面板构建到 `dist/web/public`。
|
|
35
|
+
- **字段收敛为穷举注册表**:服务端 `FIELD_BEHAVIOR` / `FIELD_SEAL`、前端 `FIELD_CONTROLS`
|
|
36
|
+
都是 `Record<FieldType, …>`;`FIELD_TYPES` 加一项而漏实现/漏控件,会直接编译失败。
|
|
37
|
+
- **模块「目录即声明」**:`src/modules/<id>/index.ts` 自动装载,新增模块不再需要改注册表与 eslint 清单。
|
|
38
|
+
- **前端只消费 `shared`**:类型与零依赖纯函数从 `src/shared/**` 引入,eslint 边界规则覆盖 `.ts/.tsx`,
|
|
39
|
+
继续拦住 `import '../../core/**'` 与 `import '../../modules/**'`。
|
|
40
|
+
|
|
41
|
+
### Fixed
|
|
42
|
+
|
|
43
|
+
- **导出 ZIP 时表格的敏感列按列定义解密**:此前 `plainValues` 只处理 `entrylist`,含敏感列的表格会带密文出包,
|
|
44
|
+
换机器后永久不可解(独立提交 `fc4b9e2`)。
|
|
45
|
+
|
|
46
|
+
### 说明
|
|
47
|
+
|
|
48
|
+
- 命令、HTTP 响应形状、面板文案与交互、`store.json` 格式均未变化;`engines.node` 仍是 `>=18.17`。
|
|
49
|
+
- 贡献者:单测直接执行 `.ts` 需要 Node `>=22.18`;改了后端源码要重新 `pnpm build`。
|
|
50
|
+
|
|
5
51
|
## 0.27.0 (2026-11-08)
|
|
6
52
|
|
|
7
53
|
**表格字段重做:列头 ⋮ 属性菜单、行列都有抓手、去掉了那一整块「列设置」表单。**
|
package/README.md
CHANGED
|
@@ -11,13 +11,26 @@ nx-sk serve # 打开面板(http://127.0.0.1:7866)
|
|
|
11
11
|
|
|
12
12
|
## 安装
|
|
13
13
|
|
|
14
|
+
**要求 Node.js >= 18.17。** 包内是构建好的 `dist/`(纯 JS),运行时不需要 TypeScript。
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm i -g nx-sk # 命令名就是包名
|
|
18
|
+
nx-sk version
|
|
19
|
+
nx-sk serve # 打开面板
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## 开发
|
|
23
|
+
|
|
24
|
+
**开发/测试需要 Node >= 22.18**(单测用 `node --test` 直接跑 `.ts`,依赖 Node 原生类型剥离);
|
|
25
|
+
运行 CLI 与面板仍只需 >= 18.17。改了后端要重新构建——`dist/` 是运行时唯一入口。
|
|
26
|
+
|
|
14
27
|
命令名就是包名。**推荐做成全局垫片**(全局 node_modules 里是指向本项目的软链,
|
|
15
28
|
改代码立刻生效,不用重新安装):
|
|
16
29
|
|
|
17
30
|
```bash
|
|
18
31
|
cd <本项目>
|
|
19
32
|
pnpm install # 只为构建面板;CLI 侧零依赖
|
|
20
|
-
pnpm run build #
|
|
33
|
+
pnpm run build # tsc → dist/**/*.js,vite → dist/web/public
|
|
21
34
|
npm link # → 全局多了 nx-sk / nx-sk.cmd / nx-sk.ps1
|
|
22
35
|
nx-sk version # 从任何目录都能跑
|
|
23
36
|
nx-sk serve # 打开面板
|
|
@@ -45,7 +58,7 @@ nx-sk serve # 打开面板
|
|
|
45
58
|
>
|
|
46
59
|
> 别忘了 `chmod +x ~/.local/bin/nx-sk`。验证:`cd / && nx-sk version`。
|
|
47
60
|
|
|
48
|
-
>
|
|
61
|
+
> 不想污染全局也行:先 `pnpm build`,再 `node bin/nx-sk.mjs <子命令>`,或 `npx --no-install . <子命令>`。
|
|
49
62
|
|
|
50
63
|
### skill:用**软链垫片**(推荐)
|
|
51
64
|
|
|
@@ -516,9 +529,9 @@ pnpm test # = lint + build + 冒烟 + 单测
|
|
|
516
529
|
| --- | --- |
|
|
517
530
|
| `bin/nx-sk.mjs` | 唯一入口,只转发 argv + 兜异常 |
|
|
518
531
|
| `src/core/` | 零业务语义:paths / errors / store / fsx / crypto / vault / fields / attachments / render / ids / open |
|
|
519
|
-
| `src/modules/<域>/` | `index.js`(action 声明) + `service.js`(业务)
|
|
532
|
+
| `src/modules/<域>/` | `index.js`(action 声明) + `service.js`(业务)。**不声明视图** |
|
|
520
533
|
| `src/runtime/` | registry / spec / cli / api / server —— 装配层,不写业务 |
|
|
521
|
-
| `src/web/frontend/` | React 壳 + 组件 +
|
|
534
|
+
| `src/web/frontend/` | React 壳 + 组件 + `modules/<域>/view.jsx` + 视图注册表(视图只住这里) |
|
|
522
535
|
| `assets/nx-sk/` | 随包分发的 skill(SKILL.md + references/) |
|
|
523
536
|
| `tests/unit/` · `tests/smoke.mjs` | 一致性断言 + 端到端冒烟 |
|
|
524
537
|
|
|
@@ -553,7 +566,7 @@ agent 手册** —— 它写在创建本项目的脚手架 skill `server-cli-web
|
|
|
553
566
|
| 把打码值当成新值写回去 | 密钥字段被写成 `sk-1****cdef` 这串掩码,**原凭据永久丢失** | 写入前比对掩码:相等就当成「未改动」保留原密文;含 `******` 的值直接拒绝 |
|
|
554
567
|
| 删条目/栏目没有留退路 | 误删即不可逆;这是用户的**唯一一份**个人信息 | 破坏性写操作一律先 `transfer export` 导出,导出的包就是唯一回退手段 —— 不另设本地备份模块 |
|
|
555
568
|
| store.json 解析失败就当空库继续 | 下一次写入把用户数据永久覆盖 | 先把损坏文件改名为 `store.json.corrupt-<时间>.json`,再降级返回空结构 |
|
|
556
|
-
| 前端 import 了 `node:*` 或 `core/` | Vite 把 Node 侧代码打进浏览器包,dev 模式白屏 | lint 的 `files`
|
|
569
|
+
| 前端 import 了 `node:*` 或 `core/` | Vite 把 Node 侧代码打进浏览器包,dev 模式白屏 | lint 的 `files` 覆盖整个 `src/web/frontend/**`(视图都在这里),禁掉 `node:*` / `core` / `runtime` / `service.js` |
|
|
557
570
|
| 新增模块忘了往 eslint 互依禁列里补一行 | **静默**:新模块变成「谁都可以依赖」,且规则随模块数增加持续衰减 | 在禁列旁留注释说明它是**逐模块枚举**的、漏补是静默的;加模块前先读 `eslint.config.js` |
|
|
558
571
|
| 代理前缀 `/api` 与前端源码目录 `api/` 撞车 | 只在 dev 模式整页白屏,报错却是 404 / ECONNREFUSED,离根因很远 | vite 代理加 `bypass`,按「是不是前端资源」分流;并用测试钉住 `shouldServeLocally` |
|
|
559
572
|
| 把「上传 / 选择」放到附件中心,再让条目去引用 | 条目里看不到上传入口,用户不知道该在哪儿加文件;附件中心还被迫预定义分类与槽位,跟栏目脱节 | **上传 / 选择发生在栏目条目里**(`file` 字段的值 = 附件 id);附件中心由栏目驱动、只做统一展示与库存管理,**不预定义分类、不做指派** |
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
大多数字段的值是标量(一行字、一个数字、一个日期)。这一篇只讲**值不是标量**的字段,
|
|
4
4
|
以及它们各自的规则、写入时的体检、空值与默认值怎么处理:
|
|
5
5
|
|
|
6
|
-
`table`(表格)· `entrylist`(结构清单)· `md`(图文)· `file`(附件)· `source`(原始资料袋)· `secret`(密文)
|
|
6
|
+
`table`(表格)· `entrylist`(结构清单)· `md`(图文)· `file`(附件)· `source`(原始资料袋)· `shortcut`(快捷键)· `secret`(密文)
|
|
7
7
|
|
|
8
8
|
> 为什么要单独一篇:这些字段的**值形状**决定了怎么读、怎么写、怎么在面板上编。
|
|
9
9
|
> 把它们当普通字符串塞进去,最常见的后果不是报错,而是「存进去了但面板看不见」——
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
| `md` | 一段 markdown 字符串 | — | 图文编辑器(Ctrl+V 贴图) | `entry get`(图片还原成路径) |
|
|
19
19
|
| `file` | `[附件id, …]` | 字段字典的 `kind` / `maxItems` | 附件选择器(上传 / 从库里选) | `entry get`(附件名 + 物理路径) |
|
|
20
20
|
| `source` | `[{id, kind, name, text\|fileId\|url, addedAt, …}]` | 内置(每个栏目自带一个) | 底部折叠条 → 右侧侧边栏 | `source get` |
|
|
21
|
+
| `shortcut` | `[{id, name, shortcuts:[{id, combo:[{code,label}], description, condition?}]}]` | 数据自己(组 → 条目 → 按键) | 折叠条只报组数/条数;`详细` 打开键位面板(默认全屏,可切侧边/居中) | `entry get` |
|
|
21
22
|
| `secret` | 一个字符串(落盘是密文) | — | 输入框 | `key get` / `entry get` |
|
|
22
23
|
|
|
23
24
|
共同点:**写入即校验**(不合法就整条拒绝,不会存半条)、**空值有明确语义**、
|
|
@@ -190,6 +191,29 @@
|
|
|
190
191
|
普通文字本来就是合法 markdown,老数据不用迁移。
|
|
191
192
|
- 不计完整度(`fill: optional`);袋里是明文,**敏感内容不要进袋**。
|
|
192
193
|
|
|
194
|
+
## `shortcut` 快捷键
|
|
195
|
+
|
|
196
|
+
- 值 = **组 → 条目 → 按键**三层:`[{ name, shortcuts: [{ combo, description, condition? }] }]`。
|
|
197
|
+
组是目录,条目是「这条快捷键做什么」,`condition` 写生效范围(不写 = 全局)。
|
|
198
|
+
- `combo` 存 `KeyboardEvent.code`(物理键位),不是 `key`——换键盘布局/输入法不会让快捷键错位。
|
|
199
|
+
- 写入时三种写法等价(都会归一成同一种形状):
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
# 1) 最省事的字符串
|
|
203
|
+
nx-sk entry add --section demo --title 快捷键示例 \
|
|
204
|
+
--set 'keys=[{"name":"全局","shortcuts":[{"combo":"Ctrl+Shift+R","description":"刷新"}]}]'
|
|
205
|
+
|
|
206
|
+
# 2) 键名数组
|
|
207
|
+
--set 'keys=[{"name":"列表","shortcuts":[{"combo":["J"],"description":"下一条"}]}]'
|
|
208
|
+
|
|
209
|
+
# 3) 面板存下来的按键对象(精确控制左右修饰键)
|
|
210
|
+
--set 'keys=[{"name":"全局","shortcuts":[{"combo":[{"code":"ControlLeft","label":"Ctrl"},{"code":"KeyK","label":"K"}],"description":"命令面板"}]}]'
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
- 每条必须有 `description`;键位认不出(例如 `Ctrl+?`)会整条拒绝并指出是第几组第几条。
|
|
214
|
+
- 面板里点 `详细` 打开键位图:悬停条目点亮对应键;`新增` 后直接按组合键即可录入。
|
|
215
|
+
- 不能当表格列(`cell: false`);不引用附件,没有子密文。
|
|
216
|
+
|
|
193
217
|
## `secret` 密文
|
|
194
218
|
|
|
195
219
|
- 值是一个字符串,落盘 AES-256-GCM 密文;读出来默认原文,`--mask` 打码。
|
package/bin/nx-sk.mjs
CHANGED
|
@@ -1,7 +1,25 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// nx-sk
|
|
3
|
-
// 所有命令分发都在
|
|
4
|
-
|
|
2
|
+
// nx-sk 的唯一可执行入口:转发 argv、兜住未捕获的异常。
|
|
3
|
+
// 所有命令分发都在 dist/runtime/cli.js(那里才是命令表)——只跑构建产物,
|
|
4
|
+
// 不在运行时做 TypeScript 类型剥离(Node 对 node_modules 下的 .ts 直接拒绝)。
|
|
5
|
+
//
|
|
6
|
+
// 首次从源码仓库直接跑、或改了后端还没构建时,dist 不存在:给一句能照做的提示,
|
|
7
|
+
// 而不是把 ERR_MODULE_NOT_FOUND 的栈甩给用户。
|
|
8
|
+
import { existsSync } from 'node:fs';
|
|
9
|
+
import { fileURLToPath } from 'node:url';
|
|
10
|
+
|
|
11
|
+
const cliUrl = new URL('../dist/runtime/cli.js', import.meta.url);
|
|
12
|
+
|
|
13
|
+
if (!existsSync(fileURLToPath(cliUrl))) {
|
|
14
|
+
process.stderr.write(
|
|
15
|
+
'nx-sk: 找不到构建产物 dist/runtime/cli.js。\n'
|
|
16
|
+
+ '源码仓库需要先构建:pnpm build(npm run build)——它会先 tsc 产出 dist,再构建面板。\n'
|
|
17
|
+
+ '如果你是用 npm 全局安装的,这说明包不完整,请重装:npm i -g nx-sk。\n',
|
|
18
|
+
);
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const { runCli } = await import(cliUrl.href);
|
|
5
23
|
|
|
6
24
|
runCli(process.argv.slice(2)).catch((err) => {
|
|
7
25
|
const message = err && err.message ? err.message : String(err);
|
|
@@ -12,8 +12,7 @@
|
|
|
12
12
|
// 又会拦住用 --data 写入的合法 CRLF 多行值(高假阳性);LF 截断后则与合法单行值
|
|
13
13
|
// 完全不可区分。可靠的信号不存在,因此只能提供可靠通道 + 修好通道本身。
|
|
14
14
|
import { readFileSync } from 'node:fs';
|
|
15
|
-
import { badInput } from
|
|
16
|
-
|
|
15
|
+
import { badInput } from "./errors.js";
|
|
17
16
|
/**
|
|
18
17
|
* `--data` 的值:JSON 字面量 / `@文件路径` / `-`(stdin)。
|
|
19
18
|
*
|
|
@@ -21,33 +20,34 @@ import { badInput } from './errors.js';
|
|
|
21
20
|
* 「读 stdin」因此不是一个无法测试的隐式依赖,也让本模块保持纯函数(不自己碰 fd 0)。
|
|
22
21
|
*/
|
|
23
22
|
export function parseDataArg(raw, takeStdin) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
23
|
+
const s = String(raw ?? '').trim();
|
|
24
|
+
if (!s)
|
|
25
|
+
throw badInput('--data 需要一个 JSON 字面量、@文件路径,或 -(从 stdin 读)');
|
|
26
|
+
if (s === '-' || s === '@-')
|
|
27
|
+
return parseJson(takeStdin(), '-');
|
|
28
|
+
if (s.startsWith('@'))
|
|
29
|
+
return parseJson(readText(s.slice(1)), s.slice(1));
|
|
30
|
+
return parseJson(s, '--data'); // 直接给的字面 JSON
|
|
29
31
|
}
|
|
30
|
-
|
|
31
32
|
/** 值本身走 stdin 的入口(`key set NAME -`)。true 表示「这个值来自 stdin」。 */
|
|
32
33
|
export function parseStdinValue(raw) {
|
|
33
|
-
|
|
34
|
+
return String(raw ?? '').trim() === '-';
|
|
34
35
|
}
|
|
35
|
-
|
|
36
36
|
function parseJson(text, src) {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
try {
|
|
38
|
+
return JSON.parse(text);
|
|
39
|
+
}
|
|
40
|
+
catch (e) {
|
|
41
|
+
throw badInput(`--data 不是合法 JSON(${src}): ${e.message}`);
|
|
42
|
+
}
|
|
42
43
|
}
|
|
43
|
-
|
|
44
44
|
function readText(p) {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
45
|
+
try {
|
|
46
|
+
return readFileSync(p, 'utf8');
|
|
47
|
+
}
|
|
48
|
+
catch (e) {
|
|
49
|
+
// 路径写法是最常见的坑:Git Bash 的 /tmp 在 node 侧看不到(真实事故 ENOENT),
|
|
50
|
+
// 所以错误里直接把 Windows 路径形式写出来,省掉一轮排查。
|
|
51
|
+
throw badInput(`读取文件失败: ${p}(${e.message})—— Windows 上请用 C:/Users/... 形式的路径`);
|
|
52
|
+
}
|
|
52
53
|
}
|
|
53
|
-
|