@liujitcn/kratos-admin-cli 0.0.85 → 0.0.87

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@liujitcn/kratos-admin-cli",
3
- "version": "0.0.85",
3
+ "version": "0.0.87",
4
4
  "type": "module",
5
5
  "description": "Create pnpm workspace projects for kratos-admin business modules",
6
6
  "license": "MIT",
@@ -13,7 +13,7 @@
13
13
  "kratos-admin": "./dist/index.js"
14
14
  },
15
15
  "engines": {
16
- "node": "^20.19.0 || >=22.12.0"
16
+ "node": "^24.0.0"
17
17
  },
18
18
  "files": [
19
19
  "dist/index.d.ts",
@@ -0,0 +1,2 @@
1
+ # pnpm 生成的 unified diff 以单个空格表示空行上下文。
2
+ patches/*.patch whitespace=-blank-at-eol
@@ -0,0 +1 @@
1
+ 24
@@ -2,3 +2,7 @@
2
2
  /public/*
3
3
  public/*
4
4
  stats.html
5
+
6
+ # 模板占位符尚未渲染,不能作为独立工程解析。
7
+ packages/cli/templates/**
8
+ **/dist/**
@@ -38,6 +38,10 @@ Each directory containing a `package.json` has its own README with details about
38
38
 
39
39
  ## Development
40
40
 
41
+ Use Node.js 24 and pnpm 10.33.4. Run `nvm install && nvm use` first. After dependency upgrades, regenerate the lockfile with `pnpm install --no-frozen-lockfile` and verify it with `pnpm install --frozen-lockfile`.
42
+
43
+ `patches/braces@3.0.3.patch` bounds parser and AST traversal depth for CVE-2026-93687, which has no upstream fixed release. The audit exception applies only to this patch. Run `pnpm test:dependency-security` before `pnpm audit --audit-level high`; remove the patch, this exception and its regression tests together when an upstream fix becomes available.
44
+
41
45
  ```bash
42
46
  pnpm install
43
47
  pnpm dev
@@ -39,6 +39,10 @@ __MODULE_TABLE_ROWS__
39
39
 
40
40
  ## 开发
41
41
 
42
+ 使用 Node.js 24 和 pnpm 10.33.4,先执行 `nvm install && nvm use`。依赖升级后通过 `pnpm install --no-frozen-lockfile` 生成锁文件,再用 `pnpm install --frozen-lockfile` 验证。
43
+
44
+ `patches/braces@3.0.3.patch` 限制括号解析与 AST 遍历深度,处理尚无上游修复版本的 `CVE-2026-93687`;审计豁免仅针对此补丁。执行 `pnpm test:dependency-security` 验证实际安装的依赖后再运行 `pnpm audit --audit-level high`,上游发布修复版本后同时删除补丁、该豁免和对应测试。
45
+
42
46
  ```bash
43
47
  pnpm install
44
48
  pnpm dev
@@ -12,20 +12,21 @@
12
12
  "lint:oxlint": "oxlint --fix --vue-plugin --config ./internal/lint-config/oxlint.json --ignore-path .oxlintignore ./apps ./packages ./internal ./scripts",
13
13
  "lint:lint-staged": "lint-staged",
14
14
  "lint:prettier": "prettier --write \"{apps,packages,internal,scripts}/**/*.{js,mjs,ts,json,tsx,css,less,scss,vue,html,md,yaml}\"",
15
- "lint:stylelint": "stylelint --cache --fix \"{apps,packages}/**/*.{vue,less,postcss,css,scss}\" --cache-location node_modules/.cache/stylelint/",
15
+ "lint:stylelint": "stylelint --config .stylelintrc.cjs --cache --fix \"{apps,packages}/**/*.{vue,less,postcss,css,scss}\" --cache-location node_modules/.cache/stylelint/",
16
16
  "generate:auto-import-types": "node scripts/generate-auto-import-types.mjs",
17
17
  "i18n:sync": "node scripts/sync-locales.mjs --write",
18
- "i18n:check": "node scripts/sync-locales.mjs"
18
+ "i18n:check": "node scripts/sync-locales.mjs",
19
+ "test:dependency-security": "node --test scripts/dependency-security.test.mjs"
19
20
  },
