@digitaldefiance/express-suite-starter 2.1.41

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 (214) hide show
  1. package/README.md +342 -0
  2. package/config/package-groups.json +83 -0
  3. package/config/presets/minimal.json +32 -0
  4. package/config/presets/standard.json +70 -0
  5. package/dist/scripts/addScriptsToPackageJson.d.ts +7 -0
  6. package/dist/scripts/addScriptsToPackageJson.d.ts.map +1 -0
  7. package/dist/scripts/addScriptsToPackageJson.js +69 -0
  8. package/dist/scripts/addScriptsToPackageJson.js.map +1 -0
  9. package/dist/scripts/albatross.d.ts +4 -0
  10. package/dist/scripts/albatross.d.ts.map +1 -0
  11. package/dist/scripts/albatross.js +36 -0
  12. package/dist/scripts/albatross.js.map +1 -0
  13. package/dist/scripts/fsUtils.d.ts +15 -0
  14. package/dist/scripts/fsUtils.d.ts.map +1 -0
  15. package/dist/scripts/fsUtils.js +99 -0
  16. package/dist/scripts/fsUtils.js.map +1 -0
  17. package/dist/scripts/generate-monorepo.d.ts +2 -0
  18. package/dist/scripts/generate-monorepo.d.ts.map +1 -0
  19. package/dist/scripts/generate-monorepo.js +227 -0
  20. package/dist/scripts/generate-monorepo.js.map +1 -0
  21. package/dist/scripts/licensePrompt.d.ts +5 -0
  22. package/dist/scripts/licensePrompt.d.ts.map +1 -0
  23. package/dist/scripts/licensePrompt.js +63 -0
  24. package/dist/scripts/licensePrompt.js.map +1 -0
  25. package/dist/scripts/monorepoConfig.d.ts +18 -0
  26. package/dist/scripts/monorepoConfig.d.ts.map +1 -0
  27. package/dist/scripts/monorepoConfig.js +83 -0
  28. package/dist/scripts/monorepoConfig.js.map +1 -0
  29. package/dist/scripts/nodeSetup.d.ts +5 -0
  30. package/dist/scripts/nodeSetup.d.ts.map +1 -0
  31. package/dist/scripts/nodeSetup.js +32 -0
  32. package/dist/scripts/nodeSetup.js.map +1 -0
  33. package/dist/scripts/passwordObfuscator.d.ts +14 -0
  34. package/dist/scripts/passwordObfuscator.d.ts.map +1 -0
  35. package/dist/scripts/passwordObfuscator.js +52 -0
  36. package/dist/scripts/passwordObfuscator.js.map +1 -0
  37. package/dist/scripts/shellUtils.d.ts +11 -0
  38. package/dist/scripts/shellUtils.d.ts.map +1 -0
  39. package/dist/scripts/shellUtils.js +28 -0
  40. package/dist/scripts/shellUtils.js.map +1 -0
  41. package/dist/scripts/templateUtils.d.ts +6 -0
  42. package/dist/scripts/templateUtils.d.ts.map +1 -0
  43. package/dist/scripts/templateUtils.js +15 -0
  44. package/dist/scripts/templateUtils.js.map +1 -0
  45. package/dist/src/cli/logger.d.ts +15 -0
  46. package/dist/src/cli/logger.d.ts.map +1 -0
  47. package/dist/src/cli/logger.js +48 -0
  48. package/dist/src/cli/logger.js.map +1 -0
  49. package/dist/src/cli.d.ts +6 -0
  50. package/dist/src/cli.d.ts.map +1 -0
  51. package/dist/src/cli.js +12 -0
  52. package/dist/src/cli.js.map +1 -0
  53. package/dist/src/core/config-schema.d.ts +3 -0
  54. package/dist/src/core/config-schema.d.ts.map +1 -0
  55. package/dist/src/core/config-schema.js +20 -0
  56. package/dist/src/core/config-schema.js.map +1 -0
  57. package/dist/src/core/dry-run-executor.d.ts +15 -0
  58. package/dist/src/core/dry-run-executor.d.ts.map +1 -0
  59. package/dist/src/core/dry-run-executor.js +86 -0
  60. package/dist/src/core/dry-run-executor.js.map +1 -0
  61. package/dist/src/core/interfaces/checkpoint.interface.d.ts +6 -0
  62. package/dist/src/core/interfaces/checkpoint.interface.d.ts.map +1 -0
  63. package/dist/src/core/interfaces/checkpoint.interface.js +3 -0
  64. package/dist/src/core/interfaces/checkpoint.interface.js.map +1 -0
  65. package/dist/src/core/interfaces/command-options.interface.d.ts +5 -0
  66. package/dist/src/core/interfaces/command-options.interface.d.ts.map +1 -0
  67. package/dist/src/core/interfaces/command-options.interface.js +3 -0
  68. package/dist/src/core/interfaces/command-options.interface.js.map +1 -0
  69. package/dist/src/core/interfaces/devcontainer-config.interface.d.ts +6 -0
  70. package/dist/src/core/interfaces/devcontainer-config.interface.d.ts.map +1 -0
  71. package/dist/src/core/interfaces/devcontainer-config.interface.js +3 -0
  72. package/dist/src/core/interfaces/devcontainer-config.interface.js.map +1 -0
  73. package/dist/src/core/interfaces/dry-run.interface.d.ts +16 -0
  74. package/dist/src/core/interfaces/dry-run.interface.d.ts.map +1 -0
  75. package/dist/src/core/interfaces/dry-run.interface.js +3 -0
  76. package/dist/src/core/interfaces/dry-run.interface.js.map +1 -0
  77. package/dist/src/core/interfaces/generator-config.interface.d.ts +17 -0
  78. package/dist/src/core/interfaces/generator-config.interface.d.ts.map +1 -0
  79. package/dist/src/core/interfaces/generator-config.interface.js +3 -0
  80. package/dist/src/core/interfaces/generator-config.interface.js.map +1 -0
  81. package/dist/src/core/interfaces/generator-context.interface.d.ts +6 -0
  82. package/dist/src/core/interfaces/generator-context.interface.d.ts.map +1 -0
  83. package/dist/src/core/interfaces/generator-context.interface.js +3 -0
  84. package/dist/src/core/interfaces/generator-context.interface.js.map +1 -0
  85. package/dist/src/core/interfaces/index.d.ts +16 -0
  86. package/dist/src/core/interfaces/index.d.ts.map +1 -0
  87. package/dist/src/core/interfaces/index.js +32 -0
  88. package/dist/src/core/interfaces/index.js.map +1 -0
  89. package/dist/src/core/interfaces/node-config.interface.d.ts +5 -0
  90. package/dist/src/core/interfaces/node-config.interface.d.ts.map +1 -0
  91. package/dist/src/core/interfaces/node-config.interface.js +3 -0
  92. package/dist/src/core/interfaces/node-config.interface.js.map +1 -0
  93. package/dist/src/core/interfaces/nx-config.interface.d.ts +9 -0
  94. package/dist/src/core/interfaces/nx-config.interface.d.ts.map +1 -0
  95. package/dist/src/core/interfaces/nx-config.interface.js +3 -0
  96. package/dist/src/core/interfaces/nx-config.interface.js.map +1 -0
  97. package/dist/src/core/interfaces/package-config.interface.d.ts +6 -0
  98. package/dist/src/core/interfaces/package-config.interface.d.ts.map +1 -0
  99. package/dist/src/core/interfaces/package-config.interface.js +3 -0
  100. package/dist/src/core/interfaces/package-config.interface.js.map +1 -0
  101. package/dist/src/core/interfaces/package-resolution.interface.d.ts +21 -0
  102. package/dist/src/core/interfaces/package-resolution.interface.d.ts.map +1 -0
  103. package/dist/src/core/interfaces/package-resolution.interface.js +3 -0
  104. package/dist/src/core/interfaces/package-resolution.interface.js.map +1 -0
  105. package/dist/src/core/interfaces/plugin.interface.d.ts +21 -0
  106. package/dist/src/core/interfaces/plugin.interface.d.ts.map +1 -0
  107. package/dist/src/core/interfaces/plugin.interface.js +3 -0
  108. package/dist/src/core/interfaces/plugin.interface.js.map +1 -0
  109. package/dist/src/core/interfaces/project-config.interface.d.ts +7 -0
  110. package/dist/src/core/interfaces/project-config.interface.d.ts.map +1 -0
  111. package/dist/src/core/interfaces/project-config.interface.js +3 -0
  112. package/dist/src/core/interfaces/project-config.interface.js.map +1 -0
  113. package/dist/src/core/interfaces/step.interface.d.ts +9 -0
  114. package/dist/src/core/interfaces/step.interface.d.ts.map +1 -0
  115. package/dist/src/core/interfaces/step.interface.js +3 -0
  116. package/dist/src/core/interfaces/step.interface.js.map +1 -0
  117. package/dist/src/core/interfaces/template-config.interface.d.ts +5 -0
  118. package/dist/src/core/interfaces/template-config.interface.d.ts.map +1 -0
  119. package/dist/src/core/interfaces/template-config.interface.js +3 -0
  120. package/dist/src/core/interfaces/template-config.interface.js.map +1 -0
  121. package/dist/src/core/interfaces/validation-issue.interface.d.ts +18 -0
  122. package/dist/src/core/interfaces/validation-issue.interface.d.ts.map +1 -0
  123. package/dist/src/core/interfaces/validation-issue.interface.js +3 -0
  124. package/dist/src/core/interfaces/validation-issue.interface.js.map +1 -0
  125. package/dist/src/core/interfaces/validation-result.interface.d.ts +5 -0
  126. package/dist/src/core/interfaces/validation-result.interface.d.ts.map +1 -0
  127. package/dist/src/core/interfaces/validation-result.interface.js +3 -0
  128. package/dist/src/core/interfaces/validation-result.interface.js.map +1 -0
  129. package/dist/src/core/interfaces/workspace-config.interface.d.ts +8 -0
  130. package/dist/src/core/interfaces/workspace-config.interface.d.ts.map +1 -0
  131. package/dist/src/core/interfaces/workspace-config.interface.js +3 -0
  132. package/dist/src/core/interfaces/workspace-config.interface.js.map +1 -0
  133. package/dist/src/core/package-resolver.d.ts +10 -0
  134. package/dist/src/core/package-resolver.d.ts.map +1 -0
  135. package/dist/src/core/package-resolver.js +68 -0
  136. package/dist/src/core/package-resolver.js.map +1 -0
  137. package/dist/src/core/plugin-manager.d.ts +13 -0
  138. package/dist/src/core/plugin-manager.d.ts.map +1 -0
  139. package/dist/src/core/plugin-manager.js +48 -0
  140. package/dist/src/core/plugin-manager.js.map +1 -0
  141. package/dist/src/core/plugins/example-plugin.d.ts +3 -0
  142. package/dist/src/core/plugins/example-plugin.d.ts.map +1 -0
  143. package/dist/src/core/plugins/example-plugin.js +30 -0
  144. package/dist/src/core/plugins/example-plugin.js.map +1 -0
  145. package/dist/src/core/project-config-builder.d.ts +11 -0
  146. package/dist/src/core/project-config-builder.d.ts.map +1 -0
  147. package/dist/src/core/project-config-builder.js +77 -0
  148. package/dist/src/core/project-config-builder.js.map +1 -0
  149. package/dist/src/core/project-generator.d.ts +11 -0
  150. package/dist/src/core/project-generator.d.ts.map +1 -0
  151. package/dist/src/core/project-generator.js +29 -0
  152. package/dist/src/core/project-generator.js.map +1 -0
  153. package/dist/src/core/step-executor.d.ts +19 -0
  154. package/dist/src/core/step-executor.d.ts.map +1 -0
  155. package/dist/src/core/step-executor.js +130 -0
  156. package/dist/src/core/step-executor.js.map +1 -0
  157. package/dist/src/core/validators/config-validator.d.ts +10 -0
  158. package/dist/src/core/validators/config-validator.d.ts.map +1 -0
  159. package/dist/src/core/validators/config-validator.js +44 -0
  160. package/dist/src/core/validators/config-validator.js.map +1 -0
  161. package/dist/src/core/validators/post-generation-validator.d.ts +10 -0
  162. package/dist/src/core/validators/post-generation-validator.d.ts.map +1 -0
  163. package/dist/src/core/validators/post-generation-validator.js +219 -0
  164. package/dist/src/core/validators/post-generation-validator.js.map +1 -0
  165. package/dist/src/generate-monorepo.d.ts +3 -0
  166. package/dist/src/generate-monorepo.d.ts.map +1 -0
  167. package/dist/src/generate-monorepo.js +668 -0
  168. package/dist/src/generate-monorepo.js.map +1 -0
  169. package/dist/src/templates/engines/handlebars-engine.d.ts +7 -0
  170. package/dist/src/templates/engines/handlebars-engine.d.ts.map +1 -0
  171. package/dist/src/templates/engines/handlebars-engine.js +19 -0
  172. package/dist/src/templates/engines/handlebars-engine.js.map +1 -0
  173. package/dist/src/templates/engines/mustache-engine.d.ts +5 -0
  174. package/dist/src/templates/engines/mustache-engine.d.ts.map +1 -0
  175. package/dist/src/templates/engines/mustache-engine.js +44 -0
  176. package/dist/src/templates/engines/mustache-engine.js.map +1 -0
  177. package/dist/src/templates/index.d.ts +5 -0
  178. package/dist/src/templates/index.d.ts.map +1 -0
  179. package/dist/src/templates/index.js +21 -0
  180. package/dist/src/templates/index.js.map +1 -0
  181. package/dist/src/templates/interfaces/template-engine.interface.d.ts +4 -0
  182. package/dist/src/templates/interfaces/template-engine.interface.d.ts.map +1 -0
  183. package/dist/src/templates/interfaces/template-engine.interface.js +3 -0
  184. package/dist/src/templates/interfaces/template-engine.interface.js.map +1 -0
  185. package/dist/src/templates/template-engine-factory.d.ts +3 -0
  186. package/dist/src/templates/template-engine-factory.d.ts.map +1 -0
  187. package/dist/src/templates/template-engine-factory.js +9 -0
  188. package/dist/src/templates/template-engine-factory.js.map +1 -0
  189. package/dist/src/utils/diff-viewer.d.ts +15 -0
  190. package/dist/src/utils/diff-viewer.d.ts.map +1 -0
  191. package/dist/src/utils/diff-viewer.js +61 -0
  192. package/dist/src/utils/diff-viewer.js.map +1 -0
  193. package/dist/src/utils/doc-generator.d.ts +8 -0
  194. package/dist/src/utils/doc-generator.d.ts.map +1 -0
  195. package/dist/src/utils/doc-generator.js +174 -0
  196. package/dist/src/utils/doc-generator.js.map +1 -0
  197. package/dist/src/utils/shell-utils.d.ts +4 -0
  198. package/dist/src/utils/shell-utils.d.ts.map +1 -0
  199. package/dist/src/utils/shell-utils.js +32 -0
  200. package/dist/src/utils/shell-utils.js.map +1 -0
  201. package/dist/src/utils/system-check.d.ts +11 -0
  202. package/dist/src/utils/system-check.d.ts.map +1 -0
  203. package/dist/src/utils/system-check.js +71 -0
  204. package/dist/src/utils/system-check.js.map +1 -0
  205. package/dist/src/utils/template-renderer.d.ts +3 -0
  206. package/dist/src/utils/template-renderer.d.ts.map +1 -0
  207. package/dist/src/utils/template-renderer.js +127 -0
  208. package/dist/src/utils/template-renderer.js.map +1 -0
  209. package/package.json +51 -0
  210. package/templates/api/.env.example.mustache +57 -0
  211. package/templates/api-lib/README.md.mustache +23 -0
  212. package/templates/react-lib/README.md.mustache +23 -0
  213. package/templates/root/README.md.mustache +175 -0
  214. package/templates/root/reset.sh.mustache +25 -0
