moyan-mfw-cli 1.1.5 → 1.1.7

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/dist/index.cjs CHANGED
@@ -60,6 +60,15 @@ var fsSync = __toESM(require("fs"), 1);
60
60
  var path2 = __toESM(require("path"), 1);
61
61
  var import_node_url = require("url");
62
62
  var import_meta = {};
63
+ var _currentDir = path2.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
64
+ function getCliVersion() {
65
+ const pkgPathProd = path2.resolve(_currentDir, "../package.json");
66
+ const pkgPathDev = path2.resolve(_currentDir, "../../package.json");
67
+ const pkgPath = fsSync.existsSync(pkgPathProd) ? pkgPathProd : pkgPathDev;
68
+ const raw = fsSync.readFileSync(pkgPath, "utf-8");
69
+ const pkg = JSON.parse(raw);
70
+ return pkg.version;
71
+ }
63
72
  import_handlebars.default.registerHelper(
64
73
  "pascalCase",
65
74
  (str) => str.replace(/(^\w|-\w)/g, (c) => c.slice(-1).toUpperCase())
@@ -74,9 +83,8 @@ import_handlebars.default.registerHelper("pascalCaseUpper", (str) => {
74
83
  });
75
84
  import_handlebars.default.registerHelper("snakeCase", (str) => str.replace(/-/g, "_"));
76
85
  function getTemplateDir(type) {
77
- const currentDir = path2.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
78
- const distTemplate = path2.resolve(currentDir, `templates/${type}`);
79
- const srcTemplate = path2.resolve(currentDir, `../templates/${type}`);
86
+ const distTemplate = path2.resolve(_currentDir, `templates/${type}`);
87
+ const srcTemplate = path2.resolve(_currentDir, `../templates/${type}`);
80
88
  if (fsSync.existsSync(distTemplate)) return distTemplate;
81
89
  if (fsSync.existsSync(srcTemplate)) return srcTemplate;
82
90
  return distTemplate;
@@ -208,6 +216,7 @@ Use --force to overwrite.`));
208
216
  hasFrontend: answers.hasFrontend,
209
217
  hasShared: answers.hasShared,
210
218
  version: "0.1.0",
219
+ baseVersion: getCliVersion(),
211
220
  year: (/* @__PURE__ */ new Date()).getFullYear()
212
221
  };
213
222
  const templateDir = getTemplateDir("extension");
@@ -303,6 +312,7 @@ Use --force to overwrite.`));
303
312
  frontendPort: Number(answers.frontendPort),
304
313
  className,
305
314
  version: "0.1.0",
315
+ baseVersion: getCliVersion(),
306
316
  year: (/* @__PURE__ */ new Date()).getFullYear()
307
317
  };
308
318
  const templateDir = getTemplateDir("business");
