@farris/cli 2.2.6 → 2.3.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/lib/commands/add-app.js +6 -0
- package/lib/commands/add-app.js.map +1 -0
- package/lib/commands/add-lib.js +6 -0
- package/lib/commands/add-lib.js.map +1 -0
- package/lib/commands/add-project.js +194 -0
- package/lib/commands/add-project.js.map +1 -0
- package/lib/commands/build-components.js +8 -1
- package/lib/commands/build-components.js.map +1 -1
- package/lib/commands/build-lib.js +5 -0
- package/lib/commands/build-lib.js.map +1 -1
- package/lib/commands/build.js +7 -2
- package/lib/commands/build.js.map +1 -1
- package/lib/commands/create-app-options.js +0 -2
- package/lib/commands/create-app-options.js.map +1 -1
- package/lib/commands/create-app.js +6 -1
- package/lib/commands/create-app.js.map +1 -1
- package/lib/commands/create-options.js +3 -0
- package/lib/commands/create-options.js.map +1 -1
- package/lib/commands/create.js +95 -42
- package/lib/commands/create.js.map +1 -1
- package/lib/commands/generate/common.js +13 -12
- package/lib/commands/generate/common.js.map +1 -1
- package/lib/commands/workspace/add-app.js +10 -175
- package/lib/commands/workspace/add-app.js.map +1 -1
- package/lib/commands/workspace/create.js +29 -346
- package/lib/commands/workspace/create.js.map +1 -1
- package/lib/common/agents-doc.js +34 -0
- package/lib/common/agents-doc.js.map +1 -0
- package/lib/common/generate-app.js +48 -24
- package/lib/common/generate-app.js.map +1 -1
- package/lib/common/output.js +72 -2
- package/lib/common/output.js.map +1 -1
- package/lib/common/project-layout.js +143 -0
- package/lib/common/project-layout.js.map +1 -0
- package/lib/common/safety.js +4 -2
- package/lib/common/safety.js.map +1 -1
- package/lib/common/template-manifest.js +2 -4
- package/lib/common/template-manifest.js.map +1 -1
- package/lib/common/verifier.js +143 -99
- package/lib/common/verifier.js.map +1 -1
- package/lib/common/workspace-contract.js +86 -0
- package/lib/common/workspace-contract.js.map +1 -0
- package/lib/index.js +31 -2
- package/lib/index.js.map +1 -1
- package/lib/plugins/create-app-package-json.js +24 -0
- package/lib/plugins/create-app-package-json.js.map +1 -0
- package/package.json +53 -52
- package/templates/create/.gitignore.tpl +12 -0
- package/templates/create/AGENTS.md +62 -0
- package/templates/create/CLAUDE.md +1 -0
- package/templates/create/README.md +14 -1
- package/templates/create/package.json +11 -3
- package/templates/create/pnpm-workspace.yaml +2 -1
- package/templates/lib/.eslintrc.cjs +15 -0
- package/templates/lib/.gitignore.tpl +3 -0
- package/templates/lib/.prettierrc.json +8 -0
- package/templates/lib/index.html +1 -1
- package/templates/lib/package.json +38 -3
- package/templates/lib/{components → test/components}/button/button.spec.ts +3 -2
- package/templates/lib/test/components/button/button.spec.tsx +11 -0
- package/templates/lib/tsconfig.json +5 -1
- package/templates/lib/vitest.config.ts +1 -1
- package/templates/mobile/.gitignore.tpl +31 -0
- package/templates/mobile/.gitlab-ci.yml +3 -9
- package/templates/mobile/index.html +1 -1
- package/templates/mobile/package.json +14 -10
- package/templates/mobile/src/main.ts +5 -4
- package/templates/mobile/src/router/index.ts +17 -17
- package/templates/mobile/test/src/components/TheButton.spec.ts +15 -0
- package/templates/mobile/test/src/components/TheButton.spec.tsx +15 -0
- package/templates/mobile/tsconfig.json +3 -2
- package/templates/mobile/vitest.config.ts +2 -1
- package/templates/web/.gitignore.tpl +31 -0
- package/templates/web/.gitlab-ci.yml +3 -9
- package/templates/web/index.html +1 -1
- package/templates/web/package.json +14 -10
- package/templates/web/src/locales/index.ts +5 -0
- package/templates/web/src/locales/zh-CN.json +1 -0
- package/templates/web/src/main.ts +5 -2
- package/templates/web/src/router/index.ts +17 -17
- package/templates/web/src/styles/index.css +0 -0
- package/templates/web/src/styles/index.scss +0 -0
- package/templates/web/test/src/components/TheButton.spec.ts +15 -0
- package/templates/web/test/src/components/TheButton.spec.tsx +15 -0
- package/templates/web/tsconfig.json +3 -2
- package/templates/web/vitest.config.ts +2 -1
- package/lib/common/project-package-name.js +0 -5
- package/lib/common/project-package-name.js.map +0 -1
- package/templates/mobile/.changeset/README.md +0 -4
- package/templates/mobile/.changeset/config.json +0 -11
- package/templates/mobile/project.json +0 -4
- package/templates/mobile/src/components/TheButton.spec.ts +0 -8
- package/templates/web/.changeset/README.md +0 -4
- package/templates/web/.changeset/config.json +0 -11
- package/templates/web/project.json +0 -4
- package/templates/web/src/components/TheButton.spec.ts +0 -8
- package/templates/workspace/app/farris.config.mjs +0 -13
- package/templates/workspace/app/index.html +0 -12
- package/templates/workspace/app/package.json +0 -22
- package/templates/workspace/app/src/App.tsx +0 -11
- package/templates/workspace/app/src/main.ts +0 -12
- package/templates/workspace/app/src/router/index.ts +0 -16
- package/templates/workspace/app/src/views/home/composables/use-home.ts +0 -7
- package/templates/workspace/app/src/views/home/home.component.tsx +0 -15
- package/templates/workspace/app/src/views/home/index.ts +0 -4
- package/templates/workspace/app/tsconfig.json +0 -21
- package/templates/workspace/root/README.md +0 -28
- package/templates/workspace/root/package.json +0 -13
- package/templates/workspace/root/pnpm-workspace.yaml +0 -12
- /package/templates/{workspace/app → mobile}/src/locales/index.ts +0 -0
- /package/templates/{workspace/app → mobile}/src/locales/zh-CN.json +0 -0
- /package/templates/{workspace/app → mobile}/src/styles/index.css +0 -0
- /package/templates/{workspace/app → mobile}/src/styles/index.scss +0 -0
package/lib/commands/create.js
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, readFileSync, rmSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
2
|
-
import { join, resolve } from 'node:path';
|
|
2
|
+
import { basename, isAbsolute, join, relative, resolve } from 'node:path';
|
|
3
3
|
import inquirer from 'inquirer';
|
|
4
|
-
import {
|
|
4
|
+
import { DEFAULT_CATALOG_VERSIONS, ExitCode, getDirname } from '../common/constant.js';
|
|
5
5
|
import { applyCatalogDeps } from '../common/apply-catalog-deps.js';
|
|
6
|
+
import { checkPlannedConflicts, inspectTarget } from '../common/safety.js';
|
|
7
|
+
import { collectTemplateOutputPaths, renderTemplateDir } from '../common/template-renderer.js';
|
|
8
|
+
import { CreateAppError } from '../common/create-app-target.js';
|
|
6
9
|
import { generateApp } from '../common/generate-app.js';
|
|
7
|
-
import { fail,
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
+
import { fail, printNextSteps, printSuccess, sendJson, setJsonMode } from '../common/output.js';
|
|
11
|
+
import { PROJECT_CONTAINERS, containerFor, deriveAppDir } from '../common/project-layout.js';
|
|
12
|
+
import { renderCommandTable, renderProjectList } from '../common/workspace-contract.js';
|
|
13
|
+
import { ALLOWED_TYPES, DEFAULT_LIB_FORMATS, resolvePackageName } from './create-app-options.js';
|
|
10
14
|
export { parseCreateArgv } from './create-options.js';
|
|
11
15
|
const DEFAULT_WORKSPACE = 'my-workspace';
|
|
12
16
|
const DEFAULT_APP = 'app';
|
|
@@ -31,8 +35,12 @@ function assertAppName(appName) {
|
|
|
31
35
|
if (!trimmed || trimmed === '.' || trimmed === '..') {
|
|
32
36
|
throw new CreateAppError('应用名称不能为空或为 . / ..');
|
|
33
37
|
}
|
|
34
|
-
if (trimmed.includes('
|
|
35
|
-
throw new CreateAppError(
|
|
38
|
+
if (trimmed.includes('\0') || trimmed.includes('\\')) {
|
|
39
|
+
throw new CreateAppError(`应用名称必须是单段目录名或带 scope 的包名: ${appName}`);
|
|
40
|
+
}
|
|
41
|
+
// 允许 @scope/name(包名保留 scope,目录名由 deriveAppDir 推导),其余多段路径一律拒绝
|
|
42
|
+
if (trimmed.includes('/') && !/^@[^/]+\/[^/]+$/.test(trimmed)) {
|
|
43
|
+
throw new CreateAppError(`应用名称必须是单段目录名或带 scope 的包名: ${appName}`);
|
|
36
44
|
}
|
|
37
45
|
}
|
|
38
46
|
function assertProjectType(type) {
|
|
@@ -41,36 +49,38 @@ function assertProjectType(type) {
|
|
|
41
49
|
}
|
|
42
50
|
return type;
|
|
43
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* create 的目标路径:允许 `.`(就地生成,见设计文档 §9.2),仍禁止逃出 cwd。
|
|
54
|
+
*/
|
|
55
|
+
function resolveCreateTarget(target, cwd = process.cwd()) {
|
|
56
|
+
const trimmed = (target ?? '').trim();
|
|
57
|
+
if (trimmed.includes('\0')) {
|
|
58
|
+
throw new CreateAppError('目标路径包含非法字符');
|
|
59
|
+
}
|
|
60
|
+
const resolved = resolve(cwd, trimmed);
|
|
61
|
+
const rel = relative(cwd, resolved);
|
|
62
|
+
if (rel.startsWith('..') || isAbsolute(rel)) {
|
|
63
|
+
throw new CreateAppError(`目标目录必须位于当前工作目录内: ${target}`);
|
|
64
|
+
}
|
|
65
|
+
return resolved;
|
|
66
|
+
}
|
|
44
67
|
function rootTemplateVariables(createApp, appRel, pkgType = 'app') {
|
|
45
68
|
if (createApp && appRel) {
|
|
46
69
|
const artifactDir = pkgType === 'lib' ? `${appRel}/lib` : `${appRel}/dist`;
|
|
47
|
-
const publishSteps = pkgType === 'lib'
|
|
48
|
-
? [' - cd dist', ' - npm publish']
|
|
49
|
-
: [
|
|
50
|
-
` - cp ${appRel}/project.json dist/package.json`,
|
|
51
|
-
' - cd dist',
|
|
52
|
-
' - npm publish'
|
|
53
|
-
];
|
|
54
70
|
return {
|
|
55
|
-
rootDevScript: `pnpm --filter ./${appRel} run dev`,
|
|
56
|
-
rootBuildScript: `pnpm --filter ./${appRel} run build`,
|
|
57
|
-
rootTestScript: `pnpm --filter ./${appRel} run test`,
|
|
58
71
|
ciBuildSteps: [
|
|
59
72
|
` - pnpm --filter ./${appRel} run build`,
|
|
60
73
|
' - mkdir -p dist',
|
|
61
74
|
` - cp -r ${artifactDir}/. dist/`
|
|
62
75
|
].join('\n'),
|
|
63
|
-
ciPublishSteps:
|
|
64
|
-
readmeBody: `pnpm workspace
|
|
76
|
+
ciPublishSteps: [' - cd dist', ' - npm publish'].join('\n'),
|
|
77
|
+
readmeBody: `pnpm workspace,包含一个 Farris ${pkgType}(\`${appRel}\`)。`
|
|
65
78
|
};
|
|
66
79
|
}
|
|
67
80
|
return {
|
|
68
|
-
rootDevScript: 'pnpm --recursive --if-present run dev',
|
|
69
|
-
rootBuildScript: 'pnpm --recursive --if-present run build',
|
|
70
|
-
rootTestScript: 'pnpm --recursive --if-present run test',
|
|
71
81
|
ciBuildSteps: '',
|
|
72
82
|
ciPublishSteps: ' - echo "no app to publish"',
|
|
73
|
-
readmeBody:
|
|
83
|
+
readmeBody: `pnpm workspace,可在 \`${PROJECT_CONTAINERS.app}\` / \`${PROJECT_CONTAINERS.lib}\` 下添加工程。`
|
|
74
84
|
};
|
|
75
85
|
}
|
|
76
86
|
export async function create(nameArg, options = {}) {
|
|
@@ -134,17 +144,45 @@ export async function create(nameArg, options = {}) {
|
|
|
134
144
|
if (options.noApp) {
|
|
135
145
|
createApp = false;
|
|
136
146
|
}
|
|
137
|
-
assertTargetDirectoryFree(name);
|
|
138
147
|
const cwd = process.cwd();
|
|
139
|
-
const
|
|
148
|
+
const targetArg = name;
|
|
149
|
+
const targetPath = resolveCreateTarget(name, cwd);
|
|
150
|
+
const workspaceTitle = targetArg === '.' ? basename(targetPath) : targetArg;
|
|
151
|
+
const inspect = inspectTarget(targetPath);
|
|
152
|
+
if (!inspect.canCreate) {
|
|
153
|
+
throw new CreateAppError(`目标目录不能用于创建 workspace,状态: ${inspect.status}${inspect.conflicts.length > 0 ? `,冲突项: ${inspect.conflicts.join(', ')}` : ''}`, ExitCode.TARGET_CONFLICT);
|
|
154
|
+
}
|
|
140
155
|
const created = !existsSync(targetPath);
|
|
141
156
|
let appPackageName;
|
|
157
|
+
let appDir;
|
|
142
158
|
let appRel;
|
|
143
159
|
if (createApp) {
|
|
144
160
|
assertAppName(appName);
|
|
145
161
|
appPackageName = resolvePackageName(appName);
|
|
146
162
|
assertAppName(appPackageName);
|
|
147
|
-
|
|
163
|
+
appDir = deriveAppDir(appPackageName);
|
|
164
|
+
if (!appDir || !/^[a-z0-9-_]+$/.test(appDir)) {
|
|
165
|
+
throw new CreateAppError(`无法从工程名 "${appPackageName}" 推导出合法的子目录名`);
|
|
166
|
+
}
|
|
167
|
+
appRel = `${containerFor(pkgType)}/${appDir}`;
|
|
168
|
+
}
|
|
169
|
+
const plannedProjects = appRel && appDir ? [{ type: pkgType, dir: appRel, name: appDir }] : [];
|
|
170
|
+
// 写入前冲突预检(设计文档 §9.1)。create 的子工程落在全新容器内,因此只需预检根模板。
|
|
171
|
+
const conflicts = checkPlannedConflicts(targetPath, collectTemplateOutputPaths(createTemplateDir()));
|
|
172
|
+
if (conflicts.length > 0 && !options.force) {
|
|
173
|
+
const shouldOverwrite = !isJson &&
|
|
174
|
+
!skipPrompt &&
|
|
175
|
+
(await inquirer.createPromptModule()([
|
|
176
|
+
{
|
|
177
|
+
type: 'confirm',
|
|
178
|
+
name: 'overwrite',
|
|
179
|
+
message: `以下 ${conflicts.length} 个文件已存在,是否覆盖?\n${conflicts.join('\n')}`,
|
|
180
|
+
default: false
|
|
181
|
+
}
|
|
182
|
+
])).overwrite;
|
|
183
|
+
if (!shouldOverwrite) {
|
|
184
|
+
throw new CreateAppError(`目标目录包含将被模板写入的文件: ${conflicts.join(', ')}。请交互确认,或显式传入 --force 覆盖。`, ExitCode.TARGET_CONFLICT);
|
|
185
|
+
}
|
|
148
186
|
}
|
|
149
187
|
try {
|
|
150
188
|
const rootRender = renderTemplateDir({
|
|
@@ -152,23 +190,38 @@ export async function create(nameArg, options = {}) {
|
|
|
152
190
|
targetDir: targetPath,
|
|
153
191
|
variables: {
|
|
154
192
|
...catalogVariables(),
|
|
155
|
-
|
|
156
|
-
|
|
193
|
+
...rootTemplateVariables(createApp, appRel, pkgType),
|
|
194
|
+
appContainer: PROJECT_CONTAINERS.app,
|
|
195
|
+
libContainer: PROJECT_CONTAINERS.lib,
|
|
196
|
+
commandTable: renderCommandTable(),
|
|
197
|
+
projectList: renderProjectList(plannedProjects),
|
|
198
|
+
title: workspaceTitle
|
|
157
199
|
}
|
|
158
200
|
});
|
|
159
201
|
if (rootRender.unreplacedPlaceholders.length > 0) {
|
|
160
202
|
throw new Error(`根模板未替换: ${rootRender.unreplacedPlaceholders.map((p) => p.placeholder).join(', ')}`);
|
|
161
203
|
}
|
|
204
|
+
// 两个容器目录必须同时存在(pnpm-workspace.yaml 的 glob 与 verifier 都要求);
|
|
205
|
+
// 空容器放 .gitkeep 使其可见且可提交(设计文档 §4.4)。
|
|
206
|
+
for (const container of [PROJECT_CONTAINERS.app, PROJECT_CONTAINERS.lib]) {
|
|
207
|
+
const containerDir = join(targetPath, container);
|
|
208
|
+
mkdirSync(containerDir, { recursive: true });
|
|
209
|
+
if (!appRel || !appRel.startsWith(`${container}/`)) {
|
|
210
|
+
writeFileSync(join(containerDir, '.gitkeep'), '');
|
|
211
|
+
}
|
|
212
|
+
}
|
|
162
213
|
if (createApp && appRel && appPackageName) {
|
|
163
214
|
generateApp({
|
|
164
|
-
name: join(
|
|
215
|
+
name: join(targetPath, appRel).replace(/\\/g, '/'),
|
|
165
216
|
packageName: appPackageName,
|
|
217
|
+
title: workspaceTitle,
|
|
166
218
|
type: pkgType,
|
|
167
219
|
...(pkgType === 'lib'
|
|
168
220
|
? { formats: [...DEFAULT_LIB_FORMATS] }
|
|
169
|
-
: { platform: 'web', format: 'es' }),
|
|
221
|
+
: { platform: options.platform ?? 'web', format: options.format ?? 'es', style: options.style ?? 'css' }),
|
|
170
222
|
hints: false
|
|
171
223
|
});
|
|
224
|
+
// 根目录只保留一份 .gitlab-ci.yml
|
|
172
225
|
const appGitlab = join(targetPath, appRel, '.gitlab-ci.yml');
|
|
173
226
|
if (existsSync(appGitlab)) {
|
|
174
227
|
unlinkSync(appGitlab);
|
|
@@ -178,9 +231,6 @@ export async function create(nameArg, options = {}) {
|
|
|
178
231
|
applyCatalogDeps(appPkg);
|
|
179
232
|
writeFileSync(appPkgPath, JSON.stringify(appPkg, null, 2) + '\n');
|
|
180
233
|
}
|
|
181
|
-
else {
|
|
182
|
-
mkdirSync(join(targetPath, 'packages'), { recursive: true });
|
|
183
|
-
}
|
|
184
234
|
if (options.install) {
|
|
185
235
|
const { runPnpmInstall } = await import('./workspace/create.js');
|
|
186
236
|
const result = await runPnpmInstall(targetPath, isJson);
|
|
@@ -188,23 +238,26 @@ export async function create(nameArg, options = {}) {
|
|
|
188
238
|
throw new CreateAppError(result.error || 'pnpm install 失败');
|
|
189
239
|
}
|
|
190
240
|
}
|
|
191
|
-
if (
|
|
192
|
-
logInfo(`cd ${name}`);
|
|
193
|
-
logInfo('pnpm install');
|
|
194
|
-
if (createApp) {
|
|
195
|
-
logInfo('pnpm dev');
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
else {
|
|
241
|
+
if (isJson) {
|
|
199
242
|
sendJson({
|
|
200
243
|
command: 'create',
|
|
201
244
|
ok: true,
|
|
202
|
-
name,
|
|
245
|
+
name: workspaceTitle,
|
|
203
246
|
createdApp: createApp,
|
|
204
247
|
...(createApp ? { packageName: appPackageName, appDir: appRel, type: pkgType } : {}),
|
|
205
248
|
target: targetPath
|
|
206
249
|
});
|
|
207
250
|
}
|
|
251
|
+
else {
|
|
252
|
+
printSuccess(`工作空间已创建 ${targetPath}`);
|
|
253
|
+
printNextSteps({
|
|
254
|
+
targetArg,
|
|
255
|
+
targetDir: targetPath,
|
|
256
|
+
cwd,
|
|
257
|
+
installed: !!options.install,
|
|
258
|
+
appPackageName
|
|
259
|
+
});
|
|
260
|
+
}
|
|
208
261
|
}
|
|
209
262
|
catch (inner) {
|
|
210
263
|
if (created && existsSync(targetPath)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.js","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACjG,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"create.js","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { existsSync,
|
|
1
|
+
import { existsSync, statSync, readFileSync } from 'node:fs';
|
|
2
2
|
import { resolve, join, dirname } from 'node:path';
|
|
3
3
|
import { fail } from '../../common/output.js';
|
|
4
4
|
import { ExitCode } from '../../common/constant.js';
|
|
5
|
+
import { findWorkspaceRoot, listProjects } from '../../common/project-layout.js';
|
|
5
6
|
export function toKebabCase(str) {
|
|
6
7
|
return str
|
|
7
8
|
.replace(/([a-z])([A-Z])/g, '$1-$2')
|
|
@@ -75,19 +76,19 @@ export function findAppContext(startDir = process.cwd()) {
|
|
|
75
76
|
}
|
|
76
77
|
current = parent;
|
|
77
78
|
}
|
|
78
|
-
// 检查是否在 workspace
|
|
79
|
-
const
|
|
80
|
-
if (
|
|
81
|
-
const
|
|
82
|
-
if (
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
return findAppContext(singleAppDir);
|
|
87
|
-
}
|
|
79
|
+
// 检查是否在 workspace 根目录执行:容器名与工程清单都来自单一数据源
|
|
80
|
+
const wsRoot = findWorkspaceRoot(startDir);
|
|
81
|
+
if (wsRoot) {
|
|
82
|
+
const projects = listProjects(wsRoot);
|
|
83
|
+
if (projects.length === 1) {
|
|
84
|
+
return findAppContext(join(wsRoot, projects[0].dir));
|
|
85
|
+
}
|
|
86
|
+
if (projects.length > 1) {
|
|
88
87
|
fail({
|
|
89
88
|
command: 'generate',
|
|
90
|
-
error: `当前处于 Workspace
|
|
89
|
+
error: `当前处于 Workspace 根目录,存在多个工程 (${projects
|
|
90
|
+
.map((project) => project.dir)
|
|
91
|
+
.join(', ')})。请先进入具体工程目录(如 cd ${projects[0].dir})后再执行 generate 命令。`,
|
|
91
92
|
exitCode: ExitCode.GENERAL_ERROR
|
|
92
93
|
});
|
|
93
94
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common.js","sourceRoot":"","sources":["../../../src/commands/generate/common.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"common.js","sourceRoot":"","sources":["../../../src/commands/generate/common.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,181 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
import { Transaction } from '../../common/transaction.js';
|
|
6
|
-
import { verifyWorkspace } from '../../common/verifier.js';
|
|
7
|
-
import { sendJson, logInfo, fail, setJsonMode, createSpinner } from '../../common/output.js';
|
|
8
|
-
import { deriveAppDir, validatePackageName } from './create.js';
|
|
1
|
+
import { addProject } from '../add-project.js';
|
|
2
|
+
import { findWorkspaceRoot } from '../../common/project-layout.js';
|
|
3
|
+
import { logWarn } from '../../common/output.js';
|
|
4
|
+
export { findWorkspaceRoot };
|
|
9
5
|
/**
|
|
10
|
-
*
|
|
6
|
+
* [已废弃] 请改用 `farris-cli add-app`。保留本命令只为兼容既有脚本。
|
|
11
7
|
*/
|
|
12
|
-
export function findWorkspaceRoot(startDir = process.cwd()) {
|
|
13
|
-
let current = resolve(startDir);
|
|
14
|
-
while (true) {
|
|
15
|
-
if (existsSync(join(current, 'pnpm-workspace.yaml')) && existsSync(join(current, 'package.json'))) {
|
|
16
|
-
return current;
|
|
17
|
-
}
|
|
18
|
-
const parent = dirname(current);
|
|
19
|
-
if (parent === current) {
|
|
20
|
-
break;
|
|
21
|
-
}
|
|
22
|
-
current = parent;
|
|
23
|
-
}
|
|
24
|
-
return null;
|
|
25
|
-
}
|
|
26
8
|
export async function addAppToWorkspace(name, options = {}) {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
if (
|
|
30
|
-
|
|
31
|
-
command: 'workspace.add-app',
|
|
32
|
-
error: '必须指定应用名称: farris-cli workspace add-app <name>',
|
|
33
|
-
exitCode: ExitCode.GENERAL_ERROR
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
if (!validatePackageName(name)) {
|
|
37
|
-
fail({
|
|
38
|
-
command: 'workspace.add-app',
|
|
39
|
-
error: `非法的应用包名: "${name}"`,
|
|
40
|
-
exitCode: ExitCode.GENERAL_ERROR
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
const wsRoot = findWorkspaceRoot(options.cwd || process.cwd());
|
|
44
|
-
if (!wsRoot) {
|
|
45
|
-
fail({
|
|
46
|
-
command: 'workspace.add-app',
|
|
47
|
-
error: '当前目录或上级目录未找到标准 pnpm workspace (缺少 pnpm-workspace.yaml)',
|
|
48
|
-
exitCode: ExitCode.GENERAL_ERROR
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
const appDir = deriveAppDir(name);
|
|
52
|
-
if (!appDir || !/^[a-z0-9-_]+$/.test(appDir)) {
|
|
53
|
-
fail({
|
|
54
|
-
command: 'workspace.add-app',
|
|
55
|
-
error: `无法从应用名 "${name}" 推导出合法的子目录名`,
|
|
56
|
-
exitCode: ExitCode.GENERAL_ERROR
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
const title = options.title || name;
|
|
60
|
-
const router = options.router ?? false;
|
|
61
|
-
const routerMode = options.routerMode || 'hash';
|
|
62
|
-
const format = options.format || 'es';
|
|
63
|
-
const style = options.style || 'css';
|
|
64
|
-
const appTargetDir = join(wsRoot, 'packages', appDir);
|
|
65
|
-
if (existsSync(appTargetDir)) {
|
|
66
|
-
fail({
|
|
67
|
-
command: 'workspace.add-app',
|
|
68
|
-
error: `子应用目录已存在: packages/${appDir}`,
|
|
69
|
-
exitCode: ExitCode.TARGET_CONFLICT
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
const templatesBase = resolve(getDirname(import.meta.url), '../../../templates/workspace');
|
|
73
|
-
const appTemplateDir = join(templatesBase, 'app');
|
|
74
|
-
const transaction = new Transaction();
|
|
75
|
-
const spinner = createSpinner(`正在向 Workspace 添加子应用 ${name}...`);
|
|
76
|
-
spinner.start();
|
|
77
|
-
try {
|
|
78
|
-
mkdirSync(appTargetDir, { recursive: true });
|
|
79
|
-
transaction.recordCreatedDir(appTargetDir);
|
|
80
|
-
const routerDependency = router ? ',\n "vue-router": "catalog:"' : '';
|
|
81
|
-
const sassDevDependency = style === 'scss' ? ',\n "sass": "catalog:"' : '';
|
|
82
|
-
let styleImport = '';
|
|
83
|
-
if (style === 'css') {
|
|
84
|
-
styleImport = "\nimport './styles/index.css';";
|
|
85
|
-
}
|
|
86
|
-
else if (style === 'scss') {
|
|
87
|
-
styleImport = "\nimport './styles/index.scss';";
|
|
88
|
-
}
|
|
89
|
-
const routerImport = router ? "\nimport router from './router';" : '';
|
|
90
|
-
const routerUse = router ? '\napp.use(router);' : '';
|
|
91
|
-
const i18nImport = '';
|
|
92
|
-
const i18nUse = '';
|
|
93
|
-
const appRouterImport = router ? "\nimport { RouterView } from 'vue-router';" : '';
|
|
94
|
-
const appTemplateBody = router
|
|
95
|
-
? ' <RouterView />'
|
|
96
|
-
: ` <h1>${title}</h1>`;
|
|
97
|
-
const appVariables = {
|
|
98
|
-
appName: name,
|
|
99
|
-
title,
|
|
100
|
-
appDir,
|
|
101
|
-
base: '/',
|
|
102
|
-
routerMode: router ? routerMode : 'none',
|
|
103
|
-
format,
|
|
104
|
-
routerDependency,
|
|
105
|
-
sassDevDependency,
|
|
106
|
-
styleImport,
|
|
107
|
-
routerImport,
|
|
108
|
-
routerUse,
|
|
109
|
-
i18nImport,
|
|
110
|
-
i18nUse,
|
|
111
|
-
appRouterImport,
|
|
112
|
-
appTemplateBody,
|
|
113
|
-
routerHistoryFunction: routerMode === 'history' ? 'createWebHistory' : 'createWebHashHistory',
|
|
114
|
-
routerHistoryCall: routerMode === 'history'
|
|
115
|
-
? 'createWebHistory(import.meta.env.BASE_URL)'
|
|
116
|
-
: 'createWebHashHistory()'
|
|
117
|
-
};
|
|
118
|
-
const appFilter = (relPath) => {
|
|
119
|
-
const normalized = relPath.replace(/\\/g, '/');
|
|
120
|
-
if (style === 'none' && normalized.startsWith('src/styles')) {
|
|
121
|
-
return false;
|
|
122
|
-
}
|
|
123
|
-
if (style === 'css' && (normalized === 'src/styles/index.scss' || normalized === 'src/styles/index.scss.tpl')) {
|
|
124
|
-
return false;
|
|
125
|
-
}
|
|
126
|
-
if (style === 'scss' && (normalized === 'src/styles/index.css' || normalized === 'src/styles/index.css.tpl')) {
|
|
127
|
-
return false;
|
|
128
|
-
}
|
|
129
|
-
if (!router && (normalized.startsWith('src/router') || normalized.startsWith('src/views'))) {
|
|
130
|
-
return false;
|
|
131
|
-
}
|
|
132
|
-
return true;
|
|
133
|
-
};
|
|
134
|
-
const appRender = renderTemplateDir({
|
|
135
|
-
sourceDir: appTemplateDir,
|
|
136
|
-
targetDir: appTargetDir,
|
|
137
|
-
variables: appVariables,
|
|
138
|
-
skipExisting: false,
|
|
139
|
-
filter: appFilter
|
|
140
|
-
});
|
|
141
|
-
if (appRender.unreplacedPlaceholders.length > 0) {
|
|
142
|
-
throw new Error(`子应用渲染出现未替换占位符: ${appRender.unreplacedPlaceholders.map((p) => `${p.file} (${p.placeholder})`).join(', ')}`);
|
|
143
|
-
}
|
|
144
|
-
appRender.filesCreated.forEach((f) => transaction.prepareWrite(f));
|
|
145
|
-
// 执行 verify
|
|
146
|
-
const verifyResult = verifyWorkspace(wsRoot);
|
|
147
|
-
if (!verifyResult.ok) {
|
|
148
|
-
throw new Error(`Workspace 校验失败: ${verifyResult.errors.join('; ')}`);
|
|
149
|
-
}
|
|
150
|
-
transaction.commit();
|
|
151
|
-
spinner.succeed(`子应用 ${name} 添加成功!`);
|
|
152
|
-
if (isJson) {
|
|
153
|
-
sendJson({
|
|
154
|
-
command: 'workspace.add-app',
|
|
155
|
-
ok: true,
|
|
156
|
-
workspaceRoot: wsRoot,
|
|
157
|
-
appName: name,
|
|
158
|
-
appDir,
|
|
159
|
-
title,
|
|
160
|
-
router,
|
|
161
|
-
format,
|
|
162
|
-
style,
|
|
163
|
-
filesCreated: appRender.filesCreated
|
|
164
|
-
});
|
|
165
|
-
return;
|
|
166
|
-
}
|
|
167
|
-
logInfo(`\n✨ 已在 packages/${appDir} 成功创建应用 ${name}`);
|
|
168
|
-
logInfo('\n启动该应用:');
|
|
169
|
-
logInfo(` pnpm --filter "${name}" dev\n`);
|
|
170
|
-
}
|
|
171
|
-
catch (err) {
|
|
172
|
-
spinner.fail('添加子应用失败,正在回滚...');
|
|
173
|
-
transaction.rollback();
|
|
174
|
-
fail({
|
|
175
|
-
command: 'workspace.add-app',
|
|
176
|
-
error: `添加应用失败: ${err.message}`,
|
|
177
|
-
exitCode: ExitCode.GENERAL_ERROR
|
|
178
|
-
});
|
|
9
|
+
logWarn('`farris-cli workspace add-app` 已废弃,请改用 `farris-cli add-app`。');
|
|
10
|
+
const { router, routerMode, ...rest } = options;
|
|
11
|
+
if (router !== undefined || routerMode !== undefined) {
|
|
12
|
+
logWarn('--router / --router-mode 已废弃:新 app 模板始终包含路由,参数被忽略。');
|
|
179
13
|
}
|
|
14
|
+
await addProject('app', name, rest);
|
|
180
15
|
}
|
|
181
16
|
//# sourceMappingURL=add-app.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add-app.js","sourceRoot":"","sources":["../../../src/commands/workspace/add-app.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"add-app.js","sourceRoot":"","sources":["../../../src/commands/workspace/add-app.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAA0B,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAEjD,OAAO,EAAE,iBAAiB,EAAE,CAAC;AAQ7B;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAAY,EAAE,UAAkC,EAAE;IACtF,OAAO,CAAC,8DAA8D,CAAC,CAAC;IAExE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC;IAChD,IAAI,MAAM,KAAK,SAAS,IAAI,UAAU,KAAK,SAAS,EAAE;QAClD,OAAO,CAAC,oDAAoD,CAAC,CAAC;KACjE;IAED,MAAM,UAAU,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AACxC,CAAC"}
|