20
21
  "devDependencies": {
21
- "@types/node": "^25.9.1",
22
+ "@types/node": "26.5.1",
22
23
  "sass": "^1.100.0",
23
24
  "turbo": "^2.5.6",
24
25
  "typescript": "6.0.3",
25
26
  "vite": "^8.0.14",
26
27
  "vue-tsc": "^3.3.2",
27
- "@commitlint/cli": "^18.4.3",
28
- "@commitlint/config-conventional": "^18.4.3",
28
+ "@commitlint/cli": "21.2.2",
29
+ "@commitlint/config-conventional": "21.2.2",
29
30
  "@types/md5": "^2.3.5",
30
31
  "@types/nprogress": "^0.2.3",
31
32
  "@types/qs": "^6.9.15",
@@ -39,7 +40,7 @@
39
40
  "postcss-html": "^1.8.1",
40
41
  "prettier": "^3.3.2",
41
42
  "standard-version": "^9.5.0",
42
- "stylelint": "^17.12.0",
43
+ "stylelint": "^17.15.0",
43
44
  "stylelint-config-html": "^1.1.0",
44
45
  "stylelint-config-recess-order": "^7.7.0",
45
46
  "stylelint-config-recommended-scss": "^17.0.1",
@@ -50,7 +51,7 @@
50
51
  "ts-proto": "^2.11.8"
51
52
  },
52
53
  "engines": {
53
- "node": "^20.19.0 || >=22.12.0"
54
+ "node": "^24.0.0"
54
55
  },
55
56
  "packageManager": "pnpm@10.33.4",
56
57
  "pnpm": {
@@ -61,7 +62,11 @@
61
62
  "svg-baker>micromatch": "4.0.8",
62
63
  "svg-baker>postcss": "8.5.26",
63
64
  "vue": "3.5.42",
64
- "vue-router": "5.3.1"
65
+ "vue-router": "5.3.1",
66
+ "brace-expansion@<2.0.0": "1.1.20",
67
+ "brace-expansion@>=2.0.0 <3.0.0": "2.1.6",
68
+ "handlebars@<4.7.10": "4.7.10",
69
+ "source-map-js@<1.2.2": "1.2.2"
65
70
  },
66
71
  "onlyBuiltDependencies": [
67
72
  "@parcel/watcher",
@@ -76,8 +81,12 @@
76
81
  "auditConfig": {
77
82
  "ignoreCves": [
78
83
  "CVE-2025-71330",
79
- "CVE-2025-71329"
84
+ "CVE-2025-71329",
85
+ "CVE-2026-93687"
80
86
  ]
87
+ },
88
+ "patchedDependencies": {
89
+ "braces@3.0.3": "patches/braces@3.0.3.patch"
81
90
  }
82
91
  }
83
92
  }
