@bleedingdev/modern-js-create 3.2.0-ultramodern.12 → 3.2.0-ultramodern.121

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 (165) hide show
  1. package/README.md +167 -72
  2. package/bin/run.js +0 -0
  3. package/dist/cjs/create-package-root.cjs +63 -0
  4. package/dist/cjs/index.cjs +528 -0
  5. package/dist/cjs/locale/en.cjs +93 -0
  6. package/dist/cjs/locale/index.cjs +50 -0
  7. package/dist/cjs/locale/zh.cjs +93 -0
  8. package/dist/cjs/ultramodern-package-source.cjs +135 -0
  9. package/dist/cjs/ultramodern-workspace/add-vertical.cjs +337 -0
  10. package/dist/cjs/ultramodern-workspace/app-files.cjs +223 -0
  11. package/dist/cjs/ultramodern-workspace/contracts.cjs +836 -0
  12. package/dist/cjs/ultramodern-workspace/demo-components.cjs +422 -0
  13. package/dist/cjs/ultramodern-workspace/descriptors.cjs +222 -0
  14. package/dist/cjs/ultramodern-workspace/effect-api.cjs +952 -0
  15. package/dist/cjs/ultramodern-workspace/fs-io.cjs +191 -0
  16. package/dist/cjs/ultramodern-workspace/index.cjs +48 -0
  17. package/dist/cjs/ultramodern-workspace/locales.cjs +173 -0
  18. package/dist/cjs/ultramodern-workspace/module-federation.cjs +487 -0
  19. package/dist/cjs/ultramodern-workspace/naming.cjs +161 -0
  20. package/dist/cjs/ultramodern-workspace/package-json.cjs +406 -0
  21. package/dist/cjs/ultramodern-workspace/package-source.cjs +59 -0
  22. package/dist/cjs/ultramodern-workspace/policy.cjs +248 -0
  23. package/dist/cjs/ultramodern-workspace/public-surface.cjs +268 -0
  24. package/dist/cjs/ultramodern-workspace/routes.cjs +375 -0
  25. package/dist/cjs/ultramodern-workspace/types.cjs +61 -0
  26. package/dist/cjs/ultramodern-workspace/versions.cjs +153 -0
  27. package/dist/cjs/ultramodern-workspace/workspace-scripts.cjs +153 -0
  28. package/dist/cjs/ultramodern-workspace/write-workspace.cjs +175 -0
  29. package/dist/esm/create-package-root.js +14 -0
  30. package/dist/esm/index.js +491 -0
  31. package/dist/esm/locale/en.js +55 -0
  32. package/dist/esm/locale/index.js +9 -0
  33. package/dist/esm/locale/zh.js +55 -0
  34. package/dist/esm/ultramodern-package-source.js +63 -0
  35. package/dist/esm/ultramodern-workspace/add-vertical.js +252 -0
  36. package/dist/esm/ultramodern-workspace/app-files.js +149 -0
  37. package/dist/esm/ultramodern-workspace/contracts.js +741 -0
  38. package/dist/esm/ultramodern-workspace/demo-components.js +363 -0
  39. package/dist/esm/ultramodern-workspace/descriptors.js +133 -0
  40. package/dist/esm/ultramodern-workspace/effect-api.js +854 -0
  41. package/dist/esm/ultramodern-workspace/fs-io.js +90 -0
  42. package/dist/esm/ultramodern-workspace/index.js +3 -0
  43. package/dist/esm/ultramodern-workspace/locales.js +122 -0
  44. package/dist/esm/ultramodern-workspace/module-federation.js +415 -0
  45. package/dist/esm/ultramodern-workspace/naming.js +71 -0
  46. package/dist/esm/ultramodern-workspace/package-json.js +338 -0
  47. package/dist/esm/ultramodern-workspace/package-source.js +21 -0
  48. package/dist/esm/ultramodern-workspace/policy.js +183 -0
  49. package/dist/esm/ultramodern-workspace/public-surface.js +183 -0
  50. package/dist/esm/ultramodern-workspace/routes.js +280 -0
  51. package/dist/esm/ultramodern-workspace/types.js +16 -0
  52. package/dist/esm/ultramodern-workspace/versions.js +34 -0
  53. package/dist/esm/ultramodern-workspace/workspace-scripts.js +91 -0
  54. package/dist/esm/ultramodern-workspace/write-workspace.js +121 -0
  55. package/dist/esm-node/create-package-root.js +15 -0
  56. package/dist/esm-node/index.js +492 -0
  57. package/dist/esm-node/locale/en.js +56 -0
  58. package/dist/esm-node/locale/index.js +10 -0
  59. package/dist/esm-node/locale/zh.js +56 -0
  60. package/dist/esm-node/ultramodern-package-source.js +64 -0
  61. package/dist/esm-node/ultramodern-workspace/add-vertical.js +253 -0
  62. package/dist/esm-node/ultramodern-workspace/app-files.js +150 -0
  63. package/dist/esm-node/ultramodern-workspace/contracts.js +742 -0
  64. package/dist/esm-node/ultramodern-workspace/demo-components.js +364 -0
  65. package/dist/esm-node/ultramodern-workspace/descriptors.js +134 -0
  66. package/dist/esm-node/ultramodern-workspace/effect-api.js +855 -0
  67. package/dist/esm-node/ultramodern-workspace/fs-io.js +91 -0
  68. package/dist/esm-node/ultramodern-workspace/index.js +4 -0
  69. package/dist/esm-node/ultramodern-workspace/locales.js +123 -0
  70. package/dist/esm-node/ultramodern-workspace/module-federation.js +416 -0
  71. package/dist/esm-node/ultramodern-workspace/naming.js +72 -0
  72. package/dist/esm-node/ultramodern-workspace/package-json.js +339 -0
  73. package/dist/esm-node/ultramodern-workspace/package-source.js +22 -0
  74. package/dist/esm-node/ultramodern-workspace/policy.js +184 -0
  75. package/dist/esm-node/ultramodern-workspace/public-surface.js +184 -0
  76. package/dist/esm-node/ultramodern-workspace/routes.js +281 -0
  77. package/dist/esm-node/ultramodern-workspace/types.js +17 -0
  78. package/dist/esm-node/ultramodern-workspace/versions.js +35 -0
  79. package/dist/esm-node/ultramodern-workspace/workspace-scripts.js +92 -0
  80. package/dist/esm-node/ultramodern-workspace/write-workspace.js +122 -0
  81. package/dist/types/create-package-root.d.ts +1 -0
  82. package/dist/types/locale/en.d.ts +8 -9
  83. package/dist/types/locale/index.d.ts +109 -2
  84. package/dist/types/locale/zh.d.ts +8 -9
  85. package/dist/types/ultramodern-package-source.d.ts +28 -0
  86. package/dist/types/ultramodern-workspace/add-vertical.d.ts +19 -0
  87. package/dist/types/ultramodern-workspace/app-files.d.ts +14 -0
  88. package/dist/types/ultramodern-workspace/contracts.d.ts +21 -0
  89. package/dist/types/ultramodern-workspace/demo-components.d.ts +9 -0
  90. package/dist/types/ultramodern-workspace/descriptors.d.ts +39 -0
  91. package/dist/types/ultramodern-workspace/effect-api.d.ts +73 -0
  92. package/dist/types/ultramodern-workspace/fs-io.d.ts +18 -0
  93. package/dist/types/ultramodern-workspace/index.d.ts +4 -0
  94. package/dist/types/ultramodern-workspace/locales.d.ts +183 -0
  95. package/dist/types/ultramodern-workspace/module-federation.d.ts +16 -0
  96. package/dist/types/ultramodern-workspace/naming.d.ts +16 -0
  97. package/dist/types/ultramodern-workspace/package-json.d.ts +12 -0
  98. package/dist/types/ultramodern-workspace/package-source.d.ts +2 -0
  99. package/dist/types/ultramodern-workspace/policy.d.ts +60 -0
  100. package/dist/types/ultramodern-workspace/public-surface.d.ts +37 -0
  101. package/dist/types/ultramodern-workspace/routes.d.ts +25 -0
  102. package/dist/types/ultramodern-workspace/types.d.ts +95 -0
  103. package/dist/types/ultramodern-workspace/versions.d.ts +38 -0
  104. package/dist/types/ultramodern-workspace/workspace-scripts.d.ts +10 -0
  105. package/dist/types/ultramodern-workspace/write-workspace.d.ts +4 -0
  106. package/package.json +34 -15
  107. package/template-workspace/.agents/agent-reference-repos.json +24 -0
  108. package/template-workspace/.agents/skills-lock.json +19 -0
  109. package/template-workspace/.codex/hooks.json +16 -0
  110. package/template-workspace/.github/renovate.json +29 -0
  111. package/template-workspace/.github/workflows/ultramodern-workspace-gates.yml.handlebars +67 -0
  112. package/template-workspace/.gitignore.handlebars +5 -0
  113. package/template-workspace/.mise.toml.handlebars +3 -0
  114. package/template-workspace/AGENTS.md.handlebars +87 -0
  115. package/template-workspace/README.md.handlebars +132 -11
  116. package/template-workspace/lefthook.yml +24 -0
  117. package/template-workspace/oxfmt.config.ts +1 -0
  118. package/template-workspace/oxlint.config.ts +1 -0
  119. package/template-workspace/pnpm-workspace.yaml.handlebars +40 -0
  120. package/template-workspace/scripts/bootstrap-agent-skills.mjs +184 -21
  121. package/template-workspace/scripts/setup-agent-reference-repos.mjs +370 -0
  122. package/templates/app/shell-frame.tsx +49 -0
  123. package/templates/app/ultramodern-route-head.tsx.handlebars +142 -0
  124. package/templates/packages/shared-contracts-index.ts +466 -0
  125. package/templates/workspace-scripts/assert-mf-types.mjs.handlebars +69 -0
  126. package/templates/workspace-scripts/check-ultramodern-i18n-boundaries.mjs +9 -0
  127. package/templates/workspace-scripts/generate-public-surface-assets.mjs +529 -0
  128. package/templates/workspace-scripts/proof-cloudflare-version.mjs +125 -0
  129. package/templates/workspace-scripts/ultramodern-cloudflare-proof.mjs +851 -0
  130. package/templates/workspace-scripts/ultramodern-performance-readiness.config.mjs +7 -0
  131. package/templates/workspace-scripts/ultramodern-performance-readiness.mjs +223 -0
  132. package/templates/workspace-scripts/validate-ultramodern-workspace.mjs.handlebars +593 -0
  133. package/dist/index.js +0 -2626
  134. package/dist/types/ultramodern-workspace.d.ts +0 -20
  135. package/template/.agents/skills-lock.json +0 -34
  136. package/template/.browserslistrc +0 -4
  137. package/template/.github/workflows/ultramodern-gates.yml.handlebars +0 -30
  138. package/template/.gitignore.handlebars +0 -30
  139. package/template/.nvmrc +0 -2
  140. package/template/AGENTS.md +0 -25
  141. package/template/README.md +0 -79
  142. package/template/api/effect/index.ts.handlebars +0 -23
  143. package/template/api/lambda/hello.ts.handlebars +0 -6
  144. package/template/config/public/locales/cs/translation.json +0 -39
  145. package/template/config/public/locales/en/translation.json +0 -39
  146. package/template/modern.config.ts.handlebars +0 -53
  147. package/template/oxfmt.config.ts +0 -8
  148. package/template/oxlint.config.ts +0 -12
  149. package/template/package.json.handlebars +0 -67
  150. package/template/postcss.config.mjs.handlebars +0 -6
  151. package/template/scripts/bootstrap-agent-skills.mjs +0 -95
  152. package/template/scripts/check-i18n-strings.mjs +0 -83
  153. package/template/scripts/validate-ultramodern.mjs.handlebars +0 -178
  154. package/template/shared/effect/api.ts.handlebars +0 -17
  155. package/template/src/modern-app-env.d.ts +0 -1
  156. package/template/src/modern.runtime.ts.handlebars +0 -23
  157. package/template/src/routes/index.css.handlebars +0 -129
  158. package/template/src/routes/layout.tsx.handlebars +0 -9
  159. package/template/src/routes/page.tsx.handlebars +0 -155
  160. package/template/tailwind.config.ts.handlebars +0 -10
  161. package/template/tsconfig.json +0 -120
  162. package/template-workspace/AGENTS.md +0 -50
  163. package/template-workspace/pnpm-workspace.yaml +0 -17
  164. package/template-workspace/scripts/check-i18n-strings.mjs +0 -83
  165. package/template-workspace/scripts/validate-ultramodern-workspace.mjs.handlebars +0 -433