@@ -336,7 +346,7 @@ ${import_chalk2.default.yellow("\u26A0 \u9996\u6B21\u5B89\u88C5\u8BF7\u4F7F\u752
336
346
 
337
347
  // src/index.ts
338
348
  var program = new import_commander3.Command();
339
- program.name("mfw").description("Moyan MFW Framework CLI").version("0.1.0");
349
+ program.name("mfw").description("Moyan MFW Framework CLI").version(getCliVersion());
340
350
  var createCmd = new import_commander3.Command("create").description("Create a new extension or resource");
341
351
  createCmd.addCommand(createCommand);
342
352
  createCmd.addCommand(createBusinessCommand);
package/dist/index.js CHANGED
@@ -36,6 +36,15 @@ import * as fs2 from "fs/promises";
36
36
  import * as fsSync from "fs";
37
37
  import * as path2 from "path";
38
38
  import { fileURLToPath } from "url";
39
+ var _currentDir = path2.dirname(fileURLToPath(import.meta.url));
40
+ function getCliVersion() {
41
+ const pkgPathProd = path2.resolve(_currentDir, "../package.json");
42
+ const pkgPathDev = path2.resolve(_currentDir, "../../package.json");
43
+ const pkgPath = fsSync.existsSync(pkgPathProd) ? pkgPathProd : pkgPathDev;
44
+ const raw = fsSync.readFileSync(pkgPath, "utf-8");
45
+ const pkg = JSON.parse(raw);
46
+ return pkg.version;
47
+ }
39
48
  Handlebars.registerHelper(
40
49
  "pascalCase",
41
50
  (str) => str.replace(/(^\w|-\w)/g, (c) => c.slice(-1).toUpperCase())
@@ -50,9 +59,8 @@ Handlebars.registerHelper("pascalCaseUpper", (str) => {
50
59
  });
51
60
  Handlebars.registerHelper("snakeCase", (str) => str.replace(/-/g, "_"));
52
61
  function getTemplateDir(type) {
53
- const currentDir = path2.dirname(fileURLToPath(import.meta.url));
54
- const distTemplate = path2.resolve(currentDir, `templates/${type}`);
55
- const srcTemplate = path2.resolve(currentDir, `../templates/${type}`);
62
+ const distTemplate = path2.resolve(_currentDir, `templates/${type}`);
63
+ const srcTemplate = path2.resolve(_currentDir, `../templates/${type}`);
56
64
  if (fsSync.existsSync(distTemplate)) return distTemplate;
57
65
  if (fsSync.existsSync(srcTemplate)) return srcTemplate;
58
66
  return distTemplate;
@@ -184,6 +192,7 @@ Use --force to overwrite.`));
184
192
  hasFrontend: answers.hasFrontend,
185
193
  hasShared: answers.hasShared,
186
194
  version: "0.1.0",
195
+ baseVersion: getCliVersion(),
187
196
  year: (/* @__PURE__ */ new Date()).getFullYear()
188
197
  };
189
198
  const templateDir = getTemplateDir("extension");
@@ -279,6 +288,7 @@ Use --force to overwrite.`));
279
288
  frontendPort: Number(answers.frontendPort),
280
289
  className,
281
290
  version: "0.1.0",
291
+ baseVersion: getCliVersion(),
282
292
  year: (/* @__PURE__ */ new Date()).getFullYear()
283
293
  };
284
294
  const templateDir = getTemplateDir("business");
@@ -312,7 +322,7 @@ ${chalk2.yellow("\u26A0 \u9996\u6B21\u5B89\u88C5\u8BF7\u4F7F\u7528 --no-frozen-l
312
322
 
313
323
  // src/index.ts
314
324
  var program = new Command3();
315
- program.name("mfw").description("Moyan MFW Framework CLI").version("0.1.0");
325
+ program.name("mfw").description("Moyan MFW Framework CLI").version(getCliVersion());
316
326
  var createCmd = new Command3("create").description("Create a new extension or resource");
317
327
  createCmd.addCommand(createCommand);
318
328
  createCmd.addCommand(createBusinessCommand);
@@ -28,8 +28,8 @@
28
28
  "reflect-metadata": "catalog:",
29
29
  "rxjs": "catalog:",
30
30
  "typeorm": "catalog:",
31
- "moyan-mfw-base": "^1.1.0",
32
- "moyan-mfw-extension-ad": "^1.1.0",
31
+ "moyan-mfw-base": "^{{baseVersion}}",
32
+ "moyan-mfw-extension-ad": "^{{baseVersion}}",
33
33
  "{{name}}-shared": "workspace:*"
34
34
  },
35
35
  "devDependencies": {
@@ -15,8 +15,8 @@
15
15
  "axios": "catalog:",
16
16
  "element-plus": "catalog:",
17
17
  "md-editor-v3": "catalog:",
18
- "moyan-mfw-base": "^1.1.0",
19
- "moyan-mfw-extension-ad": "^1.1.0",
18
+ "moyan-mfw-base": "^{{baseVersion}}",
19
+ "moyan-mfw-extension-ad": "^{{baseVersion}}",
20
20
  "pinia": "catalog:",
21
21
  "quill": "catalog:",
22
22
  "vue": "catalog:",
@@ -0,0 +1,93 @@
1
+ <template>
2
+ <div class="header-actions">
3
+ <el-space :size="2">
4
+ <!-- 主题切换 -->
5
+ <div class="action-icon-btn" data-testid="header-theme-btn" @click="toggleTheme">
6
+ <el-icon :size="18">
7
+ <component :is="isDark ? Sunny : Moon" />
8
+ </el-icon>
9
+ </div>
10
+
11
+ <!-- 全屏切换 -->
12
+ <div class="action-icon-btn" data-testid="header-fullscreen-btn" @click="toggleFullscreen">
13
+ <el-icon :size="18">
14
+ <component :is="isFullscreen ? ScaleToOriginal : FullScreen" />
15
+ </el-icon>
16
+ </div>
17
+
18
+ <!-- 布局设置 -->
19
+ <div class="action-icon-btn" data-testid="header-settings-btn" @click="openLayoutSettings">
20
+ <el-icon :size="18"><Setting /></el-icon>
21
+ </div>
22
+ </el-space>
23
+ </div>
24
+ </template>
25
+
26
+ <script setup lang="ts">
27
+ import { Setting, Moon, Sunny, FullScreen, ScaleToOriginal } from '@element-plus/icons-vue';
28
+ import { ref, onMounted, onUnmounted } from 'vue';
29
+
30
+ const isDark = ref(false);
31
+ const isFullscreen = ref(false);
32
+
33
+ const toggleTheme = () => {
34
+ isDark.value = !isDark.value;
35
+ document.documentElement.classList.toggle('dark', isDark.value);
36
+ };
37
+
38
+ const toggleFullscreen = async () => {
39
+ if (!document.fullscreenElement) {
40
+ await document.documentElement.requestFullscreen();
41
+ isFullscreen.value = true;
42
+ } else {
43
+ await document.exitFullscreen();
44
+ isFullscreen.value = false;
45
+ }
46
+ };
47
+
48
+ const openLayoutSettings = () => {
49
+ console.log('Open layout settings');
50
+ };
51
+
52
+ const handleKeydown = (e: KeyboardEvent) => {
53
+ if ((e.ctrlKey || e.metaKey) && e.key === 'k') {
54
+ e.preventDefault();
55
+ }
56
+ };
57
+
58
+ onMounted(() => {
59
+ document.addEventListener('keydown', handleKeydown);
60
+ });
61
+
62
+ onUnmounted(() => {
63
+ document.removeEventListener('keydown', handleKeydown);
64
+ });
65
+ </script>
66
+
67
+ <style scoped lang="scss">
68
+ .header-actions {
69
+ display: flex;
70
+ align-items: center;
71
+ }
72
+
73
+ .action-icon-btn {
74
+ display: flex;
75
+ align-items: center;
76
+ justify-content: center;
77
+ color: rgba(255, 255, 255, 0.85);
78
+ cursor: pointer;
79
+ transition: all 0.2s ease;
80
+ border-radius: 4px;
81
+ padding: 4px;
82
+ font-weight: 600;
83
+
84
+ &:hover {
85
+ background: rgba(255, 255, 255, 0.12);
86
+ color: #fff;
87
+ }
88
+
89
+ &:active {
90
+ background: rgba(255, 255, 255, 0.18);
91
+ }
92
+ }
93
+ </style>
@@ -0,0 +1 @@
1
+ export { default as HeaderCommonActions } from './components/HeaderCommonActions.vue';
@@ -0,0 +1,28 @@
1
+ /// <reference types="vite/client" />
2
+ import type { RouteRecordRaw } from 'vue-router'
3
+
4
+ declare module 'moyan-mfw-base/frontend' {
5
+ export function createBaseAdminApp(options: unknown): {
6
+ fetchPermissionValues(): Promise<unknown[]>
7
+ initPermissionCache(values: unknown[]): void
8
+ initPermissionValues(values: unknown[]): void
9
+ mount(selector: string): Promise<void>
10
+ }
11
+ export function registerPermissionValues(values: unknown[]): void
12
+ export function definePageConfig(config: unknown): unknown
13
+ export function buildRoutesFromConfigs(configs: unknown[], ctx?: unknown): RouteRecordRaw[]
14
+ export function createBusinessPageConfigFn(permPrefix: string): (page: unknown) => unknown
15
+ }
16
+
17
+ declare module 'moyan-mfw-base/frontend/style.css' {
18
+ const content: string
19
+ export default content
20
+ }
21
+
22
+ declare module 'moyan-mfw-extension-ad/frontend' {
23
+ export const adRoutes: RouteRecordRaw[]
24
+ }
25
+
26
+ declare module 'moyan-mfw-extension-ad/shared' {
27
+ export const AD_EXTENSION_PERMISSION_VALUES: bigint[]
28
+ }
@@ -1,10 +1,15 @@
1
- import { createBaseAdminApp } from 'moyan-mfw-base/frontend'
1
+ import { createBaseAdminApp, registerPermissionValues } from 'moyan-mfw-base/frontend'
2
+ import { HeaderCommonActions } from './components/Layout'
2
3
  import { businessRoutes } from './router'
4
+ import { adRoutes } from 'moyan-mfw-extension-ad/frontend'
5
+ import { AD_EXTENSION_PERMISSION_VALUES } from 'moyan-mfw-extension-ad/shared'
3
6
  import './permissions'
4
7
 
8
+ registerPermissionValues([...AD_EXTENSION_PERMISSION_VALUES])
9
+
5
10
  const admin = createBaseAdminApp({
6
11
  title: '{{displayName}}',
7
- routes: [...businessRoutes],
12
+ routes: [...businessRoutes, ...adRoutes],
8
13
  layout: {
9
14
  layoutMode: 'dual',
10
15
  showTabs: true,
@@ -16,6 +21,9 @@ const admin = createBaseAdminApp({
16
21
  brandTagline: '{{description}}',
17
22
  homePath: '/dashboard',
18
23
  },
24
+ layoutExtensions: {
25
+ headerCommon: HeaderCommonActions,
26
+ },
19
27
  })
20
28
 
21
29
  const values = await admin.fetchPermissionValues()
@@ -26,7 +26,7 @@
26
26
  },
27
27
  "dependencies": {
28
28
  "reflect-metadata": "catalog:",
29
- "moyan-mfw-base": "^1.0.0"
29
+ "moyan-mfw-base": "^{{baseVersion}}"
30
30
  },
31
31
  "devDependencies": {
32
32
  "typescript": "catalog:"
@@ -1 +1 @@
1
- {"name": "@internal/{{name}}-frontend", "version": "{{version}}", "type": "module", "main": "./src/index.ts", "exports": {".": {"types": "./src/index.d.ts", "import": "./src/index.mjs", "require": "./src/index.js"}}, "scripts": {"build": "vite build && vue-tsc --emitOnly", "typecheck": "vue-tsc --noEmit", "dev": "vite", "preview": "vite preview"}, "dependencies": {"moyan-mfw-base/frontend": "workspace:*", "@internal/{{name}}-shared": "workspace:*", "vue": "catalog:", "vue-router": "catalog:", "element-plus": "catalog:", "@element-plus/icons-vue": "catalog:"}, "devDependencies": {"@vitejs/plugin-vue": "catalog:", "@vitejs/plugin-vue-jsx": "catalog:", "vite": "catalog:", "vue-tsc": "catalog:", "typescript": "catalog:"}}
1
+ {"name": "@internal/{{name}}-frontend", "version": "{{version}}", "type": "module", "main": "./src/index.ts", "exports": {".": {"types": "./src/index.d.ts", "import": "./src/index.mjs", "require": "./src/index.js"}}, "scripts": {"build": "vite build && vue-tsc --emitOnly", "typecheck": "vue-tsc --noEmit", "dev": "vite", "preview": "vite preview", "verify-dist": "node ../../scripts/verify-dist.mjs"}, "dependencies": {"moyan-mfw-base/frontend": "workspace:*", "@internal/{{name}}-shared": "workspace:*", "vue": "catalog:", "vue-router": "catalog:", "element-plus": "catalog:", "@element-plus/icons-vue": "catalog:"}, "devDependencies": {"@vitejs/plugin-vue": "catalog:", "@vitejs/plugin-vue-jsx": "catalog:", "vite": "catalog:", "vue-tsc": "catalog:", "typescript": "catalog:"}}
@@ -1,13 +1,10 @@
1
1
  /**
2
2
  * @fileoverview {{displayName}}扩展包前端入口
3
+ * @description 从模块配置树构建路由,不依赖 import.meta.glob 扫描
3
4
  */
4
- import { buildExtensionRoutes } from 'moyan-mfw-base/frontend'
5
+ import { buildRoutesFromModuleTree } from 'moyan-mfw-base/frontend'
6
+ import {{pascalCase name}}ModuleConfig from './views/index'
5
7
 
6
- const allConfigs = import.meta.glob('./views/**/index.{ts,tsx}', {
7
- eager: true,
8
- import: 'default',
9
- })
10
-
11
- export const {{pascalCase name}}Routes = buildExtensionRoutes(allConfigs, '{{name}}', {
8
+ export const {{pascalCase name}}Routes = buildRoutesFromModuleTree({{pascalCase name}}ModuleConfig, '{{name}}', {
12
9
  namespaceName: '{{displayName}}',
13
10
  })
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @fileoverview {{displayName}}扩展包前端自启动入口
3
3
  */
4
- import 'moyan-mfw-base/frontend/styles/base-admin.scss'
4
+ import 'moyan-mfw-base/frontend/style.css'
5
5
  import { createExtensionFrontendApp } from 'moyan-mfw-base/frontend'
6
6
  import { {{pascalCase name}}Routes } from './index'
7
7
 
@@ -0,0 +1,15 @@
1
+ /**
2
+ * @fileoverview {{displayName}}模块配置
3
+ * @description 树形菜单分组,children 承载子页面配置。新增页面时在此处添加 import。
4
+ */
5
+ import { defineModuleConfig } from 'moyan-mfw-base/frontend'
6
+ import type { PageConfig } from 'moyan-mfw-base/frontend'
7
+
8
+ const config = defineModuleConfig({
9
+ type: 'module',
10
+ name: '{{displayName}}',
11
+ icon: 'Menu',
12
+ order: 50,
13
+ })
14
+
15
+ export default { ...config, children: [] as PageConfig<string>[] }
@@ -2,15 +2,17 @@ import { defineConfig } from 'vite';
2
2
  import vue from '@vitejs/plugin-vue';
3
3
  import vueJsx from '@vitejs/plugin-vue-jsx';
4
4
  import { resolve } from 'path';
5
+ import { fixVueDefaultImport } from 'moyan-mfw-base/frontend/vite-helpers';
5
6
 
6
7
  export default defineConfig({
7
8
  root: '.',
8
- plugins: [vue(), vueJsx()],
9
+ plugins: [vue(), vueJsx(), fixVueDefaultImport()],
9
10
  resolve: {
10
11
  alias: {
11
12
  '@': resolve(__dirname, 'src'),
12
13
  'moyan-mfw-base/frontend/styles': resolve(__dirname, '../../../../base/src/frontend/src/styles'),
13
14
  'moyan-mfw-base/frontend': resolve(__dirname, '../../../../base/src/frontend/src/index.ts'),
15
+ 'moyan-mfw-base/frontend/vite-helpers': resolve(__dirname, '../../../../base/src/frontend/src/vite-helpers.ts'),
14
16
  'moyan-mfw-base/shared': resolve(__dirname, '../../../../base/src/shared/src/index.ts'),
15
17
  'moyan-mfw-extension-{{name}}/shared': resolve(__dirname, '../shared/src/index.ts'),
16
18
  },
@@ -1 +1 @@
1
- {"name": "moyan-mfw-extension-{{name}}", "version": "{{version}}", "description": "{{description}}", "private": true, "type": "module", "exports": {"./backend": {"import": "./src/backend/dist/index.js", "require": "./src/backend/dist/index.js", "types": "./src/backend/dist/index.d.ts"}, "./backend/*": {"import": "./src/backend/dist/*.js", "require": "./src/backend/dist/*", "types": "./src/backend/dist/*.d.ts"}, "./frontend": {"import": "./src/frontend/dist/index.mjs", "require": "./src/frontend/dist/index.mjs", "types": "./src/frontend/dist/index.d.ts"}, "./frontend/*": {"import": "./src/frontend/dist/*", "require": "./src/frontend/dist/*", "types": "./src/frontend/dist/*.d.ts"}, "./shared": {"import": "./src/shared/dist/index.js", "require": "./src/shared/dist/index.js", "types": "./src/shared/dist/index.d.ts"}, "./shared/*": {"import": "./src/shared/dist/*", "require": "./src/shared/dist/*", "types": "./src/shared/dist/*.d.ts"}}, "typesVersions": {"*": {"*": ["./src/*/dist/*.d.ts", "./src/*/dist/index.d.ts"]}}, "scripts": {"build:shared": "pnpm --filter @internal/{{name}}-shared build", "build:backend": "pnpm --filter moyan-mfw-base run build:shared && pnpm --filter moyan-mfw-base run build:backend && pnpm --filter @internal/{{name}}-backend build", "build:frontend": "pnpm --filter @internal/{{name}}-frontend build", "build": "pnpm run build:shared && pnpm run build:backend && pnpm run build:frontend", "dev:backend": "pnpm --filter @internal/{{name}}-backend dev", "dev:frontend": "pnpm --filter @internal/{{name}}-frontend dev", "typecheck:shared": "pnpm --filter @internal/{{name}}-shared typecheck", "typecheck:backend": "pnpm --filter @internal/{{name}}-backend typecheck", "typecheck:frontend": "pnpm --filter @internal/{{name}}-frontend typecheck", "typecheck": "pnpm run typecheck:shared && pnpm run typecheck:backend && pnpm run typecheck:frontend"}, "devDependencies": {"@internal/{{name}}-backend": "workspace:*", "@internal/{{name}}-frontend": "workspace:*", "@internal/{{name}}-shared": "workspace:*", "moyan-mfw-base": "workspace:*", "typescript": "catalog:"}}
1
+ {"name": "moyan-mfw-extension-{{name}}", "version": "{{version}}", "description": "{{description}}", "private": true, "type": "module", "exports": {"./backend": {"import": "./src/backend/dist/index.js", "require": "./src/backend/dist/index.js", "types": "./src/backend/dist/index.d.ts"}, "./backend/*": {"import": "./src/backend/dist/*.js", "require": "./src/backend/dist/*", "types": "./src/backend/dist/*.d.ts"}, "./frontend": {"import": "./src/frontend/dist/index.mjs", "require": "./src/frontend/dist/index.mjs", "types": "./src/frontend/dist/index.d.ts"}, "./frontend/*": {"import": "./src/frontend/dist/*", "require": "./src/frontend/dist/*", "types": "./src/frontend/dist/*.d.ts"}, "./shared": {"import": "./src/shared/dist/index.js", "require": "./src/shared/dist/index.js", "types": "./src/shared/dist/index.d.ts"}, "./shared/*": {"import": "./src/shared/dist/*", "require": "./src/shared/dist/*", "types": "./src/shared/dist/*.d.ts"}}, "typesVersions": {"*": {"*": ["./src/*/dist/*.d.ts", "./src/*/dist/index.d.ts"]}}, "scripts": {"build:shared": "pnpm --filter @internal/{{name}}-shared build", "build:backend": "pnpm --filter moyan-mfw-base run build:shared && pnpm --filter moyan-mfw-base run build:backend && pnpm --filter @internal/{{name}}-backend build", "build:frontend": "pnpm --filter @internal/{{name}}-frontend build", "build": "pnpm run build:shared && pnpm run build:backend && pnpm run build:frontend", "dev:backend": "pnpm --filter @internal/{{name}}-backend dev", "dev:frontend": "pnpm --filter @internal/{{name}}-frontend dev", "typecheck:shared": "pnpm --filter @internal/{{name}}-shared typecheck", "typecheck:backend": "pnpm --filter @internal/{{name}}-backend typecheck", "typecheck:frontend": "pnpm --filter @internal/{{name}}-frontend typecheck", "typecheck": "pnpm run typecheck:shared && pnpm run typecheck:backend && pnpm run typecheck:frontend", "verify:dist": "node scripts/verify-dist.mjs", "verify": "pnpm run verify:dist"}, "devDependencies": {"@internal/{{name}}-backend": "workspace:*", "@internal/{{name}}-frontend": "workspace:*", "@internal/{{name}}-shared": "workspace:*", "moyan-mfw-base": "workspace:*", "typescript": "catalog:"}}
@@ -0,0 +1,43 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import { fileURLToPath } from 'url';
4
+
5
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
6
+ const frontendDist = path.resolve(__dirname, '../src/frontend/dist');
7
+
8
+ const FAIL = '\x1b[31mFAIL\x1b[0m';
9
+ const PASS = '\x1b[32mPASS\x1b[0m';
10
+
11
+ const distFile = path.join(frontendDist, 'index.mjs');
12
+
13
+ if (!fs.existsSync(distFile)) {
14
+ console.log(`${FAIL} {{displayName}}: dist/index.mjs 缺失,请先运行 pnpm build`);
15
+ process.exit(1);
16
+ }
17
+
18
+ const content = fs.readFileSync(distFile, 'utf-8');
19
+ let failed = 0;
20
+
21
+ if (/^import\s+\w+,\s*\{[\s\S]*?\}\s*from\s*["']vue["']/m.test(content)) {
22
+ console.log(` ${FAIL} no bare default import from "vue"`);
23
+ console.log(' → 检查 vite.config.mts 中是否配置了 fixVueDefaultImport 插件');
24
+ failed++;
25
+ } else {
26
+ console.log(` ${PASS} no bare default import from "vue"`);
27
+ }
28
+
29
+ if (!/Routes\b/.test(content)) {
30
+ console.log(` ${FAIL} exports Routes`);
31
+ console.log(' → 确保 src/index.ts 中正确导出 xxxRoutes');
32
+ failed++;
33
+ } else {
34
+ console.log(` ${PASS} exports Routes`);
35
+ }
36
+
37
+ console.log('');
38
+ if (failed > 0) {
39
+ console.log(`${FAIL} {{displayName}}: ${failed} 项检查未通过 — 阻塞发布`);
40
+ process.exit(1);
41
+ } else {
42
+ console.log(`${PASS} {{displayName}} dist 产物检查通过`);
43
+ }
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "moyan-mfw-cli",
3
- "version": "1.1.5",
3
+ "version": "1.1.7",
4
4
  "description": "MFW framework CLI — extension scaffolding, validation, and publishing tools",
5
5
  "type": "module",
6
6
  "bin": {
7
- "mfw": "./bin/mfw.js"
7
+ "mfw": "bin/mfw.js"
8
8
  },
9
9
  "exports": {
10
10
  ".": {