create-lumal-admin 0.0.4-beta → 0.0.5-beta
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 +12 -0
- package/README.md +67 -10
- package/dist/cli.d.ts +12 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +91 -28
- package/dist/cli.js.map +1 -1
- package/dist/create.d.ts +2 -1
- package/dist/create.d.ts.map +1 -1
- package/dist/create.js +85 -2
- package/dist/create.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/presets.d.ts +15 -0
- package/dist/presets.d.ts.map +1 -0
- package/dist/presets.js +30 -0
- package/dist/presets.js.map +1 -0
- package/dist/scaffold.d.ts +2 -11
- package/dist/scaffold.d.ts.map +1 -1
- package/dist/scaffold.js +2 -1602
- package/dist/scaffold.js.map +1 -1
- package/dist/templates.d.ts +5 -0
- package/dist/templates.d.ts.map +1 -0
- package/dist/templates.js +62 -0
- package/dist/templates.js.map +1 -0
- package/dist/types.d.ts +25 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +4 -3
- package/templates/base/.env.example +4 -0
- package/templates/base/API-CONTRACT.md +37 -0
- package/templates/base/README.md +42 -0
- package/templates/base/_gitignore +6 -0
- package/templates/base/eslint.config.mjs +8 -0
- package/templates/base/index.html +12 -0
- package/templates/base/package.json +38 -0
- package/templates/base/src/App.vue +214 -0
- package/templates/base/src/components/app/AppHeaderActions.vue +34 -0
- package/templates/base/src/components/app/AppSettingsDrawer.vue +37 -0
- package/templates/base/src/main.ts +41 -0
- package/templates/base/src/router/index.ts +86 -0
- package/templates/base/src/router/views.ts +16 -0
- package/templates/base/src/services/access.ts +2 -0
- package/templates/base/src/services/contracts.ts +29 -0
- package/templates/base/src/services/preferences.ts +41 -0
- package/templates/base/src/services/session-runtime.ts +137 -0
- package/templates/base/src/services/session.ts +14 -0
- package/templates/base/src/styles.scss +178 -0
- package/templates/base/src/views/auth/LoginView.vue +80 -0
- package/templates/base/src/views/dashboard/DashboardView.vue +27 -0
- package/templates/base/src/views/error/ForbiddenView.vue +25 -0
- package/templates/base/src/views/error/NotFoundView.vue +18 -0
- package/templates/base/tests/session.test.ts.template +34 -0
- package/templates/base/tsconfig.json +22 -0
- package/templates/base/vite.config.ts +54 -0
- package/templates/base/vitest.config.ts +3 -0
- package/templates/features/examples/src/modules/examples.ts +10 -0
- package/templates/features/examples/src/views/examples/CrudExampleView.vue +30 -0
- package/templates/features/examples/src/views/examples/FormExampleView.vue +25 -0
- package/templates/features/system/src/business/system/entities.ts +93 -0
- package/templates/features/system/src/modules/system.ts +28 -0
- package/templates/features/system/src/views/system/SystemEntityView.vue +85 -0
- package/templates/modes/http/src/services/data-source.ts +120 -0
- package/templates/modes/http/src/services/http-adapter.ts +124 -0
- package/templates/modes/http/tests/http.test.ts.template +165 -0
- package/templates/modes/local/src/services/data-source.ts +176 -0
- package/templates/modes/local/tests/local.test.ts.template +92 -0
- package/templates/vben-compatible/MIGRATION.md +28 -0
- package/templates/vben-compatible/src/components/migration/VbenFormExample.vue +34 -0
- package/templates/vben-compatible/src/components/migration/VbenUsers.vue +135 -0
- package/templates/vben-compatible/src/modules/vben.ts +17 -0
- package/templates/vben-compatible/src/views/migration/VbenFormView.vue +10 -0
- package/templates/vben-compatible/src/views/migration/VbenUsersView.vue +11 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# create-lumal-admin
|
|
2
2
|
|
|
3
|
+
## 0.0.5-beta (2026-10-20)
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 拆分真实模板资源与 CLI/创建器,支持 minimal、standard、vben-compatible,
|
|
8
|
+
交互及非 TTY、Local/HTTP、Hash/History、可选业务层和安全失败回滚。
|
|
9
|
+
- 生成真实 HTTP 登录、刷新、用户权限菜单、退出及 CRUD 服务,防止旧会话响应回填。
|
|
10
|
+
- standard 增加基础管理模块、Schema/CRUD、标签缓存和偏好;兼容模板增加 V5 迁移页面。
|
|
11
|
+
- 显式加载 Element Plus 深色变量,以真实背景色断言保护主题切换,不只检查状态 class。
|
|
12
|
+
- 通过真实 tarball 的十二种独立消费者组合验证安装、类型、测试、Lint、生产构建与 Chromium。
|
|
13
|
+
- 生成项目依赖精确同步为 0.0.5-beta,不引用 Monorepo 私有源码。
|
|
14
|
+
|
|
3
15
|
## 0.0.4-beta (2026-10-20)
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -4,14 +4,33 @@
|
|
|
4
4
|
|
|
5
5
|
## 使用
|
|
6
6
|
|
|
7
|
-
环境要求:Node.js `>=22.12.0`、pnpm `10.33.0
|
|
7
|
+
环境要求:Node.js `>=22.12.0`、pnpm `10.33.0`。以下命令面向 `0.0.5-beta`,
|
|
8
|
+
显式指定版本,不依赖 npm 的 `latest`。源码开发时以真实 tarball 验证独立消费者,
|
|
9
|
+
不使用旧版 CLI 代替新版模板能力。
|
|
10
|
+
在线文档:https://lumal.cuteyuchen.top/packages/create-lumal-admin。
|
|
8
11
|
|
|
9
12
|
```bash
|
|
10
|
-
pnpm create lumal-admin@0.0.
|
|
11
|
-
pnpm create lumal-admin@0.0.
|
|
13
|
+
pnpm create lumal-admin@0.0.5-beta my-admin
|
|
14
|
+
pnpm create lumal-admin@0.0.5-beta my-admin-http --api-mode http
|
|
12
15
|
```
|
|
13
16
|
|
|
14
|
-
|
|
17
|
+
在 TTY 中依次选择目录、npm 名称、预设、数据源、路由和业务模块。默认
|
|
18
|
+
`standard / local / hash`。CI、非 TTY 或 `--no-interactive` 均使用确定性默认值,不等待输入。
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
pnpm create lumal-admin@0.0.5-beta my-admin --preset standard --api-mode http --router-mode history --no-interactive
|
|
22
|
+
pnpm create lumal-admin@0.0.5-beta my-admin-v5 --preset vben-compatible
|
|
23
|
+
pnpm create lumal-admin@0.0.5-beta my-minimal --preset minimal
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
| 参数 | 取值 |
|
|
27
|
+
| --- | --- |
|
|
28
|
+
| `--preset` | `minimal`、`standard`、`vben-compatible` |
|
|
29
|
+
| `--api-mode` | `local`、`http` |
|
|
30
|
+
| `--router-mode` | `hash`、`history` |
|
|
31
|
+
| `--features` | `system,examples`、单个模块或 `none`;minimal 不接受业务模块 |
|
|
32
|
+
| `--name` | 合法 npm 包名,可与目录不同 |
|
|
33
|
+
| `--help` / `--version` | 帮助 / tarball 自身版本 |
|
|
15
34
|
|
|
16
35
|
生成后执行:
|
|
17
36
|
|
|
@@ -19,6 +38,11 @@ pnpm create lumal-admin@0.0.4-beta my-admin-http --api-mode http
|
|
|
19
38
|
cd my-admin
|
|
20
39
|
pnpm install
|
|
21
40
|
pnpm dev
|
|
41
|
+
pnpm test
|
|
42
|
+
pnpm lint
|
|
43
|
+
pnpm typecheck
|
|
44
|
+
pnpm build
|
|
45
|
+
pnpm preview
|
|
22
46
|
```
|
|
23
47
|
|
|
24
48
|
## 生成内容
|
|
@@ -26,18 +50,51 @@ pnpm dev
|
|
|
26
50
|
- Vue 3 + TypeScript + Vite。
|
|
27
51
|
- Element Plus 作为 UI 基础。
|
|
28
52
|
- `@lumal/core/theme-chalk/index.scss`、`@lumal/core/style.css` 和 SCSS 样式入口。
|
|
29
|
-
- `@lumal/core/minimal`
|
|
53
|
+
- `@lumal/core/minimal` 启动、Router 与权限;Element Plus 组件局部导入,不注册全量 UI 插件。
|
|
30
54
|
- `LumalLayout` 后台布局壳和 `LumalRouterView` 路由出口,采用路由驱动标签模式:固定首页页签、`routeTabResolver` 动态追加、会话级持久化、按标签版本刷新、`cacheKeys` 联动关闭与缓存剔除。
|
|
31
55
|
- 登录页、会话状态、权限菜单和路由守卫。
|
|
32
|
-
-
|
|
56
|
+
- 工作台、403 与独立 404 页面。
|
|
33
57
|
- 主题切换、布局与标签偏好持久化、全局设置抽屉。
|
|
34
|
-
-
|
|
58
|
+
- 统一应用服务、真实 HTTP 认证与显式后端 adapter。
|
|
35
59
|
- Element Plus、Vue 和 Lumal 公共能力的明确 vendor 分包配置。
|
|
36
60
|
|
|
37
61
|
脚手架生成的项目只通过 `@lumal/core`、`@lumal/icons`、`@lumal/icons-vue` 等公开包入口消费能力,不依赖 monorepo 内部源码路径。
|
|
38
62
|
|
|
39
|
-
|
|
63
|
+
| 能力 | minimal | standard | vben-compatible |
|
|
64
|
+
| --- | --- | --- | --- |
|
|
65
|
+
| 启动、布局、认证、权限、主题、请求、403/404 | 有 | 有 | 有 |
|
|
66
|
+
| 动态菜单、标签与页面缓存、系统偏好 | 有 | 有 | 有 |
|
|
67
|
+
| 用户、角色授权、菜单、机构、字典类型/项、配置 | 无 | system 可选层,默认有 | 同 standard |
|
|
68
|
+
| 原生 Schema Form / CRUD 示例 | 无 | examples 可选层,默认有 | 同 standard |
|
|
69
|
+
| Vben 5.7.0 Form / Grid / 权限迁移页面 | 无 | 无 | 有 |
|
|
70
|
+
| 图表、DataV、Cockpit、VXE、富文本、i18n | 不默认安装 | 不默认安装 | 不默认安装 |
|
|
71
|
+
|
|
72
|
+
三个基础 Lumal 包及可选兼容包均精确同步为脚手架自身版本。兼容预设只增加
|
|
73
|
+
`@lumal/vben-compat`,不安装 Vben/VXE/Zod 运行时。根及 `/legacy` 的旧契约不变;
|
|
74
|
+
Vben 5 页面显式导入 `/v5`,边界见生成项目 `MIGRATION.md`。
|
|
75
|
+
|
|
76
|
+
## 数据源与安全
|
|
77
|
+
|
|
78
|
+
Local 是开发演示,账号 `admin/guest`,密码 `lumal123`,Token 每次随机生成。
|
|
79
|
+
生产默认禁止本地演示认证;只允许演示站点显式设置 `VITE_ENABLE_LOCAL_DEMO=true`。
|
|
80
|
+
HTTP 模式不包含演示账号或固定 Token,未配置 `VITE_API_BASE_URL` 立即失败,不回退 Local。
|
|
81
|
+
|
|
82
|
+
HTTP 的登录、刷新、当前用户、角色权限、菜单、退出和 CRUD 均真实请求后端。
|
|
83
|
+
接口及 `lumal-mock` 接入说明位于生成项目 `API-CONTRACT.md`。权限状态、动态路由、
|
|
84
|
+
请求缓存、标签和页面缓存随会话清理;旧请求不能覆盖新登录身份。
|
|
85
|
+
公司包装和字段转换只写入应用 `http-adapter.ts`,不进入 Core。
|
|
86
|
+
|
|
87
|
+
不覆盖非空目录,不提供隐式 force;拒绝文件和符号链接目标。写入失败仅清理本次拥有
|
|
88
|
+
的文件与仍为空的目录,不递归删除目标。项目测试、类型、环境示例和部署说明一并生成;
|
|
89
|
+
History 部署需要服务器回退 `index.html`,不应把 API 请求回退到 HTML。
|
|
90
|
+
|
|
91
|
+
## 维护与验收
|
|
40
92
|
|
|
41
|
-
|
|
93
|
+
`src/cli.ts` 负责参数和交互,`create.ts` 负责安全写入,`templates.ts` 组合
|
|
94
|
+
`templates/base`、`modes`、`features` 和 `vben-compatible` 真实资源。
|
|
95
|
+
资源随 npm tarball 发布,不依赖工作区源码。
|
|
42
96
|
|
|
43
|
-
|
|
97
|
+
仓库运行 `pnpm build` 后执行 `pnpm test:create-consumer`:真实 tarball CLI、
|
|
98
|
+
无 UI 的 minimal/request 消费者、3 预设 × 2 数据源 × 2 路由独立安装/类型/测试/
|
|
99
|
+
Lint/生产构建及 Chromium 交互;另测可选模块体积。结果位于
|
|
100
|
+
`output/release/scaffold-report.json`,截图位于 `output/playwright/scaffold`。
|
package/dist/cli.d.ts
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
export {
|
|
2
|
+
export declare function parseCliArgs(args: string[]): {
|
|
3
|
+
target: string;
|
|
4
|
+
name: string | undefined;
|
|
5
|
+
apiMode: "http" | "local" | undefined;
|
|
6
|
+
preset: "minimal" | "standard" | "vben-compatible" | undefined;
|
|
7
|
+
routerMode: "hash" | "history" | undefined;
|
|
8
|
+
features: ("examples" | "system")[] | undefined;
|
|
9
|
+
help: boolean | undefined;
|
|
10
|
+
version: boolean | undefined;
|
|
11
|
+
interactive: boolean;
|
|
12
|
+
};
|
|
13
|
+
export declare function main(args?: string[]): Promise<void>;
|
|
3
14
|
//# sourceMappingURL=cli.d.ts.map
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAWA,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE;;;;;;;;;;EAqC1C;AAeD,wBAAsB,IAAI,CAAC,IAAI,WAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CA+BtE"}
|
package/dist/cli.js
CHANGED
|
@@ -1,37 +1,100 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { realpathSync } from 'node:fs';
|
|
2
3
|
import { basename, resolve } from 'node:path';
|
|
3
4
|
import process from 'node:process';
|
|
5
|
+
import { createInterface } from 'node:readline/promises';
|
|
6
|
+
import { pathToFileURL } from 'node:url';
|
|
7
|
+
import { parseArgs } from 'node:util';
|
|
4
8
|
import { createLumalAdminProject } from './create.js';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
import { apiModes, features, presets, routerModes } from './presets.js';
|
|
10
|
+
import { getVersion } from './templates.js';
|
|
11
|
+
export function parseCliArgs(args) {
|
|
12
|
+
const { values, positionals } = parseArgs({
|
|
13
|
+
args,
|
|
14
|
+
allowPositionals: true,
|
|
15
|
+
strict: true,
|
|
16
|
+
options: {
|
|
17
|
+
'api-mode': { type: 'string' },
|
|
18
|
+
'features': { type: 'string' },
|
|
19
|
+
'help': { type: 'boolean', short: 'h' },
|
|
20
|
+
'name': { type: 'string' },
|
|
21
|
+
'no-interactive': { type: 'boolean' },
|
|
22
|
+
'preset': { type: 'string' },
|
|
23
|
+
'router-mode': { type: 'string' },
|
|
24
|
+
'version': { type: 'boolean', short: 'v' },
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
if (positionals.length > 1)
|
|
28
|
+
throw new Error('只能指定一个目标目录');
|
|
29
|
+
function choice(name, value, choices) {
|
|
30
|
+
if (value !== undefined && !choices.includes(value))
|
|
31
|
+
throw new Error(`--${name} 仅支持 ${choices.join('、')}`);
|
|
32
|
+
return value;
|
|
33
|
+
}
|
|
34
|
+
const selected = values.features === undefined
|
|
35
|
+
? undefined
|
|
36
|
+
: values.features === 'none' ? [] : values.features.split(',').map(value => choice('features', value, features));
|
|
37
|
+
return {
|
|
38
|
+
target: positionals[0],
|
|
39
|
+
name: values.name,
|
|
40
|
+
apiMode: choice('api-mode', values['api-mode'], apiModes),
|
|
41
|
+
preset: choice('preset', values.preset, presets),
|
|
42
|
+
routerMode: choice('router-mode', values['router-mode'], routerModes),
|
|
43
|
+
features: selected,
|
|
44
|
+
help: values.help,
|
|
45
|
+
version: values.version,
|
|
46
|
+
interactive: !values['no-interactive'],
|
|
47
|
+
};
|
|
13
48
|
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
49
|
+
const help = `用法:pnpm create lumal-admin [目录] [选项]
|
|
50
|
+
|
|
51
|
+
--preset minimal|standard|vben-compatible 模板(默认 standard)
|
|
52
|
+
--api-mode local|http 数据源(默认 local)
|
|
53
|
+
--router-mode hash|history 路由(默认 hash)
|
|
54
|
+
--features system,examples|none 业务模块(标准预设默认全部)
|
|
55
|
+
--name <npm包名> 项目名称(默认目录名)
|
|
56
|
+
--no-interactive 禁用交互,CI/非 TTY 自动禁用
|
|
57
|
+
-h, --help 显示帮助
|
|
58
|
+
-v, --version 显示版本
|
|
59
|
+
|
|
60
|
+
非空目录拒绝覆盖;HTTP 模式必须自行配置后端。`;
|
|
61
|
+
export async function main(args = process.argv.slice(2)) {
|
|
62
|
+
const options = parseCliArgs(args);
|
|
63
|
+
if (options.help) {
|
|
64
|
+
console.log(help);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
if (options.version) {
|
|
68
|
+
console.log(await getVersion());
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
if (options.interactive && process.stdin.isTTY && process.stdout.isTTY && !process.env.CI) {
|
|
72
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
73
|
+
try {
|
|
74
|
+
options.target ??= (await rl.question('项目目录 [lumal-admin]:')).trim() || 'lumal-admin';
|
|
75
|
+
options.name ??= (await rl.question(`npm 项目名称 [${basename(resolve(options.target))}]:`)).trim() || basename(resolve(options.target));
|
|
76
|
+
options.preset ??= parseCliArgs(['--preset', (await rl.question('模板 minimal / standard / vben-compatible [standard]:')).trim() || 'standard']).preset;
|
|
77
|
+
options.apiMode ??= parseCliArgs(['--api-mode', (await rl.question('数据源 local / http [local]:')).trim() || 'local']).apiMode;
|
|
78
|
+
options.routerMode ??= parseCliArgs(['--router-mode', (await rl.question('路由 hash / history [hash]:')).trim() || 'hash']).routerMode;
|
|
79
|
+
if (options.preset !== 'minimal')
|
|
80
|
+
options.features ??= parseCliArgs(['--features', (await rl.question('可选能力 system,examples / none [system,examples]:')).trim() || 'system,examples']).features;
|
|
81
|
+
}
|
|
82
|
+
finally {
|
|
83
|
+
rl.close();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
const targetDir = resolve(options.target ?? 'lumal-admin');
|
|
87
|
+
const result = await createLumalAdminProject({ ...options, name: options.name ?? basename(targetDir), targetDir });
|
|
88
|
+
console.log(`已创建 ${result.preset} / ${result.apiMode} / ${result.routerMode} 项目:${result.targetDir}`);
|
|
89
|
+
console.log(`下一步:\n cd ${JSON.stringify(result.targetDir)}\n pnpm install\n pnpm dev`);
|
|
90
|
+
if (result.apiMode === 'http')
|
|
91
|
+
console.log('请先配置 .env.development 中的 VITE_API_BASE_URL,契约见 API-CONTRACT.md。');
|
|
17
92
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
name: basename(targetDir),
|
|
24
|
-
targetDir,
|
|
93
|
+
// npm/pnpm 的 node_modules 链接路径与模块真实路径可能不同。
|
|
94
|
+
if (process.argv[1] && import.meta.url === pathToFileURL(realpathSync(resolve(process.argv[1]))).href) {
|
|
95
|
+
main().catch((error) => {
|
|
96
|
+
console.error(`创建失败:${error instanceof Error ? error.message : String(error)}`);
|
|
97
|
+
process.exitCode = 1;
|
|
25
98
|
});
|
|
26
|
-
console.log(`已创建 Lumal Admin 项目:${result.targetDir}`);
|
|
27
|
-
console.log('下一步:');
|
|
28
|
-
console.log(` cd ${result.targetDir}`);
|
|
29
|
-
console.log(' pnpm install');
|
|
30
|
-
console.log(' pnpm dev');
|
|
31
99
|
}
|
|
32
|
-
main().catch((error) => {
|
|
33
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
34
|
-
console.error(`创建失败:${message}`);
|
|
35
|
-
process.exit(1);
|
|
36
|
-
});
|
|
37
100
|
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAC7C,OAAO,OAAO,MAAM,cAAc,CAAA;AAClC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/create.d.ts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
|
|
1
|
+
import type { CreateLumalAdminProjectOptions, CreateLumalAdminProjectResult } from './types.js';
|
|
2
|
+
export declare function createLumalAdminProject(input: CreateLumalAdminProjectOptions): Promise<CreateLumalAdminProjectResult>;
|
|
2
3
|
//# sourceMappingURL=create.d.ts.map
|
package/dist/create.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../src/create.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../src/create.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,8BAA8B,EAAE,6BAA6B,EAAE,MAAM,YAAY,CAAA;AAM/F,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,8BAA8B,GACpC,OAAO,CAAC,6BAA6B,CAAC,CAkFxC"}
|
package/dist/create.js
CHANGED
|
@@ -1,3 +1,86 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { lstat, mkdir, open, readdir, rmdir, unlink } from 'node:fs/promises';
|
|
2
|
+
import { dirname, join, parse, resolve } from 'node:path';
|
|
3
|
+
import { resolveOptions } from './presets.js';
|
|
4
|
+
import { composeTemplates } from './templates.js';
|
|
5
|
+
export async function createLumalAdminProject(input) {
|
|
6
|
+
const options = resolveOptions(input);
|
|
7
|
+
const targetDir = resolve(options.targetDir);
|
|
8
|
+
if (targetDir === parse(targetDir).root)
|
|
9
|
+
throw new Error('不能在文件系统根目录创建项目');
|
|
10
|
+
const stat = await lstat(targetDir).catch((error) => {
|
|
11
|
+
if (error.code !== 'ENOENT')
|
|
12
|
+
throw error;
|
|
13
|
+
return undefined;
|
|
14
|
+
});
|
|
15
|
+
if (stat?.isSymbolicLink() || (stat && !stat.isDirectory()))
|
|
16
|
+
throw new Error('目标必须是普通目录,不能是文件或符号链接');
|
|
17
|
+
if (stat && (await readdir(targetDir)).length)
|
|
18
|
+
throw new Error('目标目录不是空目录');
|
|
19
|
+
// 不允许经由祖先符号链接 / junction 将输出重定向到另一个位置。
|
|
20
|
+
for (let directory = dirname(targetDir); directory !== dirname(directory); directory = dirname(directory)) {
|
|
21
|
+
const parent = await lstat(directory).catch((error) => {
|
|
22
|
+
if (error.code !== 'ENOENT')
|
|
23
|
+
throw error;
|
|
24
|
+
return undefined;
|
|
25
|
+
});
|
|
26
|
+
if (parent?.isSymbolicLink())
|
|
27
|
+
throw new Error('目标祖先目录不能包含符号链接');
|
|
28
|
+
}
|
|
29
|
+
// 先读取、校验全部发布资源,再开始写入。回滚从不递归删除目标目录。
|
|
30
|
+
const files = await composeTemplates(options);
|
|
31
|
+
const ownedFiles = [];
|
|
32
|
+
const ownedDirectories = [];
|
|
33
|
+
async function ensureDirectory(directory) {
|
|
34
|
+
try {
|
|
35
|
+
await mkdir(directory);
|
|
36
|
+
ownedDirectories.push(directory);
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
const code = error.code;
|
|
40
|
+
if (code === 'ENOENT') {
|
|
41
|
+
await ensureDirectory(dirname(directory));
|
|
42
|
+
await ensureDirectory(directory);
|
|
43
|
+
}
|
|
44
|
+
else if (code === 'EEXIST') {
|
|
45
|
+
const existing = await lstat(directory);
|
|
46
|
+
if (!existing.isDirectory() || existing.isSymbolicLink())
|
|
47
|
+
throw new Error('写入路径必须是普通目录,不能包含符号链接');
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
throw error;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
try {
|
|
55
|
+
await ensureDirectory(targetDir);
|
|
56
|
+
for (const file of files) {
|
|
57
|
+
const filePath = join(targetDir, file.path);
|
|
58
|
+
await ensureDirectory(dirname(filePath));
|
|
59
|
+
const handle = await open(filePath, 'wx');
|
|
60
|
+
ownedFiles.push(filePath);
|
|
61
|
+
try {
|
|
62
|
+
await handle.writeFile(file.content, 'utf8');
|
|
63
|
+
}
|
|
64
|
+
finally {
|
|
65
|
+
await handle.close();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
const cleanupErrors = [];
|
|
71
|
+
for (const file of ownedFiles.reverse())
|
|
72
|
+
await unlink(file).catch(reason => cleanupErrors.push(reason));
|
|
73
|
+
for (const directory of ownedDirectories.reverse()) {
|
|
74
|
+
await rmdir(directory).catch((reason) => {
|
|
75
|
+
// 并发写入者的文件必须保留;只移除本次创建且仍为空的目录。
|
|
76
|
+
if (reason.code !== 'ENOTEMPTY' && reason.code !== 'ENOENT')
|
|
77
|
+
cleanupErrors.push(reason);
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
if (cleanupErrors.length)
|
|
81
|
+
throw new AggregateError([error, ...cleanupErrors], '创建失败,部分文件清理失败,请检查目标目录');
|
|
82
|
+
throw error;
|
|
83
|
+
}
|
|
84
|
+
return { ...options, targetDir, createdFiles: files.map(file => file.path) };
|
|
85
|
+
}
|
|
3
86
|
//# sourceMappingURL=create.js.map
|
package/dist/create.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.js","sourceRoot":"","sources":["../src/create.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"create.js","sourceRoot":"","sources":["../src/create.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { createLumalAdminProject, } from './create.js';
|
|
2
|
-
export type { CreateLumalAdminProjectOptions, CreateLumalAdminProjectResult, } from './
|
|
2
|
+
export type { AdminFeature, AdminPreset, ApiMode, CreateLumalAdminProjectOptions, CreateLumalAdminProjectResult, RouterMode, } from './types.js';
|
|
3
3
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,GACxB,MAAM,aAAa,CAAA;AACpB,YAAY,EACV,8BAA8B,EAC9B,6BAA6B,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,GACxB,MAAM,aAAa,CAAA;AACpB,YAAY,EACV,YAAY,EACZ,WAAW,EACX,OAAO,EACP,8BAA8B,EAC9B,6BAA6B,EAC7B,UAAU,GACX,MAAM,YAAY,CAAA"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { AdminFeature, CreateLumalAdminProjectOptions } from './types.js';
|
|
2
|
+
export declare const presets: readonly ["minimal", "standard", "vben-compatible"];
|
|
3
|
+
export declare const apiModes: readonly ["local", "http"];
|
|
4
|
+
export declare const routerModes: readonly ["hash", "history"];
|
|
5
|
+
export declare const features: readonly ["system", "examples"];
|
|
6
|
+
export declare function assertPackageName(name: string): void;
|
|
7
|
+
export declare function resolveOptions(options: CreateLumalAdminProjectOptions): {
|
|
8
|
+
preset: import("./types.js").AdminPreset;
|
|
9
|
+
apiMode: import("./types.js").ApiMode;
|
|
10
|
+
routerMode: import("./types.js").RouterMode;
|
|
11
|
+
features: AdminFeature[];
|
|
12
|
+
name: string;
|
|
13
|
+
targetDir: string;
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=presets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presets.d.ts","sourceRoot":"","sources":["../src/presets.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,8BAA8B,EAAE,MAAM,YAAY,CAAA;AAG9E,eAAO,MAAM,OAAO,qDAAsD,CAAA;AAC1E,eAAO,MAAM,QAAQ,4BAA6B,CAAA;AAClD,eAAO,MAAM,WAAW,8BAA+B,CAAA;AACvD,eAAO,MAAM,QAAQ,iCAAkC,CAAA;AAEvD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAOpD;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,8BAA8B;;;;;;;EAerE"}
|
package/dist/presets.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { builtinModules } from 'node:module';
|
|
2
|
+
export const presets = ['minimal', 'standard', 'vben-compatible'];
|
|
3
|
+
export const apiModes = ['local', 'http'];
|
|
4
|
+
export const routerModes = ['hash', 'history'];
|
|
5
|
+
export const features = ['system', 'examples'];
|
|
6
|
+
export function assertPackageName(name) {
|
|
7
|
+
// 新建 npm 包不接受前导连字符或 ~;scope 与包名均限制为安全的小写子集。
|
|
8
|
+
const part = '[a-z0-9][a-z0-9._-]*';
|
|
9
|
+
if (name.length > 214 || !new RegExp(`^(?:@${part}/)?${part}$`).test(name)
|
|
10
|
+
|| ['node_modules', 'favicon.ico', ...builtinModules].includes(name)) {
|
|
11
|
+
throw new Error(`非法 npm 项目名称:${name}`);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export function resolveOptions(options) {
|
|
15
|
+
assertPackageName(options.name);
|
|
16
|
+
const preset = options.preset ?? 'standard';
|
|
17
|
+
const apiMode = options.apiMode ?? 'local';
|
|
18
|
+
const routerMode = options.routerMode ?? 'hash';
|
|
19
|
+
const selected = [...new Set(options.features ?? (preset === 'minimal' ? [] : features))];
|
|
20
|
+
if (!presets.includes(preset) || !apiModes.includes(apiMode) || !routerModes.includes(routerMode))
|
|
21
|
+
throw new Error('预设、数据源或路由模式无效');
|
|
22
|
+
if (selected.some(feature => !features.includes(feature)))
|
|
23
|
+
throw new Error('可选能力仅支持 system、examples');
|
|
24
|
+
if (preset === 'minimal' && selected.length)
|
|
25
|
+
throw new Error('minimal 预设不包含业务模块,请选择 standard');
|
|
26
|
+
if (!options.targetDir?.trim())
|
|
27
|
+
throw new Error('目标目录不能为空');
|
|
28
|
+
return { ...options, preset, apiMode, routerMode, features: selected };
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=presets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presets.js","sourceRoot":"","sources":["../src/presets.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAE5C,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,SAAS,EAAE,UAAU,EAAE,iBAAiB,CAAU,CAAA;AAC1E,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,OAAO,EAAE,MAAM,CAAU,CAAA;AAClD,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,MAAM,EAAE,SAAS,CAAU,CAAA;AACvD,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,QAAQ,EAAE,UAAU,CAAU,CAAA;AAEvD,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,4CAA4C;IAC5C,MAAM,IAAI,GAAG,sBAAsB,CAAA;IACnC,IAAI,IAAI,CAAC,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,MAAM,CAAC,QAAQ,IAAI,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;WACrE,CAAC,cAAc,EAAE,aAAa,EAAE,GAAG,cAAc,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACvE,MAAM,IAAI,KAAK,CAAC,eAAe,IAAI,EAAE,CAAC,CAAA;IACxC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,OAAuC;IACpE,iBAAiB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IAC/B,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,UAAU,CAAA;IAC3C,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,OAAO,CAAA;IAC1C,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,MAAM,CAAA;IAC/C,MAAM,QAAQ,GAAmB,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,QAAQ,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAA;IACzG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,UAAU,CAAC;QAC/F,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAA;IAClC,IAAI,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACvD,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAA;IAC5C,IAAI,MAAM,KAAK,SAAS,IAAI,QAAQ,CAAC,MAAM;QACzC,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAA;IACnD,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE;QAC5B,MAAM,IAAI,KAAK,CAAC,UAAU,CAAC,CAAA;IAC7B,OAAO,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAA;AACxE,CAAC"}
|
package/dist/scaffold.d.ts
CHANGED
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
3
|
-
name: string;
|
|
4
|
-
targetDir: string;
|
|
5
|
-
}
|
|
6
|
-
export interface CreateLumalAdminProjectResult {
|
|
7
|
-
targetDir: string;
|
|
8
|
-
createdFiles: string[];
|
|
9
|
-
}
|
|
10
|
-
/***********************公开 API*********************/
|
|
11
|
-
export declare function createLumalAdminProject(options: CreateLumalAdminProjectOptions): Promise<CreateLumalAdminProjectResult>;
|
|
1
|
+
export { createLumalAdminProject } from './create.js';
|
|
2
|
+
export type { CreateLumalAdminProjectOptions, CreateLumalAdminProjectResult } from './types.js';
|
|
12
3
|
//# sourceMappingURL=scaffold.d.ts.map
|
package/dist/scaffold.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../src/scaffold.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../src/scaffold.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AACrD,YAAY,EAAE,8BAA8B,EAAE,6BAA6B,EAAE,MAAM,YAAY,CAAA"}
|