@maple-design/cli-vue 0.0.0-stage → 1.1.1

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.
Files changed (228) hide show
  1. package/README.md +305 -2
  2. package/README.zh-CN.md +305 -0
  3. package/bin/cli.mjs +5 -0
  4. package/client.d.ts +1 -0
  5. package/client.js +1 -0
  6. package/lib/client/appType.d.ts +4 -0
  7. package/lib/client/appType.js +7 -0
  8. package/lib/client/index.d.ts +29 -0
  9. package/lib/client/index.js +170 -0
  10. package/lib/client/language.d.ts +11 -0
  11. package/lib/client/language.js +52 -0
  12. package/lib/client/theme-state.d.ts +3 -0
  13. package/lib/client/theme-state.js +6 -0
  14. package/lib/node/bin.d.ts +2 -0
  15. package/lib/node/bin.js +154 -0
  16. package/lib/node/commands/build.d.ts +1 -0
  17. package/lib/node/commands/build.js +15 -0
  18. package/lib/node/commands/checklist.d.ts +6 -0
  19. package/lib/node/commands/checklist.js +59 -0
  20. package/lib/node/commands/compile.d.ts +3 -0
  21. package/lib/node/commands/compile.js +41 -0
  22. package/lib/node/commands/create.d.ts +8 -0
  23. package/lib/node/commands/create.js +91 -0
  24. package/lib/node/commands/dev.d.ts +6 -0
  25. package/lib/node/commands/dev.js +58 -0
  26. package/lib/node/commands/extension.d.ts +3 -0
  27. package/lib/node/commands/extension.js +5 -0
  28. package/lib/node/commands/gen.d.ts +24 -0
  29. package/lib/node/commands/gen.js +91 -0
  30. package/lib/node/commands/icons.d.ts +4 -0
  31. package/lib/node/commands/icons.js +15 -0
  32. package/lib/node/commands/preview.d.ts +4 -0
  33. package/lib/node/commands/preview.js +18 -0
  34. package/lib/node/commands/styleVars.d.ts +1 -0
  35. package/lib/node/commands/styleVars.js +6 -0
  36. package/lib/node/commands/test.d.ts +7 -0
  37. package/lib/node/commands/test.js +16 -0
  38. package/lib/node/commands/vite.d.ts +2 -0
  39. package/lib/node/commands/vite.js +14 -0
  40. package/lib/node/compiler/compileModule.d.ts +4 -0
  41. package/lib/node/compiler/compileModule.js +78 -0
  42. package/lib/node/compiler/compileSFC.d.ts +6 -0
  43. package/lib/node/compiler/compileSFC.js +119 -0
  44. package/lib/node/compiler/compileScript.d.ts +27 -0
  45. package/lib/node/compiler/compileScript.js +221 -0
  46. package/lib/node/compiler/compileSiteEntry.d.ts +19 -0
  47. package/lib/node/compiler/compileSiteEntry.js +164 -0
  48. package/lib/node/compiler/compileStyle.d.ts +14 -0
  49. package/lib/node/compiler/compileStyle.js +55 -0
  50. package/lib/node/compiler/compileStyleVars.d.ts +3 -0
  51. package/lib/node/compiler/compileStyleVars.js +46 -0
  52. package/lib/node/compiler/compileTemplateHighlight.d.ts +18 -0
  53. package/lib/node/compiler/compileTemplateHighlight.js +133 -0
  54. package/lib/node/compiler/compileTypes.d.ts +2 -0
  55. package/lib/node/compiler/compileTypes.js +58 -0
  56. package/lib/node/compiler/generateLibraryEntry.d.ts +3 -0
  57. package/lib/node/compiler/generateLibraryEntry.js +152 -0
  58. package/lib/node/compiler/siteRoutes.d.ts +4 -0
  59. package/lib/node/compiler/siteRoutes.js +9 -0
  60. package/lib/node/config/maple.config.d.ts +215 -0
  61. package/lib/node/config/maple.config.js +32 -0
  62. package/lib/node/config/maple.default.config.d.ts +2 -0
  63. package/lib/node/config/maple.default.config.js +386 -0
  64. package/lib/node/config/site-resolver.d.ts +25 -0
  65. package/lib/node/config/site-resolver.js +138 -0
  66. package/lib/node/config/vite.config.d.ts +28 -0
  67. package/lib/node/config/vite.config.js +209 -0
  68. package/lib/node/config/vitest.config.d.ts +2 -0
  69. package/lib/node/config/vitest.config.js +54 -0
  70. package/lib/node/config/vitest.setup.d.ts +1 -0
  71. package/lib/node/config/vitest.setup.js +8 -0
  72. package/lib/node/index.d.ts +13 -0
  73. package/lib/node/index.js +13 -0
  74. package/lib/node/release/index.d.ts +20 -0
  75. package/lib/node/release/index.js +147 -0
  76. package/lib/node/shared/constant.d.ts +47 -0
  77. package/lib/node/shared/constant.js +53 -0
  78. package/lib/node/shared/fsUtils.d.ts +18 -0
  79. package/lib/node/shared/fsUtils.js +57 -0
  80. package/lib/node/shared/logger.d.ts +8 -0
  81. package/lib/node/shared/logger.js +18 -0
  82. package/lib/node/shared/serial-task.d.ts +2 -0
  83. package/lib/node/shared/serial-task.js +9 -0
  84. package/package.json +111 -3
  85. package/site/documentation-sections.spec.ts +45 -0
  86. package/site/documentation-sections.ts +48 -0
  87. package/site/index.html +89 -0
  88. package/site/mobile/App.vue +437 -0
  89. package/site/mobile/AppHome.vue +154 -0
  90. package/site/mobile/main.ts +99 -0
  91. package/site/mobile/route-sync.spec.ts +34 -0
  92. package/site/mobile/route-sync.ts +10 -0
  93. package/site/mobile.html +70 -0
  94. package/site/module.d.ts +5 -0
  95. package/site/pc/App.vue +44 -0
  96. package/site/pc/Layout.vue +641 -0
  97. package/site/pc/components/AppAd.vue +117 -0
  98. package/site/pc/components/AppHeader.vue +459 -0
  99. package/site/pc/components/AppMobile.spec.ts +204 -0
  100. package/site/pc/components/AppMobile.vue +201 -0
  101. package/site/pc/components/AppOutline.spec.ts +89 -0
  102. package/site/pc/components/AppOutline.vue +161 -0
  103. package/site/pc/components/AppSidebar.vue +144 -0
  104. package/site/pc/components/code-example/CodeExample.spec.ts +36 -0
  105. package/site/pc/components/code-example/CodeExample.vue +164 -0
  106. package/site/pc/components/code-example/codeExample.less +88 -0
  107. package/site/pc/components/code-example/index.ts +10 -0
  108. package/site/pc/components/demo-preview/DemoPreview.vue +92 -0
  109. package/site/pc/components/demo-preview/index.ts +8 -0
  110. package/site/pc/components/mobile-preview-url.ts +17 -0
  111. package/site/pc/components/preview-section.spec.ts +24 -0
  112. package/site/pc/components/preview-section.ts +23 -0
  113. package/site/pc/main.ts +108 -0
  114. package/site/pc/pages/index/index.vue +421 -0
  115. package/site/pc/pages/index/locale/en-US.ts +1 -0
  116. package/site/pc/pages/index/locale/zh-CN.ts +1 -0
  117. package/site/pc/responsive-layout.spec.ts +40 -0
  118. package/site/pc/route-state.spec.ts +34 -0
  119. package/site/pc/route-state.ts +25 -0
  120. package/site/pc/scroll-hash.spec.ts +49 -0
  121. package/site/pc/scroll-hash.ts +25 -0
  122. package/site/route-recovery.spec.ts +51 -0
  123. package/site/route-recovery.ts +38 -0
  124. package/site/tsconfig.json +16 -0
  125. package/site/types.ts +6 -0
  126. package/site/utils.ts +45 -0
  127. package/template/create/[ComponentName].tsx.ejs +16 -0
  128. package/template/create/[ComponentName].vue.ejs +21 -0
  129. package/template/create/[componentName].d.ts.ejs +13 -0
  130. package/template/create/__tests__/index.spec.js.ejs +10 -0
  131. package/template/create/docs/en-US.md +0 -0
  132. package/template/create/docs/zh-CN.md +0 -0
  133. package/template/create/example/index.vue.ejs +17 -0
  134. package/template/create/example/locale/_index.ts +17 -0
  135. package/template/create/example/locale/en-US.ts +3 -0
  136. package/template/create/example/locale/index.ts +24 -0
  137. package/template/create/example/locale/zh-CN.ts +3 -0
  138. package/template/create/index.ts.ejs +12 -0
  139. package/template/create/props.ts +1 -0
  140. package/template/create/style/[componentName].less.ejs +5 -0
  141. package/template/create/style/index.less.ejs +1 -0
  142. package/template/create/style/index.ts.ejs +1 -0
  143. package/template/generators/base/.browserslistrc +2 -0
  144. package/template/generators/base/.prettierignore +14 -0
  145. package/template/generators/base/README.md +90 -0
  146. package/template/generators/base/_gitignore +19 -0
  147. package/template/generators/base/eslint.config.js +15 -0
  148. package/template/generators/base/package.json +97 -0
  149. package/template/generators/base/prettier.config.js +3 -0
  150. package/template/generators/base/public/logo.svg +30 -0
  151. package/template/generators/base/shims/shims-md.d.ts +4 -0
  152. package/template/generators/base/shims/shims-vue.d.ts +6 -0
  153. package/template/generators/base/tsconfig.declaration.json +21 -0
  154. package/template/generators/base/tsconfig.json +28 -0
  155. package/template/generators/base/ui-build.config.mjs +16 -0
  156. package/template/generators/config/default/base/docs/home.zh-CN.md +3 -0
  157. package/template/generators/config/default/base/maple.config.mjs +49 -0
  158. package/template/generators/config/default/sfc/src/button/Button.vue +34 -0
  159. package/template/generators/config/default/sfc/src/button/__tests__/index.spec.js +8 -0
  160. package/template/generators/config/default/sfc/src/button/docs/zh-CN.md +39 -0
  161. package/template/generators/config/default/sfc/src/button/example/BasicUse.vue +7 -0
  162. package/template/generators/config/default/sfc/src/button/example/ModifyColor.vue +7 -0
  163. package/template/generators/config/default/sfc/src/button/example/index.vue +12 -0
  164. package/template/generators/config/default/sfc/src/button/index.ts +8 -0
  165. package/template/generators/config/default/sfc/src/button/style/button.less +14 -0
  166. package/template/generators/config/default/sfc/src/button/style/index.less +1 -0
  167. package/template/generators/config/default/sfc/src/button/style/index.ts +1 -0
  168. package/template/generators/config/default/sfc/src/utils/components.ts +20 -0
  169. package/template/generators/config/default/tsx/src/button/Button.tsx +30 -0
  170. package/template/generators/config/default/tsx/src/button/__tests__/index.spec.js +8 -0
  171. package/template/generators/config/default/tsx/src/button/docs/zh-CN.md +39 -0
  172. package/template/generators/config/default/tsx/src/button/example/BasicUse.vue +7 -0
  173. package/template/generators/config/default/tsx/src/button/example/ModifyColor.vue +7 -0
  174. package/template/generators/config/default/tsx/src/button/example/index.vue +12 -0
  175. package/template/generators/config/default/tsx/src/button/index.ts +8 -0
  176. package/template/generators/config/default/tsx/src/button/style/button.less +14 -0
  177. package/template/generators/config/default/tsx/src/button/style/index.less +1 -0
  178. package/template/generators/config/default/tsx/src/button/style/index.ts +1 -0
  179. package/template/generators/config/default/tsx/src/utils/components.ts +20 -0
  180. package/template/generators/config/i18n/base/docs/home.en-US.md +3 -0
  181. package/template/generators/config/i18n/base/docs/home.zh-CN.md +3 -0
  182. package/template/generators/config/i18n/base/maple.config.mjs +51 -0
  183. package/template/generators/config/i18n/sfc/src/button/Button.vue +38 -0
  184. package/template/generators/config/i18n/sfc/src/button/__tests__/index.spec.js +8 -0
  185. package/template/generators/config/i18n/sfc/src/button/docs/en-US.md +39 -0
  186. package/template/generators/config/i18n/sfc/src/button/docs/zh-CN.md +39 -0
  187. package/template/generators/config/i18n/sfc/src/button/example/BasicUse.vue +11 -0
  188. package/template/generators/config/i18n/sfc/src/button/example/ModifyColor.vue +11 -0
  189. package/template/generators/config/i18n/sfc/src/button/example/index.vue +15 -0
  190. package/template/generators/config/i18n/sfc/src/button/example/locale/en-US.ts +5 -0
  191. package/template/generators/config/i18n/sfc/src/button/example/locale/index.ts +23 -0
  192. package/template/generators/config/i18n/sfc/src/button/example/locale/zh-CN.ts +5 -0
  193. package/template/generators/config/i18n/sfc/src/button/index.ts +8 -0
  194. package/template/generators/config/i18n/sfc/src/button/style/button.less +14 -0
  195. package/template/generators/config/i18n/sfc/src/button/style/index.less +1 -0
  196. package/template/generators/config/i18n/sfc/src/button/style/index.ts +1 -0
  197. package/template/generators/config/i18n/sfc/src/locale/__tests__/index.spec.js +52 -0
  198. package/template/generators/config/i18n/sfc/src/locale/docs/en-US.md +26 -0
  199. package/template/generators/config/i18n/sfc/src/locale/docs/zh-CN.md +25 -0
  200. package/template/generators/config/i18n/sfc/src/locale/en-US.d.ts +5 -0
  201. package/template/generators/config/i18n/sfc/src/locale/en-US.ts +7 -0
  202. package/template/generators/config/i18n/sfc/src/locale/index.ts +82 -0
  203. package/template/generators/config/i18n/sfc/src/locale/zh-CN.d.ts +5 -0
  204. package/template/generators/config/i18n/sfc/src/locale/zh-CN.ts +7 -0
  205. package/template/generators/config/i18n/sfc/src/utils/components.ts +20 -0
  206. package/template/generators/config/i18n/tsx/src/button/Button.tsx +35 -0
  207. package/template/generators/config/i18n/tsx/src/button/__tests__/index.spec.js +8 -0
  208. package/template/generators/config/i18n/tsx/src/button/docs/en-US.md +39 -0
  209. package/template/generators/config/i18n/tsx/src/button/docs/zh-CN.md +39 -0
  210. package/template/generators/config/i18n/tsx/src/button/example/BasicUse.vue +11 -0
  211. package/template/generators/config/i18n/tsx/src/button/example/ModifyColor.vue +11 -0
  212. package/template/generators/config/i18n/tsx/src/button/example/index.vue +15 -0
  213. package/template/generators/config/i18n/tsx/src/button/example/locale/en-US.ts +5 -0
  214. package/template/generators/config/i18n/tsx/src/button/example/locale/index.ts +23 -0
  215. package/template/generators/config/i18n/tsx/src/button/example/locale/zh-CN.ts +5 -0
  216. package/template/generators/config/i18n/tsx/src/button/index.ts +8 -0
  217. package/template/generators/config/i18n/tsx/src/button/style/button.less +14 -0
  218. package/template/generators/config/i18n/tsx/src/button/style/index.less +1 -0
  219. package/template/generators/config/i18n/tsx/src/button/style/index.ts +1 -0
  220. package/template/generators/config/i18n/tsx/src/locale/__tests__/index.spec.js +52 -0
  221. package/template/generators/config/i18n/tsx/src/locale/docs/en-US.md +26 -0
  222. package/template/generators/config/i18n/tsx/src/locale/docs/zh-CN.md +25 -0
  223. package/template/generators/config/i18n/tsx/src/locale/en-US.d.ts +5 -0
  224. package/template/generators/config/i18n/tsx/src/locale/en-US.ts +7 -0
  225. package/template/generators/config/i18n/tsx/src/locale/index.ts +82 -0
  226. package/template/generators/config/i18n/tsx/src/locale/zh-CN.d.ts +5 -0
  227. package/template/generators/config/i18n/tsx/src/locale/zh-CN.ts +7 -0
  228. package/template/generators/config/i18n/tsx/src/utils/components.ts +20 -0