@@ -0,0 +1,668 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.main = main;
40
+ const input_1 = __importDefault(require("@inquirer/input"));
41
+ const select_1 = __importDefault(require("@inquirer/select"));
42
+ const confirm_1 = __importDefault(require("@inquirer/confirm"));
43
+ const checkbox_1 = __importDefault(require("@inquirer/checkbox"));
44
+ const path = __importStar(require("path"));
45
+ const fs = __importStar(require("fs"));
46
+ const albatross_1 = require("../scripts/albatross");
47
+ const logger_1 = require("./cli/logger");
48
+ const config_schema_1 = require("./core/config-schema");
49
+ const system_check_1 = require("./utils/system-check");
50
+ const step_executor_1 = require("./core/step-executor");
51
+ const project_config_builder_1 = require("./core/project-config-builder");
52
+ const project_generator_1 = require("./core/project-generator");
53
+ const shell_utils_1 = require("./utils/shell-utils");
54
+ const template_renderer_1 = require("./utils/template-renderer");
55
+ const passwordObfuscator_1 = require("../scripts/passwordObfuscator");
56
+ const nodeSetup_1 = require("../scripts/nodeSetup");
57
+ const licensePrompt_1 = require("../scripts/licensePrompt");
58
+ const addScriptsToPackageJson_1 = require("../scripts/addScriptsToPackageJson");
59
+ const templateUtils_1 = require("../scripts/templateUtils");
60
+ async function main() {
61
+ (0, albatross_1.printBanner)();
62
+ (0, nodeSetup_1.checkAndUseNode)();
63
+ // Disable Yarn build scripts globally to avoid native module issues
64
+ process.env.YARN_ENABLE_SCRIPTS = 'false';
65
+ // System check
66
+ logger_1.Logger.header('System Check');
67
+ const systemCheck = system_check_1.SystemCheck.check();
68
+ system_check_1.SystemCheck.printReport(systemCheck);
69
+ if (!systemCheck.passed) {
70
+ const proceed = await (0, confirm_1.default)({
71
+ message: 'Continue anyway? (Installation may fail)',
72
+ default: false,
73
+ });
74
+ if (!proceed) {
75
+ logger_1.Logger.info('Cancelled. Please install required tools and try again.');
76
+ process.exit(0);
77
+ }
78
+ }
79
+ // Load preset
80
+ const presetPath = path.resolve(__dirname, '../../config/presets/standard.json');
81
+ const preset = JSON.parse(fs.readFileSync(presetPath, 'utf-8'));
82
+ // Prompt for workspace configuration
83
+ logger_1.Logger.header('Workspace Configuration');
84
+ const workspaceName = await (0, input_1.default)({
85
+ message: 'Enter the workspace name:',
86
+ default: 'example-project',
87
+ validate: (val) => config_schema_1.ConfigValidator.validateWorkspaceName(val) || 'Invalid workspace name (letters, numbers, dashes only)',
88
+ });
89
+ const projectPrefix = await (0, input_1.default)({
90
+ message: 'Enter the project prefix:',
91
+ default: workspaceName,
92
+ validate: (val) => config_schema_1.ConfigValidator.validatePrefix(val) || 'Invalid prefix (lowercase letters, numbers, dashes only)',
93
+ });
94
+ const namespaceRoot = await (0, input_1.default)({
95
+ message: 'Enter the npm namespace:',
96
+ default: `@${projectPrefix}`,
97
+ validate: (val) => config_schema_1.ConfigValidator.validateNamespace(val) || 'Invalid namespace (must start with @)',
98
+ });
99
+ const parentDir = path.resolve(await (0, input_1.default)({
100
+ message: 'Enter the parent directory:',
101
+ default: process.cwd(),
102
+ }));
103
+ const gitRepo = await (0, input_1.default)({
104
+ message: 'Enter the git repository URL (optional):',
105
+ validate: (val) => config_schema_1.ConfigValidator.validateGitRepo(val) || 'Invalid git repository URL',
106
+ });
107
+ const hostname = await (0, input_1.default)({
108
+ message: 'Enter the hostname for development (e.g., example-project.local):',
109
+ default: `${workspaceName}.local`,
110
+ validate: (val) => /^[a-z0-9-]+(\.[a-z0-9-]+)*$/.test(val) || 'Invalid hostname format',
111
+ });
112
+ const dryRun = await (0, confirm_1.default)({
113
+ message: 'Run in dry-run mode (preview without creating files)?',
114
+ default: false,
115
+ });
116
+ logger_1.Logger.section('Optional Projects');
117
+ const includeE2e = await (0, confirm_1.default)({
118
+ message: 'Include E2E tests?',
119
+ default: true,
120
+ });
121
+ logger_1.Logger.section('Package Groups');
122
+ const packageGroupsPath = path.resolve(__dirname, '../../config/package-groups.json');
123
+ const packageGroups = JSON.parse(fs.readFileSync(packageGroupsPath, 'utf-8')).groups;
124
+ const selectedGroups = await (0, checkbox_1.default)({
125
+ message: 'Select optional package groups:',
126
+ choices: packageGroups
127
+ .filter((g) => !g.enabled)
128
+ .map((g) => ({
129
+ name: `${g.name} - ${g.description}`,
130
+ value: g.name,
131
+ checked: true,
132
+ })),
133
+ });
134
+ const enableDocGeneration = await (0, confirm_1.default)({
135
+ message: 'Generate documentation (README, ARCHITECTURE, API docs)?',
136
+ default: true,
137
+ });
138
+ logger_1.Logger.section('DevContainer Configuration');
139
+ const setupDevcontainer = await (0, confirm_1.default)({
140
+ message: 'Set up DevContainer configuration?',
141
+ default: true,
142
+ });
143
+ let devcontainerChoice = 'none';
144
+ if (setupDevcontainer) {
145
+ devcontainerChoice = await (0, select_1.default)({
146
+ message: 'DevContainer configuration:',
147
+ choices: [
148
+ { name: 'Simple (Node.js only)', value: 'simple' },
149
+ { name: 'With MongoDB', value: 'mongodb' },
150
+ { name: 'With MongoDB Replica Set', value: 'mongodb-replicaset' },
151
+ ],
152
+ default: 'mongodb-replicaset',
153
+ });
154
+ }
155
+ logger_1.Logger.section('Express Suite Packages');
156
+ const monorepoPath = path.join(parentDir, workspaceName);
157
+ // Build project configurations
158
+ const projects = project_config_builder_1.ProjectConfigBuilder.build(projectPrefix, namespaceRoot, {
159
+ includeReactLib: true,
160
+ includeApiLib: true,
161
+ includeE2e,
162
+ includeInitUserDb: true,
163
+ includeTestUtils: false,
164
+ });
165
+ // Build configuration
166
+ const config = {
167
+ workspace: {
168
+ name: workspaceName,
169
+ prefix: projectPrefix,
170
+ namespace: namespaceRoot,
171
+ parentDir,
172
+ gitRepo,
173
+ hostname,
174
+ },
175
+ projects,
176
+ ...preset,
177
+ };
178
+ // Validate configuration
179
+ const validation = config_schema_1.ConfigValidator.validate(config);
180
+ if (!validation.valid) {
181
+ validation.errors.forEach(err => logger_1.Logger.error(err));
182
+ process.exit(1);
183
+ }
184
+ // Setup context with all project names
185
+ const stateEntries = [
186
+ ['monorepoPath', monorepoPath],
187
+ ['templatesDir', path.resolve(__dirname, '../../templates')],
188
+ ['scaffoldingDir', path.resolve(__dirname, '../../scaffolding')],
189
+ ];
190
+ projects.forEach(project => {
191
+ stateEntries.push([project.type === 'lib' ? 'libName' : `${project.type}Name`, project.name]);
192
+ });
193
+ const context = {
194
+ config,
195
+ state: new Map(stateEntries),
196
+ checkpointPath: path.join(parentDir, `.${workspaceName}.checkpoint`),
197
+ };
198
+ // Merge selected package groups
199
+ const additionalPackages = [];
200
+ selectedGroups.forEach((groupName) => {
201
+ const group = packageGroups.find((g) => g.name === groupName);
202
+ if (group) {
203
+ additionalPackages.push(...group.packages);
204
+ }
205
+ });
206
+ if (additionalPackages.length > 0 && config.packages) {
207
+ config.packages = {
208
+ ...config.packages,
209
+ dev: [...(config.packages.dev || []), ...additionalPackages],
210
+ prod: config.packages.prod || [],
211
+ };
212
+ }
213
+ // Note: @digitaldefiance/express-suite-test-utils is always included in dev dependencies
214
+ // react-components will be added to react-lib or react project directly
215
+ // Setup steps
216
+ const executor = dryRun
217
+ ? new (await Promise.resolve().then(() => __importStar(require('./core/dry-run-executor')))).DryRunExecutor()
218
+ : new step_executor_1.StepExecutor();
219
+ if (dryRun) {
220
+ logger_1.Logger.warning('DRY RUN MODE - No files will be created');
221
+ }
222
+ executor.addStep({
223
+ name: 'checkTargetDir',
224
+ description: 'Checking target directory',
225
+ execute: () => {
226
+ if (fs.existsSync(monorepoPath) && fs.readdirSync(monorepoPath).length > 0) {
227
+ throw new Error(`Directory ${logger_1.Logger.path(monorepoPath)} already exists and is not empty`);
228
+ }
229
+ },
230
+ });
231
+ executor.addStep({
232
+ name: 'createMonorepo',
233
+ description: 'Creating Nx monorepo',
234
+ execute: () => {
235
+ (0, shell_utils_1.runCommand)(`npx create-nx-workspace@latest "${workspaceName}" --package-manager=yarn --preset=apps --ci=${config.nx?.ciProvider}`, { cwd: parentDir });
236
+ },
237
+ });
238
+ executor.addStep({
239
+ name: 'setupGitOrigin',
240
+ description: 'Setting up git remote',
241
+ skip: () => !gitRepo,
242
+ execute: () => {
243
+ (0, shell_utils_1.runCommand)(`git remote add origin ${gitRepo}`, { cwd: monorepoPath });
244
+ },
245
+ });
246
+ executor.addStep({
247
+ name: 'yarnBerrySetup',
248
+ description: 'Configuring Yarn Berry',
249
+ execute: () => {
250
+ (0, shell_utils_1.runCommand)('yarn set version berry', { cwd: monorepoPath });
251
+ (0, shell_utils_1.runCommand)('yarn config set nodeLinker node-modules', { cwd: monorepoPath });
252
+ (0, shell_utils_1.runCommand)('yarn', { cwd: monorepoPath });
253
+ },
254
+ });
255
+ executor.addStep({
256
+ name: 'addNxPlugins',
257
+ description: 'Installing Nx plugins',
258
+ execute: () => {
259
+ try {
260
+ (0, shell_utils_1.runCommand)('yarn add -D @nx/react @nx/node', { cwd: monorepoPath });
261
+ }
262
+ catch (error) {
263
+ if (error.status === 1) {
264
+ logger_1.Logger.error('\nPackage installation failed.');
265
+ logger_1.Logger.section('If you see "exit code 127" above, install build tools:');
266
+ logger_1.Logger.dim(' Ubuntu/Debian: sudo apt-get install build-essential python3');
267
+ logger_1.Logger.dim(' Fedora/RHEL: sudo dnf install gcc-c++ make python3');
268
+ logger_1.Logger.dim(' macOS: xcode-select --install');
269
+ logger_1.Logger.section('\nThen retry or skip: yarn start --start-at=addYarnPackages');
270
+ }
271
+ throw error;
272
+ }
273
+ },
274
+ });
275
+ executor.addStep({
276
+ name: 'addYarnPackages',
277
+ description: 'Installing dependencies',
278
+ execute: () => {
279
+ const devPkgs = config.packages?.dev || [];
280
+ const prodPkgs = config.packages?.prod || [];
281
+ if (devPkgs.length > 0) {
282
+ (0, shell_utils_1.runCommand)(`yarn add -D ${devPkgs.join(' ')}`, { cwd: monorepoPath });
283
+ }
284
+ if (prodPkgs.length > 0) {
285
+ (0, shell_utils_1.runCommand)(`yarn add ${prodPkgs.join(' ')}`, { cwd: monorepoPath });
286
+ }
287
+ },
288
+ });
289
+ executor.addStep({
290
+ name: 'generateProjects',
291
+ description: 'Generating project structure',
292
+ execute: () => {
293
+ projects.forEach(project => {
294
+ if (!project.enabled)
295
+ return;
296
+ logger_1.Logger.info(`Generating ${project.type}: ${project.name}`);
297
+ switch (project.type) {
298
+ case 'react':
299
+ project_generator_1.ProjectGenerator.generateReact(project, monorepoPath, config.nx);
300
+ break;
301
+ case 'react-lib':
302
+ project_generator_1.ProjectGenerator.generateReactLib(project, monorepoPath, config.nx);
303
+ break;
304
+ case 'api':
305
+ project_generator_1.ProjectGenerator.generateApi(project, monorepoPath, config.nx);
306
+ break;
307
+ case 'api-lib':
308
+ project_generator_1.ProjectGenerator.generateApiLib(project, monorepoPath, config.nx);
309
+ break;
310
+ case 'lib':
311
+ project_generator_1.ProjectGenerator.generateLib(project, monorepoPath, config.nx);
312
+ break;
313
+ case 'inituserdb':
314
+ project_generator_1.ProjectGenerator.generateInitUserDb(project, monorepoPath);
315
+ break;
316
+ }
317
+ });
318
+ // Add copy-env and post-build targets to api and inituserdb project.json
319
+ const apiProject = projects.find(p => p.type === 'api' && p.enabled);
320
+ const initUserDbProject = projects.find(p => p.type === 'inituserdb' && p.enabled);
321
+ if (apiProject) {
322
+ const projectJsonPath = path.join(monorepoPath, apiProject.name, 'project.json');
323
+ if (fs.existsSync(projectJsonPath)) {
324
+ const projectJson = JSON.parse(fs.readFileSync(projectJsonPath, 'utf-8'));
325
+ projectJson.targets['copy-env'] = {
326
+ executor: 'nx:run-commands',
327
+ options: {
328
+ command: `cp ${apiProject.name}/.env dist/${apiProject.name}/.env`
329
+ }
330
+ };
331
+ projectJson.targets['post-build'] = {
332
+ executor: 'nx:run-commands',
333
+ dependsOn: ['build'],
334
+ options: {
335
+ command: `cp ${apiProject.name}/.env dist/${apiProject.name}/.env`
336
+ }
337
+ };
338
+ // Update serve to depend on post-build instead of build
339
+ if (projectJson.targets.serve) {
340
+ projectJson.targets.serve.dependsOn = ['post-build'];
341
+ projectJson.targets.serve.options.buildTarget = `${apiProject.name}:post-build`;
342
+ if (projectJson.targets.serve.configurations) {
343
+ Object.keys(projectJson.targets.serve.configurations).forEach(config => {
344
+ projectJson.targets.serve.configurations[config].buildTarget = `${apiProject.name}:post-build`;
345
+ });
346
+ }
347
+ }
348
+ fs.writeFileSync(projectJsonPath, JSON.stringify(projectJson, null, 2) + '\n');
349
+ logger_1.Logger.info(`Added copy-env and post-build targets to ${apiProject.name}/project.json`);
350
+ }
351
+ }
352
+ if (initUserDbProject) {
353
+ const projectJsonPath = path.join(monorepoPath, initUserDbProject.name, 'project.json');
354
+ if (fs.existsSync(projectJsonPath)) {
355
+ const projectJson = JSON.parse(fs.readFileSync(projectJsonPath, 'utf-8'));
356
+ projectJson.targets['copy-env'] = {
357
+ executor: 'nx:run-commands',
358
+ options: {
359
+ command: `cp ${initUserDbProject.name}/.env dist/${initUserDbProject.name}/.env`
360
+ }
361
+ };
362
+ projectJson.targets['post-build'] = {
363
+ executor: 'nx:run-commands',
364
+ dependsOn: ['build'],
365
+ options: {
366
+ commands: [
367
+ `cp ${initUserDbProject.name}/.env dist/${initUserDbProject.name}/.env`,
368
+ `cd dist/${initUserDbProject.name} && yarn install`
369
+ ],
370
+ parallel: false
371
+ }
372
+ };
373
+ // Update serve to depend on post-build instead of build
374
+ if (projectJson.targets.serve) {
375
+ projectJson.targets.serve.dependsOn = ['post-build'];
376
+ projectJson.targets.serve.options.buildTarget = `${initUserDbProject.name}:post-build`;
377
+ if (projectJson.targets.serve.configurations) {
378
+ Object.keys(projectJson.targets.serve.configurations).forEach(config => {
379
+ projectJson.targets.serve.configurations[config].buildTarget = `${initUserDbProject.name}:post-build`;
380
+ });
381
+ }
382
+ }
383
+ fs.writeFileSync(projectJsonPath, JSON.stringify(projectJson, null, 2) + '\n');
384
+ logger_1.Logger.info(`Added copy-env and post-build targets to ${initUserDbProject.name}/project.json`);
385
+ }
386
+ }
387
+ },
388
+ });
389
+ executor.addStep({
390
+ name: 'installReactComponents',
391
+ description: 'Installing React components package',
392
+ execute: () => {
393
+ const reactLibProject = projects.find(p => p.type === 'react-lib' && p.enabled);
394
+ if (reactLibProject) {
395
+ logger_1.Logger.info(`Installing @digitaldefiance/express-suite-react-components in ${reactLibProject.name}`);
396
+ const projectPackageJsonPath = path.join(monorepoPath, reactLibProject.name, 'package.json');
397
+ const projectPackageJson = JSON.parse(fs.readFileSync(projectPackageJsonPath, 'utf-8'));
398
+ projectPackageJson.dependencies = projectPackageJson.dependencies || {};
399
+ projectPackageJson.dependencies['@digitaldefiance/express-suite-react-components'] = 'latest';
400
+ fs.writeFileSync(projectPackageJsonPath, JSON.stringify(projectPackageJson, null, 2) + '\n');
401
+ (0, shell_utils_1.runCommand)('yarn install', { cwd: monorepoPath });
402
+ }
403
+ },
404
+ });
405
+ executor.addStep({
406
+ name: 'renderTemplates',
407
+ description: 'Rendering configuration templates',
408
+ execute: () => {
409
+ const variables = {
410
+ WORKSPACE_NAME: workspaceName,
411
+ PROJECT_PREFIX: projectPrefix,
412
+ NAMESPACE_ROOT: namespaceRoot,
413
+ HOSTNAME: hostname,
414
+ EXAMPLE_PASSWORD: (0, passwordObfuscator_1.obfuscatePassword)(projectPrefix),
415
+ EXAMPLE_JWT_SECRET: (0, passwordObfuscator_1.obfuscatePassword)(`${workspaceName}Secret`),
416
+ GIT_REPO: gitRepo,
417
+ NVM_USE_VERSION: config.node?.version,
418
+ YARN_VERSION: config.node?.yarnVersion,
419
+ };
420
+ projects.forEach(project => {
421
+ const key = project.type === 'lib' ? 'LIB_NAME' : `${project.type.toUpperCase().replace(/-/g, '_')}_NAME`;
422
+ variables[key] = project.name;
423
+ });
424
+ (0, template_renderer_1.renderTemplates)(context.state.get('templatesDir'), monorepoPath, variables, config.templates?.engine);
425
+ },
426
+ });
427
+ executor.addStep({
428
+ name: 'copyScaffolding',
429
+ description: 'Copying scaffolding files',
430
+ execute: () => {
431
+ const scaffoldingDir = context.state.get('scaffoldingDir');
432
+ // Template variables for scaffolding
433
+ const scaffoldingVars = {
434
+ workspaceName,
435
+ WorkspaceName: workspaceName.charAt(0).toUpperCase() + workspaceName.slice(1).replace(/-([a-z])/g, (_, c) => c.toUpperCase()),
436
+ prefix: projectPrefix,
437
+ namespace: namespaceRoot,
438
+ hostname,
439
+ };
440
+ // Copy root scaffolding
441
+ const rootSrc = path.join(scaffoldingDir, 'root');
442
+ if (fs.existsSync(rootSrc)) {
443
+ (0, template_renderer_1.copyDir)(rootSrc, monorepoPath, scaffoldingVars);
444
+ }
445
+ // Copy devcontainer configuration
446
+ if (devcontainerChoice !== 'none') {
447
+ const devcontainerSrc = path.join(scaffoldingDir, `devcontainer-${devcontainerChoice}`);
448
+ if (fs.existsSync(devcontainerSrc)) {
449
+ logger_1.Logger.info(`Copying devcontainer configuration: ${devcontainerChoice}`);
450
+ (0, template_renderer_1.copyDir)(devcontainerSrc, monorepoPath, scaffoldingVars);
451
+ }
452
+ }
453
+ // Copy project-specific scaffolding
454
+ projects.forEach(project => {
455
+ const projectSrc = path.join(scaffoldingDir, project.type);
456
+ if (fs.existsSync(projectSrc)) {
457
+ (0, template_renderer_1.copyDir)(projectSrc, path.join(monorepoPath, project.name), scaffoldingVars);
458
+ }
459
+ });
460
+ },
461
+ });
462
+ executor.addStep({
463
+ name: 'generateLicense',
464
+ description: 'Generating LICENSE file',
465
+ execute: async () => {
466
+ await (0, licensePrompt_1.promptAndGenerateLicense)(monorepoPath);
467
+ },
468
+ });
469
+ executor.addStep({
470
+ name: 'addScripts',
471
+ description: 'Adding package.json scripts',
472
+ execute: () => {
473
+ const packageJsonPath = path.join(monorepoPath, 'package.json');
474
+ const scriptContext = {
475
+ workspaceName,
476
+ projectPrefix,
477
+ namespaceRoot,
478
+ gitRepo,
479
+ };
480
+ projects.forEach(project => {
481
+ scriptContext[`${project.type}Name`] = project.name;
482
+ });
483
+ const addScripts = {
484
+ 'build': 'NODE_ENV=production npx nx run-many --target=build --all --configuration=production',
485
+ 'build:dev': 'NODE_ENV=development npx nx run-many --target=build --all --configuration=development',
486
+ 'test:all': 'yarn test:jest && yarn test:e2e',
487
+ 'test:jest': 'NODE_ENV=development npx nx run-many --target=test --all --configuration=development',
488
+ 'lint:all': 'npx nx run-many --target=lint --all',
489
+ 'prettier:check': "prettier --check '**/*.{ts,tsx}'",
490
+ 'prettier:fix': "prettier --write '**/*.{ts,tsx}'",
491
+ };
492
+ const apiProject = projects.find(p => p.type === 'api');
493
+ if (apiProject) {
494
+ addScripts['serve'] = `npx nx serve ${apiProject.name} --configuration production`;
495
+ addScripts['serve:stream'] = `npx nx serve ${apiProject.name} --configuration production --output-style=stream`;
496
+ addScripts['serve:dev'] = `npx nx serve ${apiProject.name} --configuration development`;
497
+ addScripts['serve:dev:stream'] = `npx nx serve ${apiProject.name} --configuration development --output-style=stream`;
498
+ addScripts['build:api'] = `npx nx build ${apiProject.name}`;
499
+ }
500
+ const reactProject = projects.find(p => p.type === 'react');
501
+ if (reactProject) {
502
+ addScripts['build:react'] = `npx nx build ${reactProject.name}`;
503
+ }
504
+ const interpolatedScripts = {};
505
+ for (const [k, v] of Object.entries(addScripts)) {
506
+ interpolatedScripts[k] = (0, templateUtils_1.interpolateTemplateStrings)(v, scriptContext);
507
+ }
508
+ (0, addScriptsToPackageJson_1.addScriptsToPackageJson)(packageJsonPath, interpolatedScripts);
509
+ },
510
+ });
511
+ executor.addStep({
512
+ name: 'generateDocumentation',
513
+ description: 'Generating documentation',
514
+ skip: () => !enableDocGeneration || dryRun,
515
+ execute: async () => {
516
+ const { DocGenerator } = await Promise.resolve().then(() => __importStar(require('./utils/doc-generator')));
517
+ DocGenerator.generateProjectDocs(context);
518
+ },
519
+ });
520
+ executor.addStep({
521
+ name: 'setupEnvironment',
522
+ description: 'Setting up environment files',
523
+ execute: () => {
524
+ const apiProject = projects.find(p => p.type === 'api');
525
+ const initUserDbProject = projects.find(p => p.type === 'inituserdb');
526
+ // Setup API .env
527
+ if (apiProject) {
528
+ const envExamplePath = path.join(monorepoPath, apiProject.name, '.env.example');
529
+ const envPath = path.join(monorepoPath, apiProject.name, '.env');
530
+ if (fs.existsSync(envExamplePath) && !fs.existsSync(envPath)) {
531
+ fs.copyFileSync(envExamplePath, envPath);
532
+ logger_1.Logger.info(`Created ${apiProject.name}/.env from .env.example`);
533
+ }
534
+ }
535
+ // Setup inituserdb .env
536
+ if (initUserDbProject && apiProject) {
537
+ const apiEnvPath = path.join(monorepoPath, apiProject.name, '.env');
538
+ const initEnvPath = path.join(monorepoPath, initUserDbProject.name, '.env');
539
+ if (fs.existsSync(apiEnvPath) && !fs.existsSync(initEnvPath)) {
540
+ fs.copyFileSync(apiEnvPath, initEnvPath);
541
+ logger_1.Logger.info(`Created ${initUserDbProject.name}/.env from ${apiProject.name}/.env`);
542
+ }
543
+ }
544
+ // Setup devcontainer .env if devcontainer with MongoDB
545
+ if (devcontainerChoice === 'mongodb' || devcontainerChoice === 'mongodb-replicaset') {
546
+ const devcontainerEnvPath = path.join(monorepoPath, '.devcontainer', '.env');
547
+ if (!fs.existsSync(devcontainerEnvPath)) {
548
+ const mongoUri = devcontainerChoice === 'mongodb-replicaset'
549
+ ? 'mongodb://localhost:27017/example-project?replicaSet=rs0&directConnection=true'
550
+ : 'mongodb://localhost:27017/example-project?directConnection=true';
551
+ const envContent = `MONGO_URI=${mongoUri}\n`;
552
+ fs.writeFileSync(devcontainerEnvPath, envContent);
553
+ logger_1.Logger.info('Created .devcontainer/.env with MongoDB configuration');
554
+ }
555
+ }
556
+ },
557
+ });
558
+ executor.addStep({
559
+ name: 'rebuildNativeModules',
560
+ description: 'Building native modules',
561
+ execute: () => {
562
+ logger_1.Logger.info('Re-enabling build scripts and building native modules...');
563
+ (0, shell_utils_1.runCommand)('yarn config set enableScripts true', { cwd: monorepoPath });
564
+ (0, shell_utils_1.runCommand)('yarn rebuild', { cwd: monorepoPath });
565
+ },
566
+ });
567
+ executor.addStep({
568
+ name: 'validateGeneration',
569
+ description: 'Validating generated project',
570
+ skip: () => dryRun,
571
+ execute: async () => {
572
+ const { PostGenerationValidator } = await Promise.resolve().then(() => __importStar(require('./core/validators/post-generation-validator')));
573
+ const report = await PostGenerationValidator.validate(context);
574
+ PostGenerationValidator.printReport(report);
575
+ if (!report.passed) {
576
+ logger_1.Logger.warning('Validation found errors, but continuing...');
577
+ }
578
+ },
579
+ });
580
+ executor.addStep({
581
+ name: 'initialCommit',
582
+ description: 'Creating initial commit',
583
+ execute: async () => {
584
+ // Ensure git is initialized
585
+ if (!fs.existsSync(path.join(monorepoPath, '.git'))) {
586
+ (0, shell_utils_1.runCommand)('git init', { cwd: monorepoPath });
587
+ }
588
+ const doCommit = await (0, confirm_1.default)({
589
+ message: 'Create initial git commit?',
590
+ default: true,
591
+ });
592
+ if (doCommit) {
593
+ (0, shell_utils_1.runCommand)('git add -A', { cwd: monorepoPath });
594
+ (0, shell_utils_1.runCommand)('git commit -m "Initial commit"', { cwd: monorepoPath });
595
+ if (gitRepo) {
596
+ const doPush = await (0, confirm_1.default)({
597
+ message: 'Push to remote repository?',
598
+ default: true,
599
+ });
600
+ if (doPush) {
601
+ (0, shell_utils_1.runCommand)('git push --set-upstream origin main', { cwd: monorepoPath });
602
+ }
603
+ }
604
+ }
605
+ },
606
+ });
607
+ executor.addStep({
608
+ name: 'installPlaywright',
609
+ description: 'Installing Playwright browsers',
610
+ skip: () => !includeE2e,
611
+ execute: async () => {
612
+ const installPlaywright = await (0, confirm_1.default)({
613
+ message: 'Install Playwright browsers? (Required for E2E tests)',
614
+ default: true,
615
+ });
616
+ if (installPlaywright) {
617
+ logger_1.Logger.info('Installing Playwright browsers (this may take a few minutes)...');
618
+ (0, shell_utils_1.runCommand)('yarn playwright install --with-deps', { cwd: monorepoPath });
619
+ }
620
+ else {
621
+ logger_1.Logger.warning('Skipped. Run manually later: yarn playwright install --with-deps');
622
+ }
623
+ },
624
+ });
625
+ // Execute
626
+ try {
627
+ await executor.execute(context);
628
+ if (dryRun) {
629
+ logger_1.Logger.warning('Dry-run complete. Re-run without dry-run to generate.');
630
+ process.exit(0);
631
+ }
632
+ logger_1.Logger.header('Generation Complete!');
633
+ logger_1.Logger.success(`Monorepo created at: ${logger_1.Logger.path(monorepoPath)}`);
634
+ const apiProject = projects.find(p => p.type === 'api');
635
+ if (apiProject) {
636
+ logger_1.Logger.warning(`\nIMPORTANT: Update ${apiProject.name}/.env with your configuration`);
637
+ }
638
+ if (devcontainerChoice === 'mongodb' || devcontainerChoice === 'mongodb-replicaset') {
639
+ logger_1.Logger.warning(`IMPORTANT: Update .devcontainer/.env with your MongoDB configuration`);
640
+ }
641
+ logger_1.Logger.section('Next steps:');
642
+ logger_1.Logger.dim(` cd ${workspaceName}`);
643
+ if (apiProject) {
644
+ logger_1.Logger.dim(` # Update ${apiProject.name}/.env with your settings`);
645
+ }
646
+ logger_1.Logger.dim(` yarn build:dev`);
647
+ logger_1.Logger.dim(` yarn serve:dev`);
648
+ logger_1.Logger.section('Generated projects:');
649
+ projects.forEach(p => {
650
+ if (p.enabled) {
651
+ logger_1.Logger.dim(` ${p.type.padEnd(12)} ${p.name}`);
652
+ }
653
+ });
654
+ }
655
+ catch (error) {
656
+ logger_1.Logger.error('Generation failed');
657
+ console.error(error);
658
+ process.exit(1);
659
+ }
660
+ }
661
+ if (require.main === module) {
662
+ main().catch((err) => {
663
+ logger_1.Logger.error('Fatal error');
664
+ console.error(err);
665
+ process.exit(1);
666
+ });
667
+ }
668
+ //# sourceMappingURL=generate-monorepo.js.map