@tfdesign/b-end 1.0.10 → 1.0.11
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
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* TFDS 版本更新检测(只读,不修改用户项目)
|
|
4
|
+
*
|
|
5
|
+
* 在对方项目根目录执行:
|
|
6
|
+
* node node_modules/@tfdesign/b-end/scripts/check-tfds-update.mjs
|
|
7
|
+
*
|
|
8
|
+
* 也可以直接执行包内脚本:
|
|
9
|
+
* node /path/to/node_modules/@tfdesign/b-end/scripts/check-tfds-update.mjs
|
|
10
|
+
*/
|
|
11
|
+
import fs from 'node:fs';
|
|
12
|
+
import path from 'node:path';
|
|
13
|
+
import { fileURLToPath } from 'node:url';
|
|
14
|
+
|
|
15
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
16
|
+
const __dirname = path.dirname(__filename);
|
|
17
|
+
const pkgRoot = path.resolve(__dirname, '..');
|
|
18
|
+
const packageJsonPath = path.join(pkgRoot, 'package.json');
|
|
19
|
+
const packageName = '@tfdesign/b-end';
|
|
20
|
+
const registryUrl = `https://registry.npmjs.org/${encodeURIComponent(packageName).replace('%2F', '%2f')}`;
|
|
21
|
+
|
|
22
|
+
function readPackageJson() {
|
|
23
|
+
try {
|
|
24
|
+
return JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
25
|
+
} catch (error) {
|
|
26
|
+
console.log('\n[tfds-update-check] 无法读取本地 package.json');
|
|
27
|
+
console.log(` 路径:${packageJsonPath}`);
|
|
28
|
+
console.log(` 错误:${error?.message || error}`);
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function formatDateToMinute(value) {
|
|
34
|
+
if (!value) return '未知';
|
|
35
|
+
const date = new Date(value);
|
|
36
|
+
if (Number.isNaN(date.getTime())) return '未知';
|
|
37
|
+
|
|
38
|
+
const parts = new Intl.DateTimeFormat('zh-CN', {
|
|
39
|
+
timeZone: 'Asia/Shanghai',
|
|
40
|
+
year: 'numeric',
|
|
41
|
+
month: '2-digit',
|
|
42
|
+
day: '2-digit',
|
|
43
|
+
hour: '2-digit',
|
|
44
|
+
minute: '2-digit',
|
|
45
|
+
hour12: false,
|
|
46
|
+
}).formatToParts(date);
|
|
47
|
+
|
|
48
|
+
const byType = Object.fromEntries(parts.map((part) => [part.type, part.value]));
|
|
49
|
+
return `${byType.year}-${byType.month}-${byType.day} ${byType.hour}:${byType.minute}`;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function parseVersion(version) {
|
|
53
|
+
return String(version || '')
|
|
54
|
+
.trim()
|
|
55
|
+
.replace(/^v/i, '')
|
|
56
|
+
.split('-')[0]
|
|
57
|
+
.split('.')
|
|
58
|
+
.map((part) => Number.parseInt(part, 10) || 0);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function compareVersions(a, b) {
|
|
62
|
+
const av = parseVersion(a);
|
|
63
|
+
const bv = parseVersion(b);
|
|
64
|
+
const len = Math.max(av.length, bv.length, 3);
|
|
65
|
+
|
|
66
|
+
for (let i = 0; i < len; i += 1) {
|
|
67
|
+
const left = av[i] || 0;
|
|
68
|
+
const right = bv[i] || 0;
|
|
69
|
+
if (left > right) return 1;
|
|
70
|
+
if (left < right) return -1;
|
|
71
|
+
}
|
|
72
|
+
return 0;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
async function fetchNpmMetadata() {
|
|
76
|
+
const response = await fetch(registryUrl, {
|
|
77
|
+
headers: {
|
|
78
|
+
accept: 'application/json',
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
if (!response.ok) {
|
|
83
|
+
throw new Error(`npm registry 返回 ${response.status} ${response.statusText}`);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return response.json();
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function printUpdateCommand() {
|
|
90
|
+
console.log('\n 建议更新命令:');
|
|
91
|
+
console.log(` npm install ${packageName}@latest --save`);
|
|
92
|
+
console.log(' 或重新执行一键安装:');
|
|
93
|
+
console.log(` npx -y -p ${packageName}@latest tfds-setup`);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async function main() {
|
|
97
|
+
const localPkg = readPackageJson();
|
|
98
|
+
const localVersion = localPkg.version;
|
|
99
|
+
|
|
100
|
+
console.log('\n╔══════════════════════════════════════════════════════╗');
|
|
101
|
+
console.log('║ TFDS NPM 版本更新检测 ║');
|
|
102
|
+
console.log('╚══════════════════════════════════════════════════════╝');
|
|
103
|
+
|
|
104
|
+
if (localPkg.name !== packageName || !localVersion) {
|
|
105
|
+
console.log('\n[tfds-update-check] 当前脚本不在有效的 @tfdesign/b-end 包内。');
|
|
106
|
+
console.log(` 读取到的包名:${localPkg.name || '未知'}`);
|
|
107
|
+
console.log(` 读取到的版本:${localVersion || '未知'}\n`);
|
|
108
|
+
process.exit(1);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
let metadata;
|
|
112
|
+
try {
|
|
113
|
+
metadata = await fetchNpmMetadata();
|
|
114
|
+
} catch (error) {
|
|
115
|
+
console.log('\n⚠ 暂时无法连接 npm registry,已跳过线上版本检测。');
|
|
116
|
+
console.log(` 当前本地版本:v ${localVersion}`);
|
|
117
|
+
console.log(` 原因:${error?.message || error}`);
|
|
118
|
+
console.log('\n 不影响继续使用 TFDS。网络恢复后可重新执行:');
|
|
119
|
+
console.log(` node node_modules/${packageName}/scripts/check-tfds-update.mjs\n`);
|
|
120
|
+
process.exit(0);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const latestVersion = metadata?.['dist-tags']?.latest;
|
|
124
|
+
const localPublishedAt = metadata?.time?.[localVersion];
|
|
125
|
+
const latestPublishedAt = latestVersion ? metadata?.time?.[latestVersion] : metadata?.time?.modified;
|
|
126
|
+
|
|
127
|
+
if (!latestVersion) {
|
|
128
|
+
console.log('\n⚠ 已连接 npm registry,但没有读取到 latest 版本。');
|
|
129
|
+
console.log(` 当前本地版本:v ${localVersion}`);
|
|
130
|
+
console.log(' 请稍后重试,或打开 npm 页面手动确认:');
|
|
131
|
+
console.log(` https://www.npmjs.com/package/${packageName.replace('/', '%2F')}\n`);
|
|
132
|
+
process.exit(0);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const versionState = compareVersions(localVersion, latestVersion);
|
|
136
|
+
|
|
137
|
+
console.log(`\n 包名:${packageName}`);
|
|
138
|
+
console.log(` 当前版本:v ${localVersion}`);
|
|
139
|
+
console.log(` 当前版本更新时间:${formatDateToMinute(localPublishedAt)}`);
|
|
140
|
+
console.log(` 线上最新版本:v ${latestVersion}`);
|
|
141
|
+
console.log(` 最新版本更新时间:${formatDateToMinute(latestPublishedAt)}`);
|
|
142
|
+
|
|
143
|
+
if (versionState < 0) {
|
|
144
|
+
console.log('\n⚠ 检测到 TFDS 有新版本,可以选择更新后再生成页面。');
|
|
145
|
+
printUpdateCommand();
|
|
146
|
+
console.log('');
|
|
147
|
+
process.exit(0);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (versionState > 0) {
|
|
151
|
+
console.log('\n✓ 当前本地版本高于 npm latest,可能是本地预发布或内部测试包。');
|
|
152
|
+
console.log(' 如果你不是在调试 TFDS 包,请确认安装来源是否符合预期。\n');
|
|
153
|
+
process.exit(0);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
console.log('\n✓ 当前已是 npm latest,可以继续使用 TFDS 生成页面。\n');
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
main().catch((error) => {
|
|
160
|
+
console.log('\n[tfds-update-check] 更新检测脚本异常退出。');
|
|
161
|
+
console.log(` 错误:${error?.message || error}\n`);
|
|
162
|
+
process.exit(1);
|
|
163
|
+
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// 安装 @tfdesign/b-end
|
|
1
|
+
// 安装 @tfdesign/b-end 后自动执行四件事:
|
|
2
2
|
//
|
|
3
3
|
// 1. IDE Skill 自动写入(仅 opt-in 通道,不写 always-on)
|
|
4
4
|
// → .cursor/skills/tfds/ (Cursor → /tfds 唤起)
|
|
@@ -21,11 +21,15 @@
|
|
|
21
21
|
// 已有 theme.css import → 跳过;未找到 @import "tailwindcss" → 不改写,终端提示
|
|
22
22
|
// 跳过:SKIP_TFDS_CSS_PATCH=1
|
|
23
23
|
//
|
|
24
|
-
// 3.
|
|
24
|
+
// 3. npm 最新版本检测(只读提醒,不阻断安装)
|
|
25
|
+
// 跳过:SKIP_TFDS_UPDATE_CHECK=1
|
|
26
|
+
//
|
|
27
|
+
// 4. 终端安装报告(已做了什么、还差什么、如何唤起规范)
|
|
25
28
|
|
|
26
29
|
import fs from 'node:fs';
|
|
27
30
|
import os from 'node:os';
|
|
28
31
|
import path from 'node:path';
|
|
32
|
+
import { spawnSync } from 'node:child_process';
|
|
29
33
|
import { fileURLToPath } from 'node:url';
|
|
30
34
|
|
|
31
35
|
const __filename = fileURLToPath(import.meta.url);
|
|
@@ -49,6 +53,7 @@ function readJson(p) {
|
|
|
49
53
|
const projectPkg = readJson(path.join(projectRoot, 'package.json'));
|
|
50
54
|
const isSelfPkg = projectPkg?.name === '@tfdesign/b-end';
|
|
51
55
|
const hasNoPkg = !projectPkg;
|
|
56
|
+
const updateCheckScript = path.join(pkgRoot, 'scripts', 'check-tfds-update.mjs');
|
|
52
57
|
|
|
53
58
|
if (hasNoPkg || isSelfPkg) {
|
|
54
59
|
console.log('\n╔══════════════════════════════════════════════════════╗');
|
|
@@ -107,6 +112,33 @@ function readText(p) {
|
|
|
107
112
|
}
|
|
108
113
|
}
|
|
109
114
|
|
|
115
|
+
function runUpdateCheck() {
|
|
116
|
+
if (process.env.SKIP_TFDS_UPDATE_CHECK === '1') {
|
|
117
|
+
done.push('版本更新检测已跳过(SKIP_TFDS_UPDATE_CHECK=1)');
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (!fs.existsSync(updateCheckScript)) {
|
|
122
|
+
todo.push('未找到版本更新检测脚本,已跳过 npm latest 检查。');
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const result = spawnSync(process.execPath, [updateCheckScript], {
|
|
127
|
+
cwd: projectRoot,
|
|
128
|
+
stdio: 'inherit',
|
|
129
|
+
env: process.env,
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
if (result.error) {
|
|
133
|
+
todo.push(`版本更新检测未完成:${result.error.message}`);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (result.status && result.status !== 0) {
|
|
138
|
+
todo.push('版本更新检测脚本返回异常,但不影响本次安装。可稍后手动执行:node node_modules/@tfdesign/b-end/scripts/check-tfds-update.mjs');
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
110
142
|
function hasSourceSkillDiff(dest) {
|
|
111
143
|
return REQUIRED_TFDS_SKILL_FILES.some((file) => {
|
|
112
144
|
const sourceFile = path.join(skillSrc, file);
|
|
@@ -344,7 +376,13 @@ function patchEntryCss() {
|
|
|
344
376
|
}
|
|
345
377
|
|
|
346
378
|
// ─────────────────────────────────────────────────────────────────
|
|
347
|
-
// Step 3:
|
|
379
|
+
// Step 3: 版本更新检测(只读,不阻断安装)
|
|
380
|
+
// ─────────────────────────────────────────────────────────────────
|
|
381
|
+
|
|
382
|
+
runUpdateCheck();
|
|
383
|
+
|
|
384
|
+
// ─────────────────────────────────────────────────────────────────
|
|
385
|
+
// Step 4: 终端安装报告
|
|
348
386
|
// ─────────────────────────────────────────────────────────────────
|
|
349
387
|
|
|
350
388
|
console.log('\n╔══════════════════════════════════════════════════════╗');
|
|
@@ -375,7 +413,7 @@ console.log(
|
|
|
375
413
|
' 自检(只读):node node_modules/@tfdesign/b-end/scripts/check-tfds-integration.mjs',
|
|
376
414
|
);
|
|
377
415
|
console.log(
|
|
378
|
-
' 跳过 CSS 补丁:SKIP_TFDS_CSS_PATCH=1 npm i | 跳过 Skill:SKIP_TFDS_CURSOR_SKILL=1 npm i |
|
|
416
|
+
' 跳过 CSS 补丁:SKIP_TFDS_CSS_PATCH=1 npm i | 跳过 Skill:SKIP_TFDS_CURSOR_SKILL=1 npm i | 跳过版本检测:SKIP_TFDS_UPDATE_CHECK=1 npm i',
|
|
379
417
|
);
|
|
380
418
|
console.log('');
|
|
381
419
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"system": "b-end",
|
|
3
3
|
"skill": "tfds",
|
|
4
|
-
"generatedAt": "2026-05-
|
|
4
|
+
"generatedAt": "2026-05-11T06:16:09.447Z",
|
|
5
5
|
"purpose": "轻量组件与页面模板目录。AI 先读本文件做选型;确定命中组件后,再到 components.index.json 按 id 读取 props / rules / examples。",
|
|
6
6
|
"counts": {
|
|
7
7
|
"total": 46,
|