@@ -0,0 +1,2 @@
1
+ export declare function generateReference(moduleDir: string): void;
2
+ export declare function compileTypes(): Promise<void>;
@@ -0,0 +1,58 @@
1
+ import { execFile } from 'node:child_process';
2
+ import { relative, resolve } from 'node:path';
3
+ import { promisify } from 'node:util';
4
+ import fse from 'fs-extra';
5
+ import { getMapleConfig } from '../config/maple.config.js';
6
+ import { CWD, SRC_DIR } from '../shared/constant.js';
7
+ import { getPublicDirs } from '../shared/fsUtils.js';
8
+ import { compileStyleVars } from './compileStyleVars.js';
9
+ import { exportedComponentTokens } from './generateLibraryEntry.js';
10
+ const declarationsDir = resolve(CWD, 'types-generated');
11
+ export function generateReference(moduleDir) {
12
+ const target = relative(moduleDir, declarationsDir).replaceAll('\\', '/');
13
+ fse.writeFileSync(resolve(moduleDir, 'index.d.ts'), `export * from '${target}'\nexport { default } from '${target}'\n`);
14
+ }
15
+ // Published declarations derive from the runtime source, not the legacy hand-written Props.
16
+ export async function compileTypes() {
17
+ compileStyleVars();
18
+ // This directory contains generated artifacts only; stale renamed components must not survive builds.
19
+ await fse.emptyDir(declarationsDir);
20
+ await promisify(execFile)('vue-tsc', ['-p', 'tsconfig.declaration.json'], { cwd: CWD, maxBuffer: 16 * 1024 * 1024 });
21
+ async function copyDeclarations(dir) {
22
+ for (const entry of await fse.readdir(dir, { withFileTypes: true })) {
23
+ if (['__tests__', '__demos__', 'example'].includes(entry.name)) {
24
+ continue;
25
+ }
26
+ const file = resolve(dir, entry.name);
27
+ if (entry.isDirectory()) {
28
+ await copyDeclarations(file);
29
+ }
30
+ else if (entry.name.endsWith('.d.ts')) {
31
+ const target = resolve(declarationsDir, relative(SRC_DIR, file));
32
+ await fse.ensureDir(resolve(target, '..'));
33
+ await fse.copyFile(file, target);
34
+ }
35
+ }
36
+ }
37
+ await copyDeclarations(SRC_DIR);
38
+ const { namespace = 'mp', directives = [] } = await getMapleConfig();
39
+ const lines = [];
40
+ const nonComponents = new Set(['_ContextComponent', '_LocaleComponent', '_ThemesComponent', '_LoadingBarComponent']);
41
+ for (const dir of await getPublicDirs()) {
42
+ for (const token of await exportedComponentTokens(dir)) {
43
+ // Loading exports both a Vue component and a directive; Hover exports a child component.
44
+ if (!token.endsWith('Component') ||
45
+ nonComponents.has(token) ||
46
+ (directives.includes(dir) &&
47
+ dir !== 'loading' &&
48
+ token.toLowerCase() === `_${dir.replaceAll('-', '')}component`)) {
49
+ continue;
50
+ }
51
+ const name = namespace[0].toUpperCase() + namespace.slice(1) + token.slice(1, -'Component'.length);
52
+ lines.push(` ${name}: typeof import('./index')['${token}']`);
53
+ }
54
+ }
55
+ await fse.writeFile(resolve(declarationsDir, 'global.d.ts'), `import 'vue'\ndeclare module 'vue' {\n export interface GlobalComponents {\n${lines.join('\n')}\n }\n}\n`);
56
+ const entry = resolve(declarationsDir, 'index.d.ts');
57
+ await fse.appendFile(entry, "\nimport './global'\n");
58
+ }
@@ -0,0 +1,3 @@
1
+ export declare function publicContractExports(dirs: string[]): string[];
2
+ export declare function exportedComponentTokens(dir: string): Promise<string[]>;
3
+ export declare function generateLibraryEntry(): Promise<void>;
@@ -0,0 +1,152 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { readFile, writeFile } from 'node:fs/promises';
3
+ import { resolve } from 'node:path';
4
+ import { pascalCase } from '@maple-design/shared-vue';
5
+ import ts from 'typescript';
6
+ import { SRC_DIR } from '../shared/constant.js';
7
+ import { getPublicDirs, getVersion } from '../shared/fsUtils.js';
8
+ // Follow exports rather than scraping type names: re-exports and child Props count too.
9
+ export function publicContractExports(dirs) {
10
+ const entries = dirs
11
+ .map((dir) => INDEX_FILES.map((file) => resolve(SRC_DIR, dir, file)).find(existsSync))
12
+ .filter((file) => Boolean(file));
13
+ const optionalExports = [
14
+ { path: 'loading', runtime: ['vLoading'], types: ['LoadingDirectiveOptions'] },
15
+ { path: 'image', runtime: ['imagePreview'], types: [] },
16
+ { path: 'upload', runtime: ['useUploader'], types: [] },
17
+ { path: 'hover', runtime: ['useHoverOverlay'], types: [] },
18
+ { path: 'form', runtime: ['useFormItem', 'useFormErrorDescription'], types: [] },
19
+ { path: 'field-decorator', runtime: ['fieldLoadingModes'], types: [] },
20
+ { path: 'utils/popup-container', runtime: [], types: ['PopupContainer'] },
21
+ ].map((item) => ({
22
+ ...item,
23
+ file: [...INDEX_FILES.map((file) => resolve(SRC_DIR, item.path, file)), resolve(SRC_DIR, `${item.path}.ts`)].find(existsSync),
24
+ }));
25
+ const program = ts.createProgram([...entries, ...optionalExports.flatMap((item) => (item.file ? [item.file] : []))], {
26
+ moduleResolution: ts.ModuleResolutionKind.NodeJs,
27
+ jsx: ts.JsxEmit.Preserve,
28
+ skipLibCheck: true,
29
+ });
30
+ const checker = program.getTypeChecker();
31
+ const used = new Set(['LoadingDirectiveOptions', ...dirs.map(pascalCase)]);
32
+ const contracts = entries.flatMap((file) => {
33
+ const source = program.getSourceFile(file);
34
+ const symbol = source && checker.getSymbolAtLocation(source);
35
+ if (!symbol) {
36
+ return [];
37
+ }
38
+ const runtime = [], types = [];
39
+ for (const exported of checker.getExportsOfModule(symbol)) {
40
+ const name = exported.name;
41
+ if (used.has(name)) {
42
+ continue;
43
+ }
44
+ const original = exported.flags & ts.SymbolFlags.Alias ? checker.getAliasedSymbol(exported) : exported;
45
+ if (/^[a-z].*Props$/.test(name)) {
46
+ runtime.push(name);
47
+ used.add(name);
48
+ }
49
+ else if (original.flags & ts.SymbolFlags.Type && /^[A-Z]/.test(name) && !['Props', 'Instance'].includes(name)) {
50
+ types.push(name);
51
+ used.add(name);
52
+ }
53
+ }
54
+ const dir = dirs.find((dir) => INDEX_FILES.some((index) => resolve(SRC_DIR, dir, index) === file));
55
+ return [
56
+ runtime.length ? `export { ${runtime.join(', ')} } from './${dir}'` : '',
57
+ types.length ? `export type { ${types.join(', ')} } from './${dir}'` : '',
58
+ ].filter(Boolean);
59
+ });
60
+ for (const item of optionalExports) {
61
+ const source = item.file && program.getSourceFile(item.file);
62
+ const symbol = source && checker.getSymbolAtLocation(source);
63
+ if (!symbol) {
64
+ continue;
65
+ }
66
+ const available = new Set(checker.getExportsOfModule(symbol).map((value) => value.name));
67
+ const runtime = item.runtime.filter((name) => available.has(name));
68
+ const types = item.types.filter((name) => available.has(name));
69
+ if (runtime.length) {
70
+ contracts.push(`export { ${runtime.join(', ')} } from './${item.path}'`);
71
+ }
72
+ if (types.length) {
73
+ contracts.push(`export type { ${types.join(', ')} } from './${item.path}'`);
74
+ }
75
+ }
76
+ return contracts;
77
+ }
78
+ const INDEX_FILES = ['index.ts', 'index.tsx', 'index.js'];
79
+ export async function exportedComponentTokens(dir) {
80
+ for (const file of INDEX_FILES) {
81
+ const path = resolve(SRC_DIR, dir, file);
82
+ if (!existsSync(path)) {
83
+ continue;
84
+ }
85
+ const source = await readFile(path, 'utf8');
86
+ const dirName = pascalCase(dir);
87
+ const aliases = [...source.matchAll(/export const (_[A-Za-z0-9]+Component)/g)].map((match) => match[1]);
88
+ const named = [...source.matchAll(/export \{([^}]+)\}/g)]
89
+ .flatMap((match) => match[1].split(','))
90
+ .map((part) => {
91
+ const sides = part.trim().split(/\s+as\s+/);
92
+ return (sides[1] ?? sides[0]).trim();
93
+ })
94
+ .filter((name) => /^[A-Z]/.test(name) && name !== dirName && !name.endsWith('Props'));
95
+ const tokens = [...new Set([...named, ...aliases])];
96
+ if (tokens.length) {
97
+ return tokens;
98
+ }
99
+ }
100
+ return [`_${pascalCase(dir)}Component`];
101
+ }
102
+ export async function generateLibraryEntry() {
103
+ const publicDirs = (await getPublicDirs()).filter((dir) => dir !== 'index');
104
+ const publicComponents = publicDirs.map((dir) => pascalCase(dir));
105
+ const imports = publicDirs.map((dir, index) => `import ${publicComponents[index]} from './${dir}'`);
106
+ const version = getVersion();
107
+ const tokenExports = await Promise.all(publicDirs.map(async (dir) => {
108
+ const tokens = await exportedComponentTokens(dir);
109
+ return `export { ${tokens.join(', ')} } from './${dir}'`;
110
+ }));
111
+ const mapleVue = `\
112
+ import type { App } from 'vue'
113
+ ${imports.join('\n')}
114
+
115
+ export const version = '${version}'
116
+
117
+ function install(app: App) {
118
+ const plugins = [${publicComponents.join(', ')}]
119
+ for (const plugin of plugins) {
120
+ if (plugin && typeof (plugin as { install?: unknown }).install === 'function') {
121
+ app.use(plugin as unknown as { install: (app: App) => void })
122
+ }
123
+ }
124
+ }
125
+
126
+ export {
127
+ install,
128
+ ${publicComponents.join(',\n ')}
129
+ }
130
+
131
+ export interface MapleLibrary {
132
+ version: string
133
+ install: typeof install
134
+ ${publicComponents.map((name) => `${name}: typeof ${name}`).join('\n ')}
135
+ }
136
+ const library: MapleLibrary = {
137
+ version,
138
+ install,
139
+ // Preserve ESM live bindings: a component entry may be evaluated before the
140
+ // aggregate entry through the development resolver's dependency graph.
141
+ ${publicComponents.map((name) => `get ${name}() { return ${name} }`).join(',\n ')}
142
+ }
143
+ export default library
144
+ `;
145
+ const index = `\
146
+ export { default, version, install, ${publicComponents.join(', ')} } from './maple-vue'
147
+ ${tokenExports.join('\n')}
148
+ ${publicContractExports(publicDirs).join('\n')}
149
+ `;
150
+ await writeFile(resolve(SRC_DIR, 'maple-vue.ts'), mapleVue);
151
+ await writeFile(resolve(SRC_DIR, 'index.ts'), index);
152
+ }
@@ -0,0 +1,4 @@
1
+ /** Join route groups without emitting array holes when a group is empty. */
2
+ export declare function joinSiteRoutes(...groups: string[][]): string;
3
+ /** Documentation redirects stay within the same site and locale. */
4
+ export declare function documentationRedirect(markdown: string): string | undefined;
@@ -0,0 +1,9 @@
1
+ /** Join route groups without emitting array holes when a group is empty. */
2
+ export function joinSiteRoutes(...groups) {
3
+ return groups.flat().join(',\n');
4
+ }
5
+ /** Documentation redirects stay within the same site and locale. */
6
+ export function documentationRedirect(markdown) {
7
+ const frontmatter = /^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/.exec(markdown)?.[1];
8
+ return frontmatter?.match(/^redirectTo:\s*(\/(?:zh-CN|en-US)\/[\w-]+)\s*$/m)?.[1];
9
+ }
@@ -0,0 +1,215 @@
1
+ import { type CopyOptions } from '@maple-design/vite-plugins-vue';
2
+ import { Plugin, ProxyOptions } from 'vite';
3
+ export interface MapleConfigIcons {
4
+ /** SVG source directory owned by the product icon package. */
5
+ entry?: string;
6
+ /** Generated Vue source directory. */
7
+ output?: string;
8
+ }
9
+ export interface MapleConfigEsbuild {
10
+ target?: string | string[];
11
+ }
12
+ export interface MapleConfigHtmlInjectPoint {
13
+ position?: 'start' | 'end' | 'script-start';
14
+ content?: string;
15
+ }
16
+ export interface MapleConfigHtmlInject {
17
+ head?: MapleConfigHtmlInjectPoint[];
18
+ body?: MapleConfigHtmlInjectPoint[];
19
+ }
20
+ export interface MapleConfigPcMenu {
21
+ text: Record<string, string>;
22
+ type: number;
23
+ doc?: string;
24
+ parent?: string;
25
+ }
26
+ export interface MapleConfigPcHeader {
27
+ i18n?: Record<string, string>;
28
+ currentVersion?: string;
29
+ github?: string;
30
+ changelog?: string;
31
+ playground?: string;
32
+ ai?: string;
33
+ themes?: Record<string, string>[];
34
+ versions?: {
35
+ name: string;
36
+ items?: {
37
+ label?: string;
38
+ link?: string;
39
+ }[];
40
+ }[];
41
+ }
42
+ export interface MapleConfigPcAd {
43
+ id?: string;
44
+ logo?: string;
45
+ logoHeight?: string;
46
+ description?: Record<string, string>;
47
+ descriptionBackground?: string;
48
+ descriptionTextColor?: string;
49
+ link?: Record<string, string>;
50
+ background?: string;
51
+ textColor?: string;
52
+ }
53
+ export interface MapleConfigMobileHeader {
54
+ i18n?: Record<string, string>;
55
+ github?: string;
56
+ themes?: Record<string, string>[];
57
+ }
58
+ export interface MapleConfigSeo {
59
+ title?: string;
60
+ description?: string;
61
+ keywords?: string;
62
+ }
63
+ export interface MapleConfigPcIndexPage {
64
+ eyebrow?: Record<string, string>;
65
+ headline?: Record<string, string>;
66
+ companion?: {
67
+ name: string;
68
+ label: Record<string, string>;
69
+ href: string;
70
+ title: Record<string, string>;
71
+ description: Record<string, string>;
72
+ };
73
+ description?: Record<string, string>;
74
+ started?: Record<string, string>;
75
+ viewOnGithub?: Record<string, string>;
76
+ features?: {
77
+ name: Record<string, string>;
78
+ description: Record<string, string>;
79
+ }[];
80
+ teamMembers?: {
81
+ label: Record<string, string>;
82
+ members: {
83
+ name?: Record<string, string>;
84
+ title?: Record<string, string>;
85
+ description?: Record<string, string>;
86
+ avatar?: string;
87
+ github?: string;
88
+ twitter?: string;
89
+ }[];
90
+ };
91
+ contributors?: {
92
+ label?: Record<string, string>;
93
+ link?: string;
94
+ image?: string;
95
+ };
96
+ sponsors?: {
97
+ label?: Record<string, string>;
98
+ link?: string;
99
+ image?: string;
100
+ };
101
+ license?: Record<string, string>;
102
+ copyright?: Record<string, string>;
103
+ }
104
+ export interface MapleConfigPc {
105
+ /** Independent documentation areas with scoped menus. */
106
+ sections?: {
107
+ id: string;
108
+ text: Record<string, string>;
109
+ entry: string;
110
+ mobileEntry?: string;
111
+ docs?: string[];
112
+ }[];
113
+ title?: Record<string, string>;
114
+ redirect?: string;
115
+ clipboard?: Record<string, string>;
116
+ indexPage?: MapleConfigPcIndexPage;
117
+ ad?: MapleConfigPcAd;
118
+ header?: MapleConfigPcHeader;
119
+ menu?: MapleConfigPcMenu[];
120
+ htmlInject?: MapleConfigHtmlInject;
121
+ fold?: {
122
+ /** Whether Markdown code blocks are collapsed on first render. Does not affect live demo previews. @default false */
123
+ defaultFold?: boolean;
124
+ /** Visible source height while collapsed. Use 0 to hide it completely. @default 0 */
125
+ foldHeight?: number;
126
+ };
127
+ }
128
+ export interface MapleConfigMobile {
129
+ /** Root documentation pages also available in the mobile site. */
130
+ docs?: string[];
131
+ title?: Record<string, string>;
132
+ redirect?: string;
133
+ header?: MapleConfigMobileHeader;
134
+ htmlInject?: MapleConfigHtmlInject;
135
+ }
136
+ export interface MapleConfig {
137
+ /**
138
+ * @default `Maple`
139
+ * UI library name.
140
+ */
141
+ name?: string;
142
+ /**
143
+ * @default `mp`
144
+ * Component name prefix
145
+ */
146
+ namespace?: string;
147
+ /**
148
+ * @default `localhost`
149
+ * Local dev server host
150
+ */
151
+ host?: string;
152
+ /**
153
+ * @default `8080`
154
+ * Local dev server port
155
+ */
156
+ port?: number;
157
+ proxy?: Record<string, string | ProxyOptions>;
158
+ title?: string;
159
+ logo?: string;
160
+ themeKey?: string;
161
+ /** Mobile demo theme storage key. Defaults to `${themeKey}_DEMO`. */
162
+ demoThemeKey?: string;
163
+ seo?: {
164
+ title?: string;
165
+ description?: string;
166
+ keywords?: string;
167
+ };
168
+ defaultLanguage?: 'zh-CN' | 'en-US';
169
+ alias?: Record<string, string>;
170
+ /**
171
+ * @default `false`
172
+ * Show mobile component on the right.
173
+ */
174
+ useMobile?: boolean;
175
+ lightTheme?: Record<string, string>;
176
+ darkTheme?: Record<string, string>;
177
+ mapleLightTheme?: Record<string, string>;
178
+ mapleDarkTheme?: Record<string, string>;
179
+ alpsLightTheme?: Record<string, string>;
180
+ fireflyLightTheme?: Record<string, string>;
181
+ alpsDarkTheme?: Record<string, string>;
182
+ fireflyDarkTheme?: Record<string, string>;
183
+ defaultLightTheme?: 'lightTheme' | 'mapleLightTheme' | 'alpsLightTheme' | 'fireflyLightTheme';
184
+ defaultDarkTheme?: 'darkTheme' | 'mapleDarkTheme' | 'alpsDarkTheme' | 'fireflyDarkTheme';
185
+ highlight?: {
186
+ style: string;
187
+ };
188
+ analysis?: {
189
+ baidu: string;
190
+ };
191
+ pc?: MapleConfigPc;
192
+ mobile?: MapleConfigMobile;
193
+ copy?: CopyOptions['paths'];
194
+ icons?: MapleConfigIcons;
195
+ esbuild?: MapleConfigEsbuild;
196
+ bundle?: {
197
+ external?: string[];
198
+ globals?: Record<string, string>;
199
+ };
200
+ /**
201
+ * @vitePlugins
202
+ * @default `[]`
203
+ * Vite plugins
204
+ */
205
+ vitePlugins?: Plugin[] | ((plugins: Plugin[]) => Plugin[]);
206
+ /**
207
+ * @default `[]`
208
+ * Directive folder name for component library.
209
+ */
210
+ directives?: string[];
211
+ _cf?: string[];
212
+ }
213
+ export declare function defineConfig(config: MapleConfig): MapleConfig;
214
+ export declare function mergeStrategy(_: any, srcValue: any, key: any): any[] | undefined;
215
+ export declare function getMapleConfig(emit?: boolean): Promise<Required<MapleConfig>>;
@@ -0,0 +1,32 @@
1
+ import { pathToFileURL } from 'url';
2
+ import { isArray, mergeWith } from '@maple-design/shared-vue';
3
+ import fse from 'fs-extra';
4
+ import { COMPONENT_REUSE_JSON, MAPLE_CONFIG, SITE_CONFIG } from '../shared/constant.js';
5
+ import { outputFileSyncOnChange } from '../shared/fsUtils.js';
6
+ const { pathExistsSync, statSync } = fse;
7
+ export function defineConfig(config) {
8
+ return config;
9
+ }
10
+ export function mergeStrategy(_, srcValue, key) {
11
+ // Arrays merged by index would pollute items across reloads when length/order changes
12
+ // (e.g. menu titles picking up the next component's `doc`).
13
+ const keys = ['features', 'members', 'versions', 'themes', '_cf', 'menu'];
14
+ if (keys.includes(key) && isArray(srcValue)) {
15
+ return srcValue;
16
+ }
17
+ }
18
+ export async function getMapleConfig(emit = false) {
19
+ const defaultConfig = (await import('./maple.default.config.js')).default;
20
+ const configStamp = pathExistsSync(MAPLE_CONFIG) ? statSync(MAPLE_CONFIG).mtimeMs : 0;
21
+ const reuseStamp = pathExistsSync(COMPONENT_REUSE_JSON) ? statSync(COMPONENT_REUSE_JSON).mtimeMs : 0;
22
+ const config = pathExistsSync(MAPLE_CONFIG)
23
+ ? (await import(`${pathToFileURL(MAPLE_CONFIG).href}?_t=${configStamp}-${reuseStamp}`)).default
24
+ : {};
25
+ // Clone first: mergeWith mutates the destination; the default export is module-cached.
26
+ const mergedConfig = mergeWith(structuredClone(defaultConfig), config, mergeStrategy);
27
+ if (emit) {
28
+ const source = JSON.stringify(mergedConfig, null, 2);
29
+ outputFileSyncOnChange(SITE_CONFIG, source);
30
+ }
31
+ return mergedConfig;
32
+ }
@@ -0,0 +1,2 @@
1
+ declare const _default: import("./maple.config.js").MapleConfig;
2
+ export default _default;