@@ -0,0 +1,135 @@
1
+ diff --git a/lib/compile.js b/lib/compile.js
2
+ index dce69beb90ece5c3b0ca234a949418f9f34eedbc..2f9fd0e732e0e1f90f71ce3f7681505002ad3290 100644
3
+ --- a/lib/compile.js
4
+ +++ b/lib/compile.js
5
+ @@ -2,9 +2,14 @@
6
+
7
+ const fill = require('fill-range');
8
+ const utils = require('./utils');
9
+ +const { MAX_DEPTH } = require('./constants');
10
+
11
+ const compile = (ast, options = {}) => {
12
+ - const walk = (node, parent = {}) => {
13
+ + const walk = (node, parent = {}, depth = 0) => {
14
+ + // 调用方也能直接传入 AST,因此遍历入口独立限制深度。
15
+ + if (node.nodes && depth > MAX_DEPTH) {
16
+ + throw new SyntaxError('Pattern nesting exceeds maximum depth');
17
+ + }
18
+ const invalidBlock = utils.isInvalidBrace(parent);
19
+ const invalidNode = node.invalid === true && options.escapeInvalid === true;
20
+ const invalid = invalidBlock === true || invalidNode === true;
21
+ @@ -47,7 +52,7 @@ const compile = (ast, options = {}) => {
22
+
23
+ if (node.nodes) {
24
+ for (const child of node.nodes) {
25
+ - output += walk(child, node);
26
+ + output += walk(child, node, depth + 1);
27
+ }
28
+ }
29
+
30
+ diff --git a/lib/constants.js b/lib/constants.js
31
+ index 2bb3b8840382c56700869b3a9e1f958fcce01efd..3289d5650833bbbe39882f833bce71612d661c12 100644
32
+ --- a/lib/constants.js
33
+ +++ b/lib/constants.js
34
+ @@ -2,6 +2,7 @@
35
+
36
+ module.exports = {
37
+ MAX_LENGTH: 10000,
38
+ + MAX_DEPTH: 128,
39
+
40
+ // Digits
41
+ CHAR_0: '0', /* 0 */
42
+ diff --git a/lib/expand.js b/lib/expand.js
43
+ index 35b2c41d6afdb8f0197959e26079f266e48370d3..2c4a5ee11e882a172c2654b985b1447b53b1d204 100644
44
+ --- a/lib/expand.js
45
+ +++ b/lib/expand.js
46
+ @@ -3,6 +3,7 @@
47
+ const fill = require('fill-range');
48
+ const stringify = require('./stringify');
49
+ const utils = require('./utils');
50
+ +const { MAX_DEPTH } = require('./constants');
51
+
52
+ const append = (queue = '', stash = '', enclose = false) => {
53
+ const result = [];
54
+ @@ -33,7 +34,10 @@ const append = (queue = '', stash = '', enclose = false) => {
55
+ const expand = (ast, options = {}) => {
56
+ const rangeLimit = options.rangeLimit === undefined ? 1000 : options.rangeLimit;
57
+
58
+ - const walk = (node, parent = {}) => {
59
+ + const walk = (node, parent = {}, depth = 0) => {
60
+ + if (node.nodes && depth > MAX_DEPTH) {
61
+ + throw new SyntaxError('Pattern nesting exceeds maximum depth');
62
+ + }
63
+ node.queue = [];
64
+
65
+ let p = parent;
66
+ @@ -100,7 +104,7 @@ const expand = (ast, options = {}) => {
67
+ }
68
+
69
+ if (child.nodes) {
70
+ - walk(child, node);
71
+ + walk(child, node, depth + 1);
72
+ }
73
+ }
74
+
75
+ diff --git a/lib/parse.js b/lib/parse.js
76
+ index 3a6988e629f52aee6609dc5ec290a5e9ff47cecb..ec76ce445e89d8cf78b23596296f19f1832a8057 100644
77
+ --- a/lib/parse.js
78
+ +++ b/lib/parse.js
79
+ @@ -8,6 +8,7 @@ const stringify = require('./stringify');
80
+
81
+ const {
82
+ MAX_LENGTH,
83
+ + MAX_DEPTH,
84
+ CHAR_BACKSLASH, /* \ */
85
+ CHAR_BACKTICK, /* ` */
86
+ CHAR_COMMA, /* , */
87
+ @@ -143,6 +144,10 @@ const parse = (input, options = {}) => {
88
+ */
89
+
90
+ if (value === CHAR_LEFT_PARENTHESES) {
91
+ + // 限制 AST 深度,避免后续递归遍历耗尽调用栈。
92
+ + if (stack.length > MAX_DEPTH) {
93
+ + throw new SyntaxError('Pattern nesting exceeds maximum depth');
94
+ + }
95
+ block = push({ type: 'paren', nodes: [] });
96
+ stack.push(block);
97
+ push({ type: 'text', value });
98
+ @@ -195,6 +200,9 @@ const parse = (input, options = {}) => {
99
+ */
100
+
101
+ if (value === CHAR_LEFT_CURLY_BRACE) {
102
+ + if (stack.length > MAX_DEPTH) {
103
+ + throw new SyntaxError('Pattern nesting exceeds maximum depth');
104
+ + }
105
+ depth++;
106
+
107
+ const dollar = prev.value && prev.value.slice(-1) === '$' || block.dollar === true;
108
+ diff --git a/lib/stringify.js b/lib/stringify.js
109
+ index 8bcf872c31894f81a8c64d9202fd607e4fd7ea2b..a88fa77189d01ec08a8084ab6275be7a33d5efbd 100644
110
+ --- a/lib/stringify.js
111
+ +++ b/lib/stringify.js
112
+ @@ -1,9 +1,13 @@
113
+ 'use strict';
114
+
115
+ const utils = require('./utils');
116
+ +const { MAX_DEPTH } = require('./constants');
117
+
118
+ module.exports = (ast, options = {}) => {
119
+ - const stringify = (node, parent = {}) => {
120
+ + const stringify = (node, parent = {}, depth = 0) => {
121
+ + if (node.nodes && depth > MAX_DEPTH) {
122
+ + throw new SyntaxError('Pattern nesting exceeds maximum depth');
123
+ + }
124
+ const invalidBlock = options.escapeInvalid && utils.isInvalidBrace(parent);
125
+ const invalidNode = node.invalid === true && options.escapeInvalid === true;
126
+ let output = '';
127
+ @@ -21,7 +25,7 @@ module.exports = (ast, options = {}) => {
128
+
129
+ if (node.nodes) {
130
+ for (const child of node.nodes) {
131
+ - output += stringify(child);
132
+ + output += stringify(child, {}, depth + 1);
133
+ }
134
+ }
135
+ return output;
@@ -0,0 +1,50 @@
1
+ import assert from "node:assert/strict";
2
+ import { createRequire } from "node:module";
3
+ import test from "node:test";
4
+
5
+ const require = createRequire(import.meta.url);
6
+
7
+ for (const consumer of ["stylelint", "lint-staged"]) {
8
+ const consumerRequire = createRequire(require.resolve(consumer));
9
+ const micromatchRequire = createRequire(consumerRequire.resolve("micromatch"));
10
+ const braces = micromatchRequire("braces");
11
+
12
+ test(`${consumer} 保留常规嵌套 glob 的编译与展开结果`, () => {
13
+ const pattern = "src/{core,modules}/{a,b}.vue";
14
+ assert.equal(braces.compile(pattern), "src/(core|modules)/(a|b).vue");
15
+ assert.deepEqual(braces.expand(pattern), ["src/core/a.vue", "src/core/b.vue", "src/modules/a.vue", "src/modules/b.vue"]);
16
+ assert.equal(braces.stringify(pattern), pattern);
17
+ assert.deepEqual(braces.expand("{1..3}"), ["1", "2", "3"]);
18
+ });
19
+
20
+ for (const [name, pattern] of [
21
+ ["花括号", "{".repeat(4000) + "a,b" + "}".repeat(4000)],
22
+ ["圆括号", "(".repeat(4000) + "a" + ")".repeat(4000)],
23
+ ["未闭合括号", "{".repeat(4000) + "a"]
24
+ ]) {
25
+ test(`${consumer} 在递归前拒绝过深${name}`, () => {
26
+ for (const method of ["parse", "compile", "expand", "stringify"]) {
27
+ assert.throws(() => braces[method](pattern), { name: "SyntaxError", message: "Pattern nesting exceeds maximum depth" });
28
+ }
29
+ });
30
+ }
31
+
32
+ test(`${consumer} 直接接收 AST 时仍限制遍历深度`, () => {
33
+ for (const method of ["compile", "expand", "stringify"]) {
34
+ let node = { type: "text", value: "a" };
35
+ for (let depth = 0; depth < 2000; depth++) {
36
+ const parent = { type: "paren", nodes: [node] };
37
+ node.parent = parent;
38
+ node = parent;
39
+ }
40
+ const ast = { type: "root", nodes: [node] };
41
+ node.parent = ast;
42
+ assert.throws(() => braces[method](ast), { name: "SyntaxError", message: "Pattern nesting exceeds maximum depth" });
43
+ }
44
+ });
45
+
46
+ test(`${consumer} 不把转义字符或引号中的括号计入深度`, () => {
47
+ assert.doesNotThrow(() => braces.compile("\\{".repeat(1000)));
48
+ assert.doesNotThrow(() => braces.compile('"' + "{".repeat(1000) + '"'));
49
+ });
50
+ }