@@ -0,0 +1,121 @@
1
+ import node_fs from "node:fs";
2
+ import { createAppEnvDts, createAppRuntimeConfig, createAppStyles, createPostcssConfig, createSharedDesignTokensCss, createShellFrameComponent, createTailwindConfig } from "./app-files.js";
3
+ import { createDevelopmentOverlay, createGeneratedContract, createOwnership, createPackageSourceMetadata, createTemplateManifest, createTopology } from "./contracts.js";
4
+ import { createLayout, createRemoteEntry, createRemoteExposeComponent, createRemotePage, createShellPage, createShellRemoteComponents, remoteComponentOutputPath } from "./demo-components.js";
5
+ import { GENERATED_CONTRACT_PATH, appHasEffectApi, appI18nNamespace, createShellHost, sharedPackages, shellApp } from "./descriptors.js";
6
+ import { createEffectClient, createEffectServiceEntry, createEffectSharedApi, createShellEffectClient } from "./effect-api.js";
7
+ import { copyRootTemplate, writeFile, writeJson } from "./fs-io.js";
8
+ import { createAppPublicLocaleMessages } from "./locales.js";
9
+ import { createAppModernConfig, createRemoteModuleFederationConfig, createShellModuleFederationConfig, createUltramodernBuildModule } from "./module-federation.js";
10
+ import { assertUniqueTailwindPrefixes, relativeRootFor, toPackageScope } from "./naming.js";
11
+ import { createAppPackage, createPackageTsConfig, createRootPackageJson, createSharedContractsIndex, createSharedPackage, createTsConfigBase } from "./package-json.js";
12
+ import { resolvePackageSource } from "./package-source.js";
13
+ import { createPublicWebAppArtifacts } from "./public-surface.js";
14
+ import { NODE_FETCH_VERSION, NODE_VERSION, PNPM_VERSION, TANSTACK_ROUTER_VERSION } from "./versions.js";
15
+ import { writeGeneratedWorkspaceScripts } from "./workspace-scripts.js";
16
+ function writeApp(targetDir, scope, app, packageSource, enableTailwind, remotes = []) {
17
+ const resolvedApp = 'shell' === app.kind ? createShellHost(remotes) : app;
18
+ const publicWeb = createPublicWebAppArtifacts(resolvedApp);
19
+ const writeAppFile = (relativePath, content)=>{
20
+ writeFile(targetDir, `${resolvedApp.directory}/${relativePath}`, content);
21
+ };
22
+ writeJson(targetDir, `${resolvedApp.directory}/package.json`, createAppPackage(scope, resolvedApp, packageSource, enableTailwind, remotes));
23
+ writeJson(targetDir, `${resolvedApp.directory}/tsconfig.json`, createPackageTsConfig(resolvedApp.directory, appHasEffectApi(resolvedApp)));
24
+ writeFile(targetDir, `${resolvedApp.directory}/src/modern-app-env.d.ts`, createAppEnvDts(resolvedApp, remotes));
25
+ writeFile(targetDir, `${resolvedApp.directory}/src/ultramodern-build.ts`, createUltramodernBuildModule(scope, resolvedApp));
26
+ writeFile(targetDir, publicWeb.jsonLdHelperFile.path, publicWeb.jsonLdHelperFile.content);
27
+ writeFile(targetDir, publicWeb.routeMetadataFile.path, publicWeb.routeMetadataFile.content);
28
+ writeFile(targetDir, publicWeb.routeHeadFile.path, publicWeb.routeHeadFile.content);
29
+ writeFile(targetDir, `${resolvedApp.directory}/modern.config.ts`, createAppModernConfig(scope, resolvedApp));
30
+ writeFile(targetDir, `${resolvedApp.directory}/src/modern.runtime.ts`, createAppRuntimeConfig(resolvedApp, scope, remotes));
31
+ writeJson(targetDir, `${resolvedApp.directory}/locales/en/translation.json`, createAppPublicLocaleMessages(resolvedApp, 'en', remotes));
32
+ writeJson(targetDir, `${resolvedApp.directory}/locales/en/${appI18nNamespace(resolvedApp)}.json`, createAppPublicLocaleMessages(resolvedApp, 'en', remotes));
33
+ writeJson(targetDir, `${resolvedApp.directory}/locales/cs/translation.json`, createAppPublicLocaleMessages(resolvedApp, 'cs', remotes));
34
+ writeJson(targetDir, `${resolvedApp.directory}/locales/cs/${appI18nNamespace(resolvedApp)}.json`, createAppPublicLocaleMessages(resolvedApp, 'cs', remotes));
35
+ writeFile(targetDir, `${resolvedApp.directory}/src/routes/index.css`, createAppStyles(enableTailwind, scope, resolvedApp));
36
+ if (enableTailwind) {
37
+ writeFile(targetDir, `${resolvedApp.directory}/postcss.config.mjs`, createPostcssConfig());
38
+ writeFile(targetDir, `${resolvedApp.directory}/tailwind.config.ts`, createTailwindConfig());
39
+ }
40
+ writeFile(targetDir, `${resolvedApp.directory}/module-federation.config.ts`, 'shell' === resolvedApp.kind ? createShellModuleFederationConfig(scope, remotes) : createRemoteModuleFederationConfig(scope, resolvedApp, remotes));
41
+ writeAppFile('src/routes/layout.tsx', createLayout(resolvedApp.id));
42
+ writeAppFile('src/routes/[lang]/page.tsx', 'shell' === resolvedApp.kind ? createShellPage(remotes) : createRemotePage(resolvedApp));
43
+ for (const generatedFile of publicWeb.routeMetaFiles)writeFile(targetDir, generatedFile.path, generatedFile.content);
44
+ for (const generatedFile of publicWeb.routeAliasFiles)writeFile(targetDir, generatedFile.path, generatedFile.content);
45
+ if ('shell' === resolvedApp.kind) {
46
+ writeAppFile('src/routes/vertical-components.tsx', createShellRemoteComponents(scope, remotes));
47
+ writeAppFile('src/routes/shell-frame.tsx', createShellFrameComponent());
48
+ writeFile(targetDir, `${resolvedApp.directory}/src/effect/vertical-clients.ts`, createShellEffectClient(scope, remotes));
49
+ }
50
+ if (appHasEffectApi(resolvedApp)) {
51
+ writeFile(targetDir, `${resolvedApp.directory}/shared/effect/api.ts`, createEffectSharedApi(resolvedApp));
52
+ writeFile(targetDir, `${resolvedApp.directory}/api/effect/index.ts`, createEffectServiceEntry(resolvedApp, '../../shared/effect/api.ts'));
53
+ writeFile(targetDir, `${resolvedApp.directory}/src/effect/${resolvedApp.effectApi.stem}-client.ts`, createEffectClient(resolvedApp, '../../shared/effect/api'));
54
+ }
55
+ if ('vertical' === resolvedApp.kind) {
56
+ writeAppFile('src/federation-entry.tsx', createRemoteEntry(resolvedApp));
57
+ for (const expose of Object.keys(resolvedApp.exposes ?? {})){
58
+ const outputPath = remoteComponentOutputPath(resolvedApp, expose);
59
+ if (outputPath) writeAppFile(outputPath.slice(resolvedApp.directory.length + 1), createRemoteExposeComponent(resolvedApp, expose));
60
+ }
61
+ }
62
+ }
63
+ function writeSharedPackages(targetDir, scope) {
64
+ for (const sharedPackage of sharedPackages){
65
+ writeJson(targetDir, `${sharedPackage.directory}/package.json`, createSharedPackage(scope, sharedPackage.id, sharedPackage.description));
66
+ writeJson(targetDir, `${sharedPackage.directory}/tsconfig.json`, {
67
+ extends: `${relativeRootFor(sharedPackage.directory)}/tsconfig.base.json`,
68
+ include: [
69
+ 'src'
70
+ ]
71
+ });
72
+ }
73
+ writeFile(targetDir, 'packages/shared-contracts/src/index.ts', createSharedContractsIndex());
74
+ writeFile(targetDir, 'packages/shared-design-tokens/src/index.ts', `export const sharedDesignTokens = {
75
+ color: {
76
+ accent: '#2f8f68',
77
+ foreground: '#133225',
78
+ surface: '#f6fbf7',
79
+ },
80
+ } as const;
81
+ `);
82
+ writeFile(targetDir, 'packages/shared-design-tokens/src/tokens.css', createSharedDesignTokensCss());
83
+ }
84
+ function generateUltramodernWorkspace(options) {
85
+ const scope = toPackageScope(options.packageName);
86
+ const packageSource = resolvePackageSource(options);
87
+ const enableTailwind = false !== options.enableTailwind;
88
+ const initialVerticals = [];
89
+ assertUniqueTailwindPrefixes([
90
+ shellApp,
91
+ ...initialVerticals
92
+ ]);
93
+ node_fs.mkdirSync(options.targetDir, {
94
+ recursive: true
95
+ });
96
+ copyRootTemplate(options.targetDir, {
97
+ packageName: options.packageName,
98
+ packageScope: scope,
99
+ nodeVersion: NODE_VERSION,
100
+ pnpmVersion: PNPM_VERSION,
101
+ nodeFetchVersion: NODE_FETCH_VERSION,
102
+ tanstackRouterVersion: TANSTACK_ROUTER_VERSION,
103
+ tailwindEnabled: String(enableTailwind)
104
+ });
105
+ writeJson(options.targetDir, 'package.json', createRootPackageJson(scope, packageSource, initialVerticals));
106
+ writeJson(options.targetDir, 'tsconfig.base.json', createTsConfigBase());
107
+ writeJson(options.targetDir, 'topology/reference-topology.json', createTopology(scope, initialVerticals));
108
+ writeJson(options.targetDir, 'topology/ownership.json', createOwnership(scope, initialVerticals));
109
+ writeJson(options.targetDir, 'topology/local-overlays/development.json', createDevelopmentOverlay(initialVerticals));
110
+ writeJson(options.targetDir, '.modernjs/ultramodern-workspace-template-manifest.json', createTemplateManifest(options.modernVersion, packageSource));
111
+ writeJson(options.targetDir, '.modernjs/ultramodern-package-source.json', createPackageSourceMetadata(scope, packageSource));
112
+ writeJson(options.targetDir, GENERATED_CONTRACT_PATH, createGeneratedContract(scope, [
113
+ createShellHost(initialVerticals),
114
+ ...initialVerticals
115
+ ], enableTailwind));
116
+ writeApp(options.targetDir, scope, shellApp, packageSource, enableTailwind, initialVerticals);
117
+ for (const remote of initialVerticals)writeApp(options.targetDir, scope, remote, packageSource, enableTailwind, initialVerticals);
118
+ writeSharedPackages(options.targetDir, scope);
119
+ writeGeneratedWorkspaceScripts(options.targetDir, scope, enableTailwind, initialVerticals);
120
+ }
121
+ export { generateUltramodernWorkspace, writeApp, writeSharedPackages };
@@ -0,0 +1,15 @@
1
+ import "node:module";
2
+ import node_fs from "node:fs";
3
+ import node_path from "node:path";
4
+ const MAX_WALK_UP_LEVELS = 5;
5
+ function resolveCreatePackageRoot(fromDir) {
6
+ let candidate = fromDir;
7
+ for(let level = 0; level <= MAX_WALK_UP_LEVELS; level++){
8
+ if (node_fs.existsSync(node_path.join(candidate, 'package.json')) && node_fs.existsSync(node_path.join(candidate, 'template-workspace'))) return candidate;
9
+ const parent = node_path.dirname(candidate);
10
+ if (parent === candidate) break;
11
+ candidate = parent;
12
+ }
13
+ throw new Error(`Unable to resolve the @modern-js/create package root (a directory containing both package.json and template-workspace/) within ${MAX_WALK_UP_LEVELS} levels above ${fromDir}`);
14
+ }
15
+ export { resolveCreatePackageRoot };
@@ -0,0 +1,492 @@
1
+ import "node:module";
2
+ import { execFileSync } from "node:child_process";
3
+ import node_fs from "node:fs";
4
+ import node_path from "node:path";
5
+ import node_readline from "node:readline";
6
+ import { fileURLToPath } from "node:url";
7
+ import { resolveCreatePackageRoot } from "./create-package-root.js";
8
+ import { i18n, localeKeys } from "./locale/index.js";
9
+ import { BLEEDINGDEV_CREATE_PACKAGE, BLEEDINGDEV_FRAMEWORK_VERSION_ENV, BLEEDINGDEV_PACKAGE_NAME_PREFIX, BLEEDINGDEV_PACKAGE_SCOPE, WORKSPACE_PACKAGE_VERSION } from "./ultramodern-package-source.js";
10
+ import { addUltramodernVertical, generateUltramodernWorkspace } from "./ultramodern-workspace/index.js";
11
+ const src_dirname = node_path.dirname(fileURLToPath(import.meta.url));
12
+ const createPackageRoot = resolveCreatePackageRoot(src_dirname);
13
+ const semverPattern = /^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/;
14
+ const LEGACY_MODERN_JS_FLAG = '--legacy-modern-js';
15
+ const LEGACY_MODERN_JS_CONFIRMATION = 'USE LEGACY MODERN.JS';
16
+ const WORKSPACE_PROTOCOL_FLAG = '--workspace';
17
+ const BFF_FLAG = '--bff';
18
+ const BFF_RUNTIME_OPTION = '--bff-runtime';
19
+ const SUPPORTED_BFF_RUNTIMES = [
20
+ 'effect'
21
+ ];
22
+ const REGISTRY_LOOKUP_TIMEOUT_MS = 15000;
23
+ function getOptionValue(args, names) {
24
+ for (const name of names){
25
+ const prefix = `${name}=`;
26
+ const byEquals = args.find((arg)=>arg.startsWith(prefix));
27
+ if (byEquals) return byEquals.slice(prefix.length);
28
+ const index = args.findIndex((arg)=>arg === name);
29
+ if (-1 !== index && args[index + 1] && !args[index + 1].startsWith('-')) return args[index + 1];
30
+ }
31
+ }
32
+ const detectLanguage = ()=>{
33
+ const lang = getOptionValue(process.argv.slice(2), [
34
+ '--lang',
35
+ '-l'
36
+ ]);
37
+ if ('zh' === lang) return 'zh';
38
+ return 'en';
39
+ };
40
+ i18n.changeLanguage({
41
+ locale: detectLanguage()
42
+ });
43
+ function readCreatePackageJson() {
44
+ const createPackageJson = node_path.join(createPackageRoot, 'package.json');
45
+ return JSON.parse(node_fs.readFileSync(createPackageJson, 'utf-8'));
46
+ }
47
+ function isBleedingDevCreatePackage(createPackage) {
48
+ return createPackage.name === BLEEDINGDEV_CREATE_PACKAGE;
49
+ }
50
+ function getBleedingDevFrameworkVersion(createPackage, fallbackVersion) {
51
+ const frameworkVersion = createPackage.ultramodern?.frameworkVersion;
52
+ return 'string' == typeof frameworkVersion && frameworkVersion.length > 0 ? frameworkVersion : fallbackVersion;
53
+ }
54
+ function showVersion() {
55
+ const createPackage = readCreatePackageJson();
56
+ const name = createPackage.name || '@modern-js/create';
57
+ const version = createPackage.version || 'unknown';
58
+ console.log(i18n.t(localeKeys.version.message, {
59
+ name,
60
+ version
61
+ }));
62
+ process.exit(0);
63
+ }
64
+ function showHelp() {
65
+ console.log(i18n.t(localeKeys.help.title));
66
+ console.log(i18n.t(localeKeys.help.description));
67
+ console.log('');
68
+ console.log(i18n.t(localeKeys.help.usage));
69
+ console.log(i18n.t(localeKeys.help.usageExample));
70
+ console.log('');
71
+ console.log(i18n.t(localeKeys.help.options));
72
+ console.log(i18n.t(localeKeys.help.optionHelp));
73
+ console.log(i18n.t(localeKeys.help.optionVersion));
74
+ console.log(i18n.t(localeKeys.help.optionLang));
75
+ console.log(i18n.t(localeKeys.help.optionTailwind));
76
+ console.log(i18n.t(localeKeys.help.optionBff));
77
+ console.log(i18n.t(localeKeys.help.optionBffRuntime));
78
+ console.log(i18n.t(localeKeys.help.optionWorkspace));
79
+ console.log(i18n.t(localeKeys.help.optionUltramodernPackageSource));
80
+ console.log(i18n.t(localeKeys.help.optionUltramodernPackageVersion));
81
+ console.log(i18n.t(localeKeys.help.optionUltramodernPackageRegistry));
82
+ console.log(i18n.t(localeKeys.help.optionUltramodernPackageScope));
83
+ console.log(i18n.t(localeKeys.help.optionUltramodernPackageNamePrefix));
84
+ console.log(i18n.t(localeKeys.help.optionVertical));
85
+ console.log(i18n.t(localeKeys.help.optionLegacyModernJs));
86
+ console.log('');
87
+ console.log(i18n.t(localeKeys.help.examples));
88
+ console.log(i18n.t(localeKeys.help.example1));
89
+ console.log(i18n.t(localeKeys.help.example2));
90
+ console.log(i18n.t(localeKeys.help.example3));
91
+ console.log(i18n.t(localeKeys.help.example4));
92
+ console.log(i18n.t(localeKeys.help.example5));
93
+ console.log(i18n.t(localeKeys.help.example6));
94
+ console.log(i18n.t(localeKeys.help.example7));
95
+ console.log('');
96
+ console.log(i18n.t(localeKeys.help.moreInfo));
97
+ console.log('');
98
+ process.exit(0);
99
+ }
100
+ function promptInput(question) {
101
+ const rl = node_readline.createInterface({
102
+ input: process.stdin,
103
+ output: process.stdout
104
+ });
105
+ return new Promise((resolve)=>{
106
+ rl.question(question, (answer)=>{
107
+ rl.close();
108
+ resolve(answer.trim());
109
+ });
110
+ });
111
+ }
112
+ function detectLegacyModernJsFlag(args) {
113
+ if (args.some((arg)=>arg.startsWith(`${LEGACY_MODERN_JS_FLAG}=`))) {
114
+ console.error(`${LEGACY_MODERN_JS_FLAG} does not accept a value.`);
115
+ process.exit(1);
116
+ }
117
+ return args.includes(LEGACY_MODERN_JS_FLAG);
118
+ }
119
+ function stripLegacyModernJsArgs(args) {
120
+ return args.filter((arg)=>arg !== LEGACY_MODERN_JS_FLAG);
121
+ }
122
+ async function confirmLegacyModernJsSetup() {
123
+ console.error('');
124
+ console.error(i18n.t(localeKeys.message.legacyModernJsWarning));
125
+ console.error('');
126
+ const answer = await promptInput(i18n.t(localeKeys.prompt.legacyModernJsConfirmation, {
127
+ confirmation: LEGACY_MODERN_JS_CONFIRMATION
128
+ }));
129
+ if (answer !== LEGACY_MODERN_JS_CONFIRMATION) {
130
+ console.error(i18n.t(localeKeys.error.legacyModernJsNotConfirmed));
131
+ process.exit(1);
132
+ }
133
+ }
134
+ function delegateLegacyModernJsSetup(args) {
135
+ const forwardedArgs = stripLegacyModernJsArgs(args);
136
+ if (commandExists('pnpm')) return void runSetupCommand('pnpm', [
137
+ 'dlx',
138
+ '@modern-js/create',
139
+ ...forwardedArgs
140
+ ], {
141
+ stdio: 'inherit'
142
+ });
143
+ if (commandExists('npx')) return void runSetupCommand('npx', [
144
+ '@modern-js/create',
145
+ ...forwardedArgs
146
+ ], {
147
+ stdio: 'inherit'
148
+ });
149
+ throw new Error('Legacy Modern.js setup requires pnpm or npx to run @modern-js/create.');
150
+ }
151
+ function detectBffRuntime(args) {
152
+ if (args.some((arg)=>arg.startsWith(`${BFF_FLAG}=`))) {
153
+ console.error(`${BFF_FLAG} does not accept a value. Use: ${BFF_RUNTIME_OPTION} <runtime>`);
154
+ process.exit(1);
155
+ }
156
+ const runtimeRequested = args.some((arg)=>arg === BFF_RUNTIME_OPTION || arg.startsWith(`${BFF_RUNTIME_OPTION}=`));
157
+ if (!runtimeRequested) return 'effect';
158
+ const runtime = getOptionValue(args, [
159
+ BFF_RUNTIME_OPTION
160
+ ]);
161
+ if (!runtime) {
162
+ console.error(`${BFF_RUNTIME_OPTION} requires a value (supported: ${SUPPORTED_BFF_RUNTIMES.join(', ')})`);
163
+ process.exit(1);
164
+ }
165
+ if (!SUPPORTED_BFF_RUNTIMES.includes(runtime)) {
166
+ console.error(`Unsupported BFF runtime "${runtime}". UltraModern workspaces scaffold an Effect BFF for every MicroVertical (supported: ${SUPPORTED_BFF_RUNTIMES.join(', ')}).`);
167
+ process.exit(1);
168
+ }
169
+ return runtime;
170
+ }
171
+ function detectTailwindFlag() {
172
+ const args = process.argv.slice(2);
173
+ return !args.includes('--no-tailwind');
174
+ }
175
+ function detectExplicitTailwindFlag() {
176
+ const args = process.argv.slice(2);
177
+ if (args.includes('--no-tailwind')) return false;
178
+ if (args.includes('--tailwind')) return true;
179
+ }
180
+ function detectVerticalFlag() {
181
+ const args = process.argv.slice(2);
182
+ if (args.some((arg)=>arg.startsWith('--vertical='))) {
183
+ console.error('--vertical does not accept a value. Use: create <name> --vertical');
184
+ process.exit(1);
185
+ }
186
+ return args.includes('--vertical');
187
+ }
188
+ function detectUltramodernPackageSource(args, defaultPackageVersion, createPackage) {
189
+ const bleedingDevDefaults = isBleedingDevCreatePackage(createPackage);
190
+ const strategy = getOptionValue(args, [
191
+ '--ultramodern-package-source'
192
+ ]) ?? (bleedingDevDefaults ? 'install' : 'workspace');
193
+ if ('workspace' !== strategy && 'install' !== strategy) {
194
+ console.error('--ultramodern-package-source must be "workspace" or "install"');
195
+ process.exit(1);
196
+ }
197
+ const packageSourceStrategy = strategy;
198
+ const explicitRegistry = getOptionValue(args, [
199
+ '--ultramodern-package-registry'
200
+ ]);
201
+ const aliasScope = getOptionValue(args, [
202
+ '--ultramodern-package-scope'
203
+ ]) ?? (bleedingDevDefaults && 'install' === packageSourceStrategy && !explicitRegistry ? BLEEDINGDEV_PACKAGE_SCOPE : void 0);
204
+ return {
205
+ strategy: packageSourceStrategy,
206
+ modernPackageVersion: getOptionValue(args, [
207
+ '--ultramodern-package-version'
208
+ ]) ?? defaultPackageVersion,
209
+ registry: explicitRegistry,
210
+ aliasScope,
211
+ aliasPackageNamePrefix: getOptionValue(args, [
212
+ '--ultramodern-package-name-prefix'
213
+ ]) ?? (aliasScope ? BLEEDINGDEV_PACKAGE_NAME_PREFIX : void 0)
214
+ };
215
+ }
216
+ function hasExplicitUltramodernPackageSource(args, value) {
217
+ const configuredValue = getOptionValue(args, [
218
+ '--ultramodern-package-source'
219
+ ]);
220
+ return value ? configuredValue === value : void 0 !== configuredValue;
221
+ }
222
+ function readBleedingDevFrameworkVersionFromRegistry(fallbackVersion) {
223
+ const envVersion = process.env[BLEEDINGDEV_FRAMEWORK_VERSION_ENV]?.trim();
224
+ if (envVersion) {
225
+ if (!semverPattern.test(envVersion)) {
226
+ console.error(`${BLEEDINGDEV_FRAMEWORK_VERSION_ENV} must be a valid semver version`);
227
+ process.exit(1);
228
+ }
229
+ return envVersion;
230
+ }
231
+ try {
232
+ const rawVersion = runSetupCommand('npm', [
233
+ 'view',
234
+ `${BLEEDINGDEV_CREATE_PACKAGE}@latest`,
235
+ 'ultramodern.frameworkVersion',
236
+ '--json'
237
+ ], {
238
+ timeoutMs: REGISTRY_LOOKUP_TIMEOUT_MS
239
+ }).trim();
240
+ const version = JSON.parse(rawVersion);
241
+ if ('string' == typeof version && semverPattern.test(version)) return version;
242
+ } catch {}
243
+ console.warn([
244
+ `Could not resolve ${BLEEDINGDEV_CREATE_PACKAGE}@latest ultramodern.frameworkVersion from the npm registry.`,
245
+ `Falling back to the packaged framework version ${fallbackVersion}.`,
246
+ `Pass ${WORKSPACE_PROTOCOL_FLAG} to use local workspace protocol dependencies,`,
247
+ 'or pass --ultramodern-package-version with the exact BleedingDev framework cohort.'
248
+ ].join(' '));
249
+ return fallbackVersion;
250
+ }
251
+ function resolveInstallBackedPackageSource(args, createPackage, packageSource) {
252
+ const explicitVersion = getOptionValue(args, [
253
+ '--ultramodern-package-version'
254
+ ]);
255
+ const explicitRegistry = getOptionValue(args, [
256
+ '--ultramodern-package-registry'
257
+ ]);
258
+ const aliasScope = getOptionValue(args, [
259
+ '--ultramodern-package-scope'
260
+ ]) ?? packageSource.aliasScope ?? (explicitRegistry ? void 0 : BLEEDINGDEV_PACKAGE_SCOPE);
261
+ return {
262
+ ...packageSource,
263
+ strategy: 'install',
264
+ modernPackageVersion: explicitVersion ?? (isBleedingDevCreatePackage(createPackage) ? packageSource.modernPackageVersion : readBleedingDevFrameworkVersionFromRegistry(packageSource.modernPackageVersion)),
265
+ aliasScope,
266
+ aliasPackageNamePrefix: getOptionValue(args, [
267
+ '--ultramodern-package-name-prefix'
268
+ ]) ?? packageSource.aliasPackageNamePrefix ?? (aliasScope ? BLEEDINGDEV_PACKAGE_NAME_PREFIX : void 0)
269
+ };
270
+ }
271
+ function resolveWorkspacePackageSource(args, createPackage, packageSource) {
272
+ const workspaceProtocolRequested = args.includes(WORKSPACE_PROTOCOL_FLAG);
273
+ if (workspaceProtocolRequested && hasExplicitUltramodernPackageSource(args, 'install')) {
274
+ console.error(`${WORKSPACE_PROTOCOL_FLAG} conflicts with --ultramodern-package-source=install`);
275
+ process.exit(1);
276
+ }
277
+ if (workspaceProtocolRequested || hasExplicitUltramodernPackageSource(args, 'workspace')) return {
278
+ ...packageSource,
279
+ strategy: 'workspace',
280
+ modernPackageVersion: WORKSPACE_PACKAGE_VERSION
281
+ };
282
+ return resolveInstallBackedPackageSource(args, createPackage, packageSource);
283
+ }
284
+ function runSetupCommand(command, args, options = {}) {
285
+ return execFileSync(command, args, {
286
+ cwd: options.cwd,
287
+ encoding: 'utf-8',
288
+ stdio: options.stdio ?? [
289
+ 'ignore',
290
+ 'pipe',
291
+ 'pipe'
292
+ ],
293
+ timeout: options.timeoutMs
294
+ });
295
+ }
296
+ function commandExists(command) {
297
+ try {
298
+ runSetupCommand(command, [
299
+ '--version'
300
+ ], {
301
+ stdio: 'ignore'
302
+ });
303
+ return true;
304
+ } catch {
305
+ return false;
306
+ }
307
+ }
308
+ function assertGitAvailableForGeneratedProject() {
309
+ if (commandExists('git')) return;
310
+ throw new Error('Git is required for UltraModern setup. Install git yourself (for example "brew install git" or "sudo apt-get install git") and rerun create. This tool never installs system packages on your behalf.');
311
+ }
312
+ function isInsideGitWorkTree(targetDir) {
313
+ try {
314
+ return 'true' === runSetupCommand('git', [
315
+ 'rev-parse',
316
+ '--is-inside-work-tree'
317
+ ], {
318
+ cwd: targetDir
319
+ }).trim();
320
+ } catch {
321
+ return false;
322
+ }
323
+ }
324
+ function initializeGeneratedGitRepository(targetDir) {
325
+ assertGitAvailableForGeneratedProject();
326
+ if (isInsideGitWorkTree(targetDir)) return;
327
+ try {
328
+ runSetupCommand('git', [
329
+ 'init',
330
+ '-b',
331
+ 'main'
332
+ ], {
333
+ cwd: targetDir,
334
+ stdio: 'inherit'
335
+ });
336
+ } catch {
337
+ runSetupCommand('git', [
338
+ 'init'
339
+ ], {
340
+ cwd: targetDir,
341
+ stdio: 'inherit'
342
+ });
343
+ runSetupCommand('git', [
344
+ 'branch',
345
+ '-M',
346
+ 'main'
347
+ ], {
348
+ cwd: targetDir,
349
+ stdio: 'inherit'
350
+ });
351
+ }
352
+ }
353
+ function isDirectoryEmpty(dirPath) {
354
+ if (!node_fs.existsSync(dirPath)) return false;
355
+ try {
356
+ const files = node_fs.readdirSync(dirPath);
357
+ return 0 === files.length;
358
+ } catch {
359
+ return false;
360
+ }
361
+ }
362
+ async function getProjectName() {
363
+ const args = process.argv.slice(2);
364
+ const optionWithValue = new Set([
365
+ '--lang',
366
+ '-l',
367
+ BFF_RUNTIME_OPTION,
368
+ '--ultramodern-package-source',
369
+ '--ultramodern-package-version',
370
+ '--ultramodern-package-registry',
371
+ '--ultramodern-package-scope',
372
+ '--ultramodern-package-name-prefix'
373
+ ]);
374
+ const optionWithoutValue = new Set([
375
+ '--help',
376
+ '-h',
377
+ '--version',
378
+ '-v',
379
+ '--tailwind',
380
+ '--no-tailwind',
381
+ BFF_FLAG,
382
+ WORKSPACE_PROTOCOL_FLAG,
383
+ '--vertical',
384
+ LEGACY_MODERN_JS_FLAG
385
+ ]);
386
+ const positionalArgs = [];
387
+ for(let i = 0; i < args.length; i++){
388
+ const arg = args[i];
389
+ if (!optionWithoutValue.has(arg)) {
390
+ if (optionWithValue.has(arg)) {
391
+ i += 1;
392
+ continue;
393
+ }
394
+ if (!(arg.startsWith('--lang=') || arg.startsWith(`${BFF_RUNTIME_OPTION}=`) || arg.startsWith('--ultramodern-package-source=') || arg.startsWith('--ultramodern-package-version=') || arg.startsWith('--ultramodern-package-registry=') || arg.startsWith('--ultramodern-package-scope=') || arg.startsWith('--ultramodern-package-name-prefix='))) positionalArgs.push(arg);
395
+ }
396
+ }
397
+ if (positionalArgs.length > 1) {
398
+ console.error(`Unexpected positional argument: ${positionalArgs[1]}`);
399
+ process.exit(1);
400
+ }
401
+ const projectNameArg = positionalArgs[0];
402
+ if (projectNameArg) {
403
+ if ('.' === projectNameArg) return {
404
+ name: node_path.basename(process.cwd()),
405
+ useCurrentDir: true
406
+ };
407
+ return {
408
+ name: projectNameArg,
409
+ useCurrentDir: false
410
+ };
411
+ }
412
+ const currentDir = process.cwd();
413
+ if (isDirectoryEmpty(currentDir)) return {
414
+ name: node_path.basename(currentDir),
415
+ useCurrentDir: true
416
+ };
417
+ const projectName = await promptInput(i18n.t(localeKeys.prompt.projectName));
418
+ if (!projectName) {
419
+ console.error(i18n.t(localeKeys.error.projectNameEmpty));
420
+ process.exit(1);
421
+ }
422
+ return {
423
+ name: projectName,
424
+ useCurrentDir: false
425
+ };
426
+ }
427
+ async function main() {
428
+ const args = process.argv.slice(2);
429
+ if (args.includes('--help') || args.includes('-h')) return void showHelp();
430
+ if (args.includes('--version') || args.includes('-v')) return void showVersion();
431
+ if (detectLegacyModernJsFlag(args)) {
432
+ await confirmLegacyModernJsSetup();
433
+ delegateLegacyModernJsSetup(args);
434
+ return;
435
+ }
436
+ detectBffRuntime(args);
437
+ console.log(`\n${i18n.t(localeKeys.message.welcome)}\n`);
438
+ const { name: projectName, useCurrentDir } = await getProjectName();
439
+ const targetDir = useCurrentDir ? process.cwd() : node_path.isAbsolute(projectName) ? projectName : node_path.resolve(process.cwd(), projectName);
440
+ const generatedPackageName = useCurrentDir || node_path.isAbsolute(projectName) ? node_path.basename(targetDir) : projectName;
441
+ const createPackage = readCreatePackageJson();
442
+ const version = createPackage.version || 'latest';
443
+ const ultramodernPackageVersion = isBleedingDevCreatePackage(createPackage) ? getBleedingDevFrameworkVersion(createPackage, version) : version;
444
+ const addVertical = detectVerticalFlag();
445
+ if (addVertical) {
446
+ const overridePackageSource = args.some((arg)=>arg.startsWith('--ultramodern-package-')) ? detectUltramodernPackageSource(args, ultramodernPackageVersion, createPackage) : void 0;
447
+ addUltramodernVertical({
448
+ workspaceRoot: process.cwd(),
449
+ name: generatedPackageName,
450
+ modernVersion: version,
451
+ enableTailwind: detectExplicitTailwindFlag(),
452
+ packageSource: overridePackageSource
453
+ });
454
+ const dim = '\x1b[2m\x1b[3m';
455
+ const reset = '\x1b[0m';
456
+ console.log(`${i18n.t(localeKeys.message.success)}\n`);
457
+ console.log(`${dim} pnpm check${reset}\n`);
458
+ return;
459
+ }
460
+ if (node_fs.existsSync(targetDir)) {
461
+ const files = node_fs.readdirSync(targetDir);
462
+ if (files.length > 0) {
463
+ console.error(i18n.t(localeKeys.error.directoryExists, {
464
+ projectName
465
+ }));
466
+ process.exit(1);
467
+ }
468
+ }
469
+ const packageSource = resolveWorkspacePackageSource(args, createPackage, detectUltramodernPackageSource(args, ultramodernPackageVersion, createPackage));
470
+ generateUltramodernWorkspace({
471
+ targetDir,
472
+ packageName: generatedPackageName,
473
+ modernVersion: version,
474
+ enableTailwind: detectTailwindFlag(),
475
+ packageSource
476
+ });
477
+ initializeGeneratedGitRepository(targetDir);
478
+ const dim = '\x1b[2m\x1b[3m';
479
+ const reset = '\x1b[0m';
480
+ console.log(`${i18n.t(localeKeys.message.success)}\n`);
481
+ console.log(i18n.t(localeKeys.message.nextSteps));
482
+ if (!useCurrentDir) console.log(`${dim} ${i18n.t(localeKeys.message.step1, {
483
+ projectName
484
+ })}${reset}`);
485
+ console.log(`${dim} ${i18n.t(localeKeys.message.step2)}${reset}`);
486
+ console.log(`${dim} pnpm check${reset}`);
487
+ console.log(`${dim} ${i18n.t(localeKeys.message.step3)}${reset}\n`);
488
+ }
489
+ main().catch((error)=>{
490
+ console.error(i18n.t(localeKeys.error.createFailed), error);
491
+ process.exit(1);
492
+ });