@digitaldefiance/express-suite-starter 2.1.44 → 2.1.46

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 (90) hide show
  1. package/README.md +5 -1
  2. package/dist/scripts/albatross.d.ts +2 -2
  3. package/dist/scripts/albatross.d.ts.map +1 -1
  4. package/dist/scripts/albatross.js +81 -4
  5. package/dist/scripts/albatross.js.map +1 -1
  6. package/dist/scripts/nodeSetup.d.ts.map +1 -1
  7. package/dist/scripts/nodeSetup.js +1 -0
  8. package/dist/scripts/nodeSetup.js.map +1 -1
  9. package/dist/src/core/dry-run-executor.d.ts.map +1 -1
  10. package/dist/src/core/dry-run-executor.js +15 -13
  11. package/dist/src/core/dry-run-executor.js.map +1 -1
  12. package/dist/src/core/interfaces/command-options.interface.d.ts +1 -0
  13. package/dist/src/core/interfaces/command-options.interface.d.ts.map +1 -1
  14. package/dist/src/core/interfaces/generator-context.interface.d.ts +1 -0
  15. package/dist/src/core/interfaces/generator-context.interface.d.ts.map +1 -1
  16. package/dist/src/core/package-resolver.d.ts.map +1 -1
  17. package/dist/src/core/package-resolver.js +4 -2
  18. package/dist/src/core/package-resolver.js.map +1 -1
  19. package/dist/src/core/plugin-manager.d.ts.map +1 -1
  20. package/dist/src/core/plugin-manager.js +4 -2
  21. package/dist/src/core/plugin-manager.js.map +1 -1
  22. package/dist/src/core/project-generator.d.ts +7 -7
  23. package/dist/src/core/project-generator.d.ts.map +1 -1
  24. package/dist/src/core/project-generator.js +14 -14
  25. package/dist/src/core/project-generator.js.map +1 -1
  26. package/dist/src/core/step-executor.d.ts.map +1 -1
  27. package/dist/src/core/step-executor.js +10 -8
  28. package/dist/src/core/step-executor.js.map +1 -1
  29. package/dist/src/generate-monorepo.d.ts.map +1 -1
  30. package/dist/src/generate-monorepo.js +176 -119
  31. package/dist/src/generate-monorepo.js.map +1 -1
  32. package/dist/src/i18n/i18n-setup.d.ts +12 -0
  33. package/dist/src/i18n/i18n-setup.d.ts.map +1 -0
  34. package/dist/src/i18n/i18n-setup.js +69 -0
  35. package/dist/src/i18n/i18n-setup.js.map +1 -0
  36. package/dist/src/i18n/index.d.ts +4 -0
  37. package/dist/src/i18n/index.d.ts.map +1 -0
  38. package/dist/src/i18n/index.js +20 -0
  39. package/dist/src/i18n/index.js.map +1 -0
  40. package/dist/src/i18n/starter-string-key.d.ts +161 -0
  41. package/dist/src/i18n/starter-string-key.d.ts.map +1 -0
  42. package/dist/src/i18n/starter-string-key.js +186 -0
  43. package/dist/src/i18n/starter-string-key.js.map +1 -0
  44. package/dist/src/i18n/translations-all.d.ts +179 -0
  45. package/dist/src/i18n/translations-all.d.ts.map +1 -0
  46. package/dist/src/i18n/translations-all.js +30 -0
  47. package/dist/src/i18n/translations-all.js.map +1 -0
  48. package/dist/src/i18n/translations-de.d.ts +3 -0
  49. package/dist/src/i18n/translations-de.d.ts.map +1 -0
  50. package/dist/src/i18n/translations-de.js +165 -0
  51. package/dist/src/i18n/translations-de.js.map +1 -0
  52. package/dist/src/i18n/translations-en-gb.d.ts +161 -0
  53. package/dist/src/i18n/translations-en-gb.d.ts.map +1 -0
  54. package/dist/src/i18n/translations-en-gb.js +7 -0
  55. package/dist/src/i18n/translations-en-gb.js.map +1 -0
  56. package/dist/src/i18n/translations-en-us.d.ts +3 -0
  57. package/dist/src/i18n/translations-en-us.d.ts.map +1 -0
  58. package/dist/src/i18n/translations-en-us.js +186 -0
  59. package/dist/src/i18n/translations-en-us.js.map +1 -0
  60. package/dist/src/i18n/translations-es.d.ts +3 -0
  61. package/dist/src/i18n/translations-es.d.ts.map +1 -0
  62. package/dist/src/i18n/translations-es.js +165 -0
  63. package/dist/src/i18n/translations-es.js.map +1 -0
  64. package/dist/src/i18n/translations-fr.d.ts +3 -0
  65. package/dist/src/i18n/translations-fr.d.ts.map +1 -0
  66. package/dist/src/i18n/translations-fr.js +165 -0
  67. package/dist/src/i18n/translations-fr.js.map +1 -0
  68. package/dist/src/i18n/translations-ja.d.ts +3 -0
  69. package/dist/src/i18n/translations-ja.d.ts.map +1 -0
  70. package/dist/src/i18n/translations-ja.js +165 -0
  71. package/dist/src/i18n/translations-ja.js.map +1 -0
  72. package/dist/src/i18n/translations-uk.d.ts +3 -0
  73. package/dist/src/i18n/translations-uk.d.ts.map +1 -0
  74. package/dist/src/i18n/translations-uk.js +165 -0
  75. package/dist/src/i18n/translations-uk.js.map +1 -0
  76. package/dist/src/i18n/translations-zh-cn.d.ts +3 -0
  77. package/dist/src/i18n/translations-zh-cn.d.ts.map +1 -0
  78. package/dist/src/i18n/translations-zh-cn.js +165 -0
  79. package/dist/src/i18n/translations-zh-cn.js.map +1 -0
  80. package/dist/src/utils/shell-utils.d.ts.map +1 -1
  81. package/dist/src/utils/shell-utils.js +5 -0
  82. package/dist/src/utils/shell-utils.js.map +1 -1
  83. package/dist/src/utils/system-check.d.ts.map +1 -1
  84. package/dist/src/utils/system-check.js +9 -10
  85. package/dist/src/utils/system-check.js.map +1 -1
  86. package/dist/src/utils/template-renderer.d.ts +2 -2
  87. package/dist/src/utils/template-renderer.d.ts.map +1 -1
  88. package/dist/src/utils/template-renderer.js +26 -14
  89. package/dist/src/utils/template-renderer.js.map +1 -1
  90. package/package.json +1 -1
@@ -57,22 +57,44 @@ const nodeSetup_1 = require("../scripts/nodeSetup");
57
57
  const licensePrompt_1 = require("../scripts/licensePrompt");
58
58
  const addScriptsToPackageJson_1 = require("../scripts/addScriptsToPackageJson");
59
59
  const templateUtils_1 = require("../scripts/templateUtils");
60
+ const i18n_1 = require("./i18n");
61
+ const i18n_lib_1 = require("@digitaldefiance/i18n-lib");
62
+ const i18n_lib_2 = require("@digitaldefiance/i18n-lib");
60
63
  async function main() {
61
64
  (0, albatross_1.printBanner)();
62
65
  (0, nodeSetup_1.checkAndUseNode)();
63
66
  // Disable Yarn build scripts globally to avoid native module issues
64
67
  process.env.YARN_ENABLE_SCRIPTS = 'false';
68
+ // Language selection
69
+ const selectedLanguage = await (0, select_1.default)({
70
+ message: 'Select language / Seleccionar idioma / Choisir la langue / Sprache wählen / 选择语言 / 言語を選択 / Виберіть мову:',
71
+ choices: [
72
+ { name: 'English (US)', value: i18n_lib_2.LanguageCodes.EN_US },
73
+ { name: 'English (UK)', value: i18n_lib_2.LanguageCodes.EN_GB },
74
+ { name: 'Español', value: i18n_lib_2.LanguageCodes.ES },
75
+ { name: 'Français', value: i18n_lib_2.LanguageCodes.FR },
76
+ { name: 'Deutsch', value: i18n_lib_2.LanguageCodes.DE },
77
+ { name: '中文', value: i18n_lib_2.LanguageCodes.ZH_CN },
78
+ { name: '日本語', value: i18n_lib_2.LanguageCodes.JA },
79
+ { name: 'Українська', value: i18n_lib_2.LanguageCodes.UK },
80
+ ],
81
+ default: i18n_lib_2.LanguageCodes.EN_US,
82
+ });
83
+ // Set the language for the i18n engine
84
+ const i18nEngine = (0, i18n_1.getStarterI18nEngine)();
85
+ i18nEngine.setLanguage(selectedLanguage);
86
+ (0, albatross_1.printIntro)();
65
87
  // System check
66
- logger_1.Logger.header('System Check');
88
+ logger_1.Logger.header((0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.SYSTEM_CHECK_HEADER));
67
89
  const systemCheck = system_check_1.SystemCheck.check();
68
90
  system_check_1.SystemCheck.printReport(systemCheck);
69
91
  if (!systemCheck.passed) {
70
92
  const proceed = await (0, confirm_1.default)({
71
- message: 'Continue anyway? (Installation may fail)',
93
+ message: (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.SYSTEM_CHECK_CONTINUE_ANYWAY),
72
94
  default: false,
73
95
  });
74
96
  if (!proceed) {
75
- logger_1.Logger.info('Cancelled. Please install required tools and try again.');
97
+ logger_1.Logger.info((0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.CLI_CANCELLED));
76
98
  process.exit(0);
77
99
  }
78
100
  }
@@ -80,49 +102,49 @@ async function main() {
80
102
  const presetPath = path.resolve(__dirname, '../../config/presets/standard.json');
81
103
  const preset = JSON.parse(fs.readFileSync(presetPath, 'utf-8'));
82
104
  // Prompt for workspace configuration
83
- logger_1.Logger.header('Workspace Configuration');
105
+ logger_1.Logger.header((0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.SECTION_WORKSPACE_CONFIG));
84
106
  const workspaceName = await (0, input_1.default)({
85
- message: 'Enter the workspace name:',
107
+ message: (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.PROMPT_WORKSPACE_NAME),
86
108
  default: 'example-project',
87
- validate: (val) => config_schema_1.ConfigValidator.validateWorkspaceName(val) || 'Invalid workspace name (letters, numbers, dashes only)',
109
+ validate: (val) => config_schema_1.ConfigValidator.validateWorkspaceName(val) || (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.VALIDATION_INVALID_WORKSPACE_NAME),
88
110
  });
89
111
  const projectPrefix = await (0, input_1.default)({
90
- message: 'Enter the project prefix:',
112
+ message: (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.PROMPT_PROJECT_PREFIX),
91
113
  default: workspaceName,
92
- validate: (val) => config_schema_1.ConfigValidator.validatePrefix(val) || 'Invalid prefix (lowercase letters, numbers, dashes only)',
114
+ validate: (val) => config_schema_1.ConfigValidator.validatePrefix(val) || (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.VALIDATION_INVALID_PREFIX),
93
115
  });
94
116
  const namespaceRoot = await (0, input_1.default)({
95
- message: 'Enter the npm namespace:',
117
+ message: (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.PROMPT_NPM_NAMESPACE),
96
118
  default: `@${projectPrefix}`,
97
- validate: (val) => config_schema_1.ConfigValidator.validateNamespace(val) || 'Invalid namespace (must start with @)',
119
+ validate: (val) => config_schema_1.ConfigValidator.validateNamespace(val) || (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.VALIDATION_INVALID_NAMESPACE),
98
120
  });
99
121
  const parentDir = path.resolve(await (0, input_1.default)({
100
- message: 'Enter the parent directory:',
122
+ message: (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.PROMPT_PARENT_DIRECTORY),
101
123
  default: process.cwd(),
102
124
  }));
103
125
  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',
126
+ message: (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.PROMPT_GIT_REPO),
127
+ validate: (val) => config_schema_1.ConfigValidator.validateGitRepo(val) || (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.VALIDATION_INVALID_GIT_REPO),
106
128
  });
107
129
  const hostname = await (0, input_1.default)({
108
- message: 'Enter the hostname for development (e.g., example-project.local):',
130
+ message: (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.PROMPT_HOSTNAME),
109
131
  default: `${workspaceName}.local`,
110
- validate: (val) => /^[a-z0-9-]+(\.[a-z0-9-]+)*$/.test(val) || 'Invalid hostname format',
132
+ validate: (val) => /^[a-z0-9-]+(\.[a-z0-9-]+)*$/.test(val) || (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.VALIDATION_INVALID_HOSTNAME),
111
133
  });
112
134
  const dryRun = await (0, confirm_1.default)({
113
- message: 'Run in dry-run mode (preview without creating files)?',
135
+ message: (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.PROMPT_DRY_RUN),
114
136
  default: false,
115
137
  });
116
- logger_1.Logger.section('Optional Projects');
138
+ logger_1.Logger.section((0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.SECTION_OPTIONAL_PROJECTS));
117
139
  const includeE2e = await (0, confirm_1.default)({
118
- message: 'Include E2E tests?',
140
+ message: (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.PROMPT_INCLUDE_E2E),
119
141
  default: true,
120
142
  });
121
- logger_1.Logger.section('Package Groups');
143
+ logger_1.Logger.section((0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.SECTION_PACKAGE_GROUPS));
122
144
  const packageGroupsPath = path.resolve(__dirname, '../../config/package-groups.json');
123
145
  const packageGroups = JSON.parse(fs.readFileSync(packageGroupsPath, 'utf-8')).groups;
124
146
  const selectedGroups = await (0, checkbox_1.default)({
125
- message: 'Select optional package groups:',
147
+ message: (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.PROMPT_SELECT_PACKAGE_GROUPS),
126
148
  choices: packageGroups
127
149
  .filter((g) => !g.enabled)
128
150
  .map((g) => ({
@@ -132,70 +154,70 @@ async function main() {
132
154
  })),
133
155
  });
134
156
  const enableDocGeneration = await (0, confirm_1.default)({
135
- message: 'Generate documentation (README, ARCHITECTURE, API docs)?',
157
+ message: (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.PROMPT_ENABLE_DOC_GENERATION),
136
158
  default: true,
137
159
  });
138
- logger_1.Logger.section('DevContainer Configuration');
160
+ logger_1.Logger.section((0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.SECTION_DEVCONTAINER_CONFIG));
139
161
  const setupDevcontainer = await (0, confirm_1.default)({
140
- message: 'Set up DevContainer configuration?',
162
+ message: (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.PROMPT_SETUP_DEVCONTAINER),
141
163
  default: true,
142
164
  });
143
165
  let devcontainerChoice = 'none';
144
166
  let mongoPassword = '';
145
167
  if (setupDevcontainer) {
146
168
  devcontainerChoice = await (0, select_1.default)({
147
- message: 'DevContainer configuration:',
169
+ message: (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.PROMPT_DEVCONTAINER_CONFIG),
148
170
  choices: [
149
- { name: 'Simple (Node.js only)', value: 'simple' },
150
- { name: 'With MongoDB', value: 'mongodb' },
151
- { name: 'With MongoDB Replica Set', value: 'mongodb-replicaset' },
171
+ { name: (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.DEVCONTAINER_SIMPLE), value: 'simple' },
172
+ { name: (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.DEVCONTAINER_MONGODB), value: 'mongodb' },
173
+ { name: (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.DEVCONTAINER_MONGODB_REPLICASET), value: 'mongodb-replicaset' },
152
174
  ],
153
175
  default: 'mongodb-replicaset',
154
176
  });
155
177
  if (devcontainerChoice === 'mongodb' || devcontainerChoice === 'mongodb-replicaset') {
156
178
  mongoPassword = await (0, input_1.default)({
157
- message: 'Enter MongoDB root password:',
158
- validate: (val) => val.length > 0 || 'Password required',
179
+ message: (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.PROMPT_MONGO_PASSWORD),
180
+ validate: (val) => val.length > 0 || (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.VALIDATION_PASSWORD_REQUIRED),
159
181
  });
160
182
  }
161
183
  }
162
- logger_1.Logger.section('Database Configuration');
184
+ logger_1.Logger.section((0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.SECTION_DATABASE_CONFIG));
163
185
  const useInMemoryDb = await (0, confirm_1.default)({
164
- message: 'Use in-memory database for development?',
186
+ message: (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.PROMPT_USE_IN_MEMORY_DB),
165
187
  default: false,
166
188
  });
167
189
  let devDatabaseName = '';
168
190
  if (useInMemoryDb) {
169
191
  devDatabaseName = await (0, input_1.default)({
170
- message: 'Enter the in-memory database name:',
192
+ message: (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.PROMPT_DEV_DATABASE_NAME),
171
193
  default: 'test',
172
- validate: (val) => val.length > 0 || 'Database name cannot be empty',
194
+ validate: (val) => val.length > 0 || (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.VALIDATION_DATABASE_NAME_REQUIRED),
173
195
  });
174
196
  }
175
- logger_1.Logger.section('Security Configuration');
197
+ logger_1.Logger.section((0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.SECTION_SECURITY_CONFIG));
176
198
  const crypto = await Promise.resolve().then(() => __importStar(require('crypto')));
177
199
  const HEX_64_REGEX = /^[0-9a-f]{64}$/i;
178
200
  const promptOrGenerateSecret = async (name) => {
179
201
  const generate = await (0, confirm_1.default)({
180
- message: `Generate ${name}?`,
202
+ message: (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.PROMPT_GENERATE_SECRET, { name }),
181
203
  default: true,
182
204
  });
183
205
  if (generate) {
184
206
  const secret = crypto.randomBytes(32).toString('hex');
185
- logger_1.Logger.info(`Generated ${name}`);
207
+ logger_1.Logger.info((0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.ENV_GENERATED_SECRET, { name }));
186
208
  return secret;
187
209
  }
188
210
  else {
189
211
  return await (0, input_1.default)({
190
- message: `Enter ${name} (64-character hex string):`,
191
- validate: (val) => HEX_64_REGEX.test(val) || 'Must be 64-character hex string',
212
+ message: (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.PROMPT_ENTER_SECRET, { name }),
213
+ validate: (val) => HEX_64_REGEX.test(val) || (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.VALIDATION_MUST_BE_HEX_64),
192
214
  });
193
215
  }
194
216
  };
195
217
  const jwtSecret = await promptOrGenerateSecret('JWT_SECRET');
196
218
  const mnemonicEncryptionKey = await promptOrGenerateSecret('MNEMONIC_ENCRYPTION_KEY');
197
219
  const mnemonicHmacSecret = await promptOrGenerateSecret('MNEMONIC_HMAC_SECRET');
198
- logger_1.Logger.section('Express Suite Packages');
220
+ logger_1.Logger.section((0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.SECTION_EXPRESS_SUITE_PACKAGES));
199
221
  const monorepoPath = path.join(parentDir, workspaceName);
200
222
  // Build project configurations
201
223
  const projects = project_config_builder_1.ProjectConfigBuilder.build(projectPrefix, namespaceRoot, {
@@ -237,6 +259,7 @@ async function main() {
237
259
  config,
238
260
  state: new Map(stateEntries),
239
261
  checkpointPath: path.join(parentDir, `.${workspaceName}.checkpoint`),
262
+ dryRun,
240
263
  };
241
264
  // Merge selected package groups
242
265
  const additionalPackages = [];
@@ -260,56 +283,56 @@ async function main() {
260
283
  ? new (await Promise.resolve().then(() => __importStar(require('./core/dry-run-executor')))).DryRunExecutor()
261
284
  : new step_executor_1.StepExecutor();
262
285
  if (dryRun) {
263
- logger_1.Logger.warning('DRY RUN MODE - No files will be created');
286
+ logger_1.Logger.warning((0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.GENERATION_DRY_RUN_MODE));
264
287
  }
265
288
  executor.addStep({
266
289
  name: 'checkTargetDir',
267
- description: 'Checking target directory',
290
+ description: (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.STEP_CHECK_TARGET_DIR),
268
291
  execute: () => {
269
292
  if (fs.existsSync(monorepoPath) && fs.readdirSync(monorepoPath).length > 0) {
270
- throw new Error(`Directory ${logger_1.Logger.path(monorepoPath)} already exists and is not empty`);
293
+ throw new i18n_lib_1.TranslatableGenericError(i18n_1.StarterComponentId, i18n_1.StarterStringKey.ERROR_DIRECTORY_NOT_EMPTY, { path: monorepoPath });
271
294
  }
272
295
  },
273
296
  });
274
297
  executor.addStep({
275
298
  name: 'createMonorepo',
276
- description: 'Creating Nx monorepo',
277
- execute: () => {
278
- (0, shell_utils_1.runCommand)(`npx create-nx-workspace@latest "${workspaceName}" --package-manager=yarn --preset=apps --ci=${config.nx?.ciProvider}`, { cwd: parentDir });
299
+ description: (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.STEP_CREATE_MONOREPO),
300
+ execute: (context) => {
301
+ (0, shell_utils_1.runCommand)(`npx create-nx-workspace@latest "${workspaceName}" --package-manager=yarn --preset=apps --ci=${config.nx?.ciProvider}`, { cwd: parentDir, dryRun: context.dryRun });
279
302
  },
280
303
  });
281
304
  executor.addStep({
282
305
  name: 'setupGitOrigin',
283
- description: 'Setting up git remote',
306
+ description: (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.STEP_SETUP_GIT_ORIGIN),
284
307
  skip: () => !gitRepo,
285
308
  execute: () => {
286
- (0, shell_utils_1.runCommand)(`git remote add origin ${gitRepo}`, { cwd: monorepoPath });
309
+ (0, shell_utils_1.runCommand)(`git remote add origin ${gitRepo}`, { cwd: monorepoPath, dryRun: context.dryRun });
287
310
  },
288
311
  });
289
312
  executor.addStep({
290
313
  name: 'yarnBerrySetup',
291
- description: 'Configuring Yarn Berry',
314
+ description: (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.STEP_YARN_BERRY_SETUP),
292
315
  execute: () => {
293
- (0, shell_utils_1.runCommand)('yarn set version berry', { cwd: monorepoPath });
294
- (0, shell_utils_1.runCommand)('yarn config set nodeLinker node-modules', { cwd: monorepoPath });
295
- (0, shell_utils_1.runCommand)('yarn', { cwd: monorepoPath });
316
+ (0, shell_utils_1.runCommand)('yarn set version berry', { cwd: monorepoPath, dryRun: context.dryRun });
317
+ (0, shell_utils_1.runCommand)('yarn config set nodeLinker node-modules', { cwd: monorepoPath, dryRun: context.dryRun });
318
+ (0, shell_utils_1.runCommand)('yarn', { cwd: monorepoPath, dryRun: context.dryRun });
296
319
  },
297
320
  });
298
321
  executor.addStep({
299
322
  name: 'addNxPlugins',
300
- description: 'Installing Nx plugins',
323
+ description: (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.STEP_ADD_NX_PLUGINS),
301
324
  execute: () => {
302
325
  try {
303
- (0, shell_utils_1.runCommand)('yarn add -D @nx/react @nx/node', { cwd: monorepoPath });
326
+ (0, shell_utils_1.runCommand)('yarn add -D @nx/react @nx/node', { cwd: monorepoPath, dryRun: context.dryRun });
304
327
  }
305
328
  catch (error) {
306
329
  if (error.status === 1) {
307
- logger_1.Logger.error('\nPackage installation failed.');
308
- logger_1.Logger.section('If you see "exit code 127" above, install build tools:');
309
- logger_1.Logger.dim(' Ubuntu/Debian: sudo apt-get install build-essential python3');
310
- logger_1.Logger.dim(' Fedora/RHEL: sudo dnf install gcc-c++ make python3');
311
- logger_1.Logger.dim(' macOS: xcode-select --install');
312
- logger_1.Logger.section('\nThen retry or skip: yarn start --start-at=addYarnPackages');
330
+ logger_1.Logger.error('\n' + (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.PACKAGE_INSTALLATION_FAILED));
331
+ logger_1.Logger.section((0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.PACKAGE_INSTALL_BUILD_TOOLS));
332
+ logger_1.Logger.dim(' ' + (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.SYSTEM_CHECK_UBUNTU_DEBIAN));
333
+ logger_1.Logger.dim(' ' + (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.SYSTEM_CHECK_FEDORA_RHEL));
334
+ logger_1.Logger.dim(' ' + (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.SYSTEM_CHECK_MACOS));
335
+ logger_1.Logger.section('\n' + (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.PACKAGE_RETRY_OR_SKIP));
313
336
  }
314
337
  throw error;
315
338
  }
@@ -317,44 +340,44 @@ async function main() {
317
340
  });
318
341
  executor.addStep({
319
342
  name: 'addYarnPackages',
320
- description: 'Installing dependencies',
343
+ description: (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.STEP_ADD_YARN_PACKAGES),
321
344
  execute: () => {
322
345
  const devPkgs = config.packages?.dev || [];
323
346
  const prodPkgs = config.packages?.prod || [];
324
347
  if (devPkgs.length > 0) {
325
- (0, shell_utils_1.runCommand)(`yarn add -D ${devPkgs.join(' ')}`, { cwd: monorepoPath });
348
+ (0, shell_utils_1.runCommand)(`yarn add -D ${devPkgs.join(' ')}`, { cwd: monorepoPath, dryRun: context.dryRun });
326
349
  }
327
350
  if (prodPkgs.length > 0) {
328
- (0, shell_utils_1.runCommand)(`yarn add ${prodPkgs.join(' ')}`, { cwd: monorepoPath });
351
+ (0, shell_utils_1.runCommand)(`yarn add ${prodPkgs.join(' ')}`, { cwd: monorepoPath, dryRun: context.dryRun });
329
352
  }
330
353
  },
331
354
  });
332
355
  executor.addStep({
333
356
  name: 'generateProjects',
334
- description: 'Generating project structure',
357
+ description: (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.STEP_GENERATE_PROJECTS),
335
358
  execute: () => {
336
359
  projects.forEach(project => {
337
360
  if (!project.enabled)
338
361
  return;
339
- logger_1.Logger.info(`Generating ${project.type}: ${project.name}`);
362
+ logger_1.Logger.info((0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.PROJECT_GENERATING, { type: project.type, name: project.name }));
340
363
  switch (project.type) {
341
364
  case 'react':
342
- project_generator_1.ProjectGenerator.generateReact(project, monorepoPath, config.nx);
365
+ project_generator_1.ProjectGenerator.generateReact(project, monorepoPath, config.nx, context.dryRun);
343
366
  break;
344
367
  case 'react-lib':
345
- project_generator_1.ProjectGenerator.generateReactLib(project, monorepoPath, config.nx);
368
+ project_generator_1.ProjectGenerator.generateReactLib(project, monorepoPath, config.nx, context.dryRun);
346
369
  break;
347
370
  case 'api':
348
- project_generator_1.ProjectGenerator.generateApi(project, monorepoPath, config.nx);
371
+ project_generator_1.ProjectGenerator.generateApi(project, monorepoPath, config.nx, context.dryRun);
349
372
  break;
350
373
  case 'api-lib':
351
- project_generator_1.ProjectGenerator.generateApiLib(project, monorepoPath, config.nx);
374
+ project_generator_1.ProjectGenerator.generateApiLib(project, monorepoPath, config.nx, context.dryRun);
352
375
  break;
353
376
  case 'lib':
354
- project_generator_1.ProjectGenerator.generateLib(project, monorepoPath, config.nx);
377
+ project_generator_1.ProjectGenerator.generateLib(project, monorepoPath, config.nx, context.dryRun);
355
378
  break;
356
379
  case 'inituserdb':
357
- project_generator_1.ProjectGenerator.generateInitUserDb(project, monorepoPath);
380
+ project_generator_1.ProjectGenerator.generateInitUserDb(project, monorepoPath, context.dryRun);
358
381
  break;
359
382
  }
360
383
  });
@@ -389,7 +412,7 @@ async function main() {
389
412
  }
390
413
  }
391
414
  fs.writeFileSync(projectJsonPath, JSON.stringify(projectJson, null, 2) + '\n');
392
- logger_1.Logger.info(`Added copy-env and post-build targets to ${apiProject.name}/project.json`);
415
+ logger_1.Logger.info((0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.PROJECT_ADDED_TARGETS, { name: apiProject.name }));
393
416
  }
394
417
  }
395
418
  if (initUserDbProject) {
@@ -424,30 +447,30 @@ async function main() {
424
447
  }
425
448
  }
426
449
  fs.writeFileSync(projectJsonPath, JSON.stringify(projectJson, null, 2) + '\n');
427
- logger_1.Logger.info(`Added copy-env and post-build targets to ${initUserDbProject.name}/project.json`);
450
+ logger_1.Logger.info((0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.PROJECT_ADDED_TARGETS, { name: initUserDbProject.name }));
428
451
  }
429
452
  }
430
453
  },
431
454
  });
432
455
  executor.addStep({
433
456
  name: 'installReactComponents',
434
- description: 'Installing React components package',
457
+ description: (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.STEP_INSTALL_REACT_COMPONENTS),
435
458
  execute: () => {
436
459
  const reactLibProject = projects.find(p => p.type === 'react-lib' && p.enabled);
437
460
  if (reactLibProject) {
438
- logger_1.Logger.info(`Installing @digitaldefiance/express-suite-react-components in ${reactLibProject.name}`);
461
+ logger_1.Logger.info((0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.PROJECT_INSTALLING_PACKAGE, { package: '@digitaldefiance/express-suite-react-components', project: reactLibProject.name }));
439
462
  const projectPackageJsonPath = path.join(monorepoPath, reactLibProject.name, 'package.json');
440
463
  const projectPackageJson = JSON.parse(fs.readFileSync(projectPackageJsonPath, 'utf-8'));
441
464
  projectPackageJson.dependencies = projectPackageJson.dependencies || {};
442
465
  projectPackageJson.dependencies['@digitaldefiance/express-suite-react-components'] = 'latest';
443
466
  fs.writeFileSync(projectPackageJsonPath, JSON.stringify(projectPackageJson, null, 2) + '\n');
444
- (0, shell_utils_1.runCommand)('yarn install', { cwd: monorepoPath });
467
+ (0, shell_utils_1.runCommand)('yarn install', { cwd: monorepoPath, dryRun: context.dryRun });
445
468
  }
446
469
  },
447
470
  });
448
471
  executor.addStep({
449
472
  name: 'renderTemplates',
450
- description: 'Rendering configuration templates',
473
+ description: (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.STEP_RENDER_TEMPLATES),
451
474
  execute: () => {
452
475
  const variables = {
453
476
  WORKSPACE_NAME: workspaceName,
@@ -464,12 +487,12 @@ async function main() {
464
487
  const key = project.type === 'lib' ? 'LIB_NAME' : `${project.type.toUpperCase().replace(/-/g, '_')}_NAME`;
465
488
  variables[key] = project.name;
466
489
  });
467
- (0, template_renderer_1.renderTemplates)(context.state.get('templatesDir'), monorepoPath, variables, config.templates?.engine);
490
+ (0, template_renderer_1.renderTemplates)(context.state.get('templatesDir'), monorepoPath, variables, config.templates?.engine, context.dryRun);
468
491
  },
469
492
  });
470
493
  executor.addStep({
471
494
  name: 'copyScaffolding',
472
- description: 'Copying scaffolding files',
495
+ description: (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.STEP_COPY_SCAFFOLDING),
473
496
  execute: () => {
474
497
  const scaffoldingDir = context.state.get('scaffoldingDir');
475
498
  // Template variables for scaffolding
@@ -483,35 +506,35 @@ async function main() {
483
506
  // Copy root scaffolding
484
507
  const rootSrc = path.join(scaffoldingDir, 'root');
485
508
  if (fs.existsSync(rootSrc)) {
486
- (0, template_renderer_1.copyDir)(rootSrc, monorepoPath, scaffoldingVars);
509
+ (0, template_renderer_1.copyDir)(rootSrc, monorepoPath, scaffoldingVars, 'mustache', context.dryRun);
487
510
  }
488
511
  // Copy devcontainer configuration
489
512
  if (devcontainerChoice !== 'none') {
490
513
  const devcontainerSrc = path.join(scaffoldingDir, `devcontainer-${devcontainerChoice}`);
491
514
  if (fs.existsSync(devcontainerSrc)) {
492
515
  logger_1.Logger.info(`Copying devcontainer configuration: ${devcontainerChoice}`);
493
- (0, template_renderer_1.copyDir)(devcontainerSrc, monorepoPath, scaffoldingVars);
516
+ (0, template_renderer_1.copyDir)(devcontainerSrc, monorepoPath, scaffoldingVars, 'mustache', context.dryRun);
494
517
  }
495
518
  }
496
519
  // Copy project-specific scaffolding
497
520
  projects.forEach(project => {
498
521
  const projectSrc = path.join(scaffoldingDir, project.type);
499
522
  if (fs.existsSync(projectSrc)) {
500
- (0, template_renderer_1.copyDir)(projectSrc, path.join(monorepoPath, project.name), scaffoldingVars);
523
+ (0, template_renderer_1.copyDir)(projectSrc, path.join(monorepoPath, project.name), scaffoldingVars, 'mustache', context.dryRun);
501
524
  }
502
525
  });
503
526
  },
504
527
  });
505
528
  executor.addStep({
506
529
  name: 'generateLicense',
507
- description: 'Generating LICENSE file',
530
+ description: (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.STEP_GENERATE_LICENSE),
508
531
  execute: async () => {
509
532
  await (0, licensePrompt_1.promptAndGenerateLicense)(monorepoPath);
510
533
  },
511
534
  });
512
535
  executor.addStep({
513
536
  name: 'addScripts',
514
- description: 'Adding package.json scripts',
537
+ description: (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.STEP_ADD_SCRIPTS),
515
538
  execute: () => {
516
539
  const packageJsonPath = path.join(monorepoPath, 'package.json');
517
540
  const scriptContext = {
@@ -553,7 +576,7 @@ async function main() {
553
576
  });
554
577
  executor.addStep({
555
578
  name: 'generateDocumentation',
556
- description: 'Generating documentation',
579
+ description: (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.STEP_GENERATE_DOCUMENTATION),
557
580
  skip: () => !enableDocGeneration || dryRun,
558
581
  execute: async () => {
559
582
  const { DocGenerator } = await Promise.resolve().then(() => __importStar(require('./utils/doc-generator')));
@@ -562,13 +585,13 @@ async function main() {
562
585
  });
563
586
  executor.addStep({
564
587
  name: 'setupEnvironment',
565
- description: 'Setting up environment files',
588
+ description: (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.STEP_SETUP_ENVIRONMENT),
566
589
  execute: () => {
567
590
  const apiProject = projects.find(p => p.type === 'api');
568
591
  const initUserDbProject = projects.find(p => p.type === 'inituserdb');
569
- // Build MONGO_URI with optional password
592
+ // Build MONGO_URI with optional password (URL-encode password for special characters)
570
593
  const buildMongoUri = (dbName) => {
571
- const auth = mongoPassword ? `root:${mongoPassword}@` : '';
594
+ const auth = mongoPassword ? `root:${encodeURIComponent(mongoPassword)}@` : '';
572
595
  const params = devcontainerChoice === 'mongodb-replicaset'
573
596
  ? '?replicaSet=rs0&directConnection=true'
574
597
  : '?directConnection=true';
@@ -596,6 +619,13 @@ async function main() {
596
619
  const mongoUri = buildMongoUri(workspaceName);
597
620
  envContent = envContent.replace(/MONGO_URI=.*/g, `MONGO_URI=${mongoUri}`);
598
621
  }
622
+ // Enable transactions for replica set
623
+ if (devcontainerChoice === 'mongodb-replicaset') {
624
+ envContent = envContent.replace(/MONGO_USE_TRANSACTIONS=.*/g, 'MONGO_USE_TRANSACTIONS=true');
625
+ }
626
+ else {
627
+ envContent = envContent.replace(/MONGO_USE_TRANSACTIONS=.*/g, 'MONGO_USE_TRANSACTIONS=false');
628
+ }
599
629
  fs.writeFileSync(envPath, envContent);
600
630
  logger_1.Logger.info(`Created ${apiProject.name}/.env with secrets`);
601
631
  }
@@ -611,58 +641,85 @@ async function main() {
611
641
  }
612
642
  // Setup devcontainer .env if devcontainer with MongoDB
613
643
  if (devcontainerChoice === 'mongodb' || devcontainerChoice === 'mongodb-replicaset') {
644
+ const devcontainerEnvExamplePath = path.join(monorepoPath, '.devcontainer', '.env.example');
614
645
  const devcontainerEnvPath = path.join(monorepoPath, '.devcontainer', '.env');
615
- const mongoUri = buildMongoUri(workspaceName);
616
- const envContent = `MONGO_PASSWORD=${mongoPassword}\nMONGO_URI=${mongoUri}\n`;
617
- fs.writeFileSync(devcontainerEnvPath, envContent);
618
- logger_1.Logger.info('Created .devcontainer/.env with MongoDB configuration');
646
+ if (fs.existsSync(devcontainerEnvExamplePath)) {
647
+ let envContent = fs.readFileSync(devcontainerEnvExamplePath, 'utf-8');
648
+ const mongoUri = buildMongoUri(workspaceName);
649
+ // Replace MongoDB configuration
650
+ envContent = envContent.replace(/MONGO_INITDB_ROOT_PASSWORD=.*/g, `MONGO_INITDB_ROOT_PASSWORD=${mongoPassword}`);
651
+ envContent = envContent.replace(/MONGO_INITDB_DATABASE=.*/g, `MONGO_INITDB_DATABASE=${workspaceName}`);
652
+ envContent = envContent.replace(/COMPOSE_PROJECT_NAME=.*/g, `COMPOSE_PROJECT_NAME=${workspaceName}_devcontainer`);
653
+ // Add MONGO_PASSWORD and MONGO_URI if not present
654
+ if (!envContent.includes('MONGO_PASSWORD=')) {
655
+ envContent += `\nMONGO_PASSWORD=${mongoPassword}\n`;
656
+ }
657
+ else {
658
+ envContent = envContent.replace(/MONGO_PASSWORD=.*/g, `MONGO_PASSWORD=${mongoPassword}`);
659
+ }
660
+ if (!envContent.includes('MONGO_URI=')) {
661
+ envContent += `MONGO_URI=${mongoUri}\n`;
662
+ }
663
+ else {
664
+ envContent = envContent.replace(/MONGO_URI=.*/g, `MONGO_URI=${mongoUri}`);
665
+ }
666
+ fs.writeFileSync(devcontainerEnvPath, envContent);
667
+ logger_1.Logger.info((0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.ENV_CREATED_DEVCONTAINER_FROM_EXAMPLE));
668
+ }
669
+ else {
670
+ // Fallback to minimal .env if .env.example doesn't exist
671
+ const mongoUri = buildMongoUri(workspaceName);
672
+ const envContent = `MONGO_PASSWORD=${mongoPassword}\nMONGO_URI=${mongoUri}\n`;
673
+ fs.writeFileSync(devcontainerEnvPath, envContent);
674
+ logger_1.Logger.warning((0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.ENV_CREATED_DEVCONTAINER_MINIMAL));
675
+ }
619
676
  }
620
677
  },
621
678
  });
622
679
  executor.addStep({
623
680
  name: 'rebuildNativeModules',
624
- description: 'Building native modules',
681
+ description: (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.STEP_REBUILD_NATIVE_MODULES),
625
682
  execute: () => {
626
- logger_1.Logger.info('Re-enabling build scripts and building native modules...');
627
- (0, shell_utils_1.runCommand)('yarn config set enableScripts true', { cwd: monorepoPath });
628
- (0, shell_utils_1.runCommand)('yarn rebuild', { cwd: monorepoPath });
683
+ logger_1.Logger.info((0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.COMMAND_REBUILDING_NATIVE));
684
+ (0, shell_utils_1.runCommand)('yarn config set enableScripts true', { cwd: monorepoPath, dryRun: context.dryRun });
685
+ (0, shell_utils_1.runCommand)('yarn rebuild', { cwd: monorepoPath, dryRun: context.dryRun });
629
686
  },
630
687
  });
631
688
  executor.addStep({
632
689
  name: 'validateGeneration',
633
- description: 'Validating generated project',
690
+ description: (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.STEP_VALIDATE_GENERATION),
634
691
  skip: () => dryRun,
635
692
  execute: async () => {
636
693
  const { PostGenerationValidator } = await Promise.resolve().then(() => __importStar(require('./core/validators/post-generation-validator')));
637
694
  const report = await PostGenerationValidator.validate(context);
638
695
  PostGenerationValidator.printReport(report);
639
696
  if (!report.passed) {
640
- logger_1.Logger.warning('Validation found errors, but continuing...');
697
+ logger_1.Logger.warning((0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.WARNING_VALIDATION_ERRORS));
641
698
  }
642
699
  },
643
700
  });
644
701
  executor.addStep({
645
702
  name: 'initialCommit',
646
- description: 'Creating initial commit',
703
+ description: (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.STEP_INITIAL_COMMIT),
647
704
  execute: async () => {
648
705
  // Ensure git is initialized
649
706
  if (!fs.existsSync(path.join(monorepoPath, '.git'))) {
650
- (0, shell_utils_1.runCommand)('git init', { cwd: monorepoPath });
707
+ (0, shell_utils_1.runCommand)('git init', { cwd: monorepoPath, dryRun: context.dryRun });
651
708
  }
652
709
  const doCommit = await (0, confirm_1.default)({
653
- message: 'Create initial git commit?',
710
+ message: (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.PROMPT_CREATE_INITIAL_COMMIT),
654
711
  default: true,
655
712
  });
656
713
  if (doCommit) {
657
- (0, shell_utils_1.runCommand)('git add -A', { cwd: monorepoPath });
658
- (0, shell_utils_1.runCommand)('git commit -m "Initial commit"', { cwd: monorepoPath });
714
+ (0, shell_utils_1.runCommand)('git add -A', { cwd: monorepoPath, dryRun: context.dryRun });
715
+ (0, shell_utils_1.runCommand)('git commit -m "Initial commit"', { cwd: monorepoPath, dryRun: context.dryRun });
659
716
  if (gitRepo) {
660
717
  const doPush = await (0, confirm_1.default)({
661
- message: 'Push to remote repository?',
718
+ message: (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.PROMPT_PUSH_TO_REMOTE),
662
719
  default: true,
663
720
  });
664
721
  if (doPush) {
665
- (0, shell_utils_1.runCommand)('git push --set-upstream origin main', { cwd: monorepoPath });
722
+ (0, shell_utils_1.runCommand)('git push --set-upstream origin main', { cwd: monorepoPath, dryRun: context.dryRun });
666
723
  }
667
724
  }
668
725
  }
@@ -670,19 +727,19 @@ async function main() {
670
727
  });
671
728
  executor.addStep({
672
729
  name: 'installPlaywright',
673
- description: 'Installing Playwright browsers',
730
+ description: (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.STEP_INSTALL_PLAYWRIGHT),
674
731
  skip: () => !includeE2e,
675
732
  execute: async () => {
676
733
  const installPlaywright = await (0, confirm_1.default)({
677
- message: 'Install Playwright browsers? (Required for E2E tests)',
734
+ message: (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.PROMPT_INSTALL_PLAYWRIGHT),
678
735
  default: true,
679
736
  });
680
737
  if (installPlaywright) {
681
- logger_1.Logger.info('Installing Playwright browsers (this may take a few minutes)...');
682
- (0, shell_utils_1.runCommand)('yarn playwright install --with-deps', { cwd: monorepoPath });
738
+ logger_1.Logger.info((0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.COMMAND_INSTALLING_PLAYWRIGHT_BROWSERS));
739
+ (0, shell_utils_1.runCommand)('yarn playwright install --with-deps', { cwd: monorepoPath, dryRun: context.dryRun });
683
740
  }
684
741
  else {
685
- logger_1.Logger.warning('Skipped. Run manually later: yarn playwright install --with-deps');
742
+ logger_1.Logger.warning((0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.COMMAND_SKIPPED_PLAYWRIGHT));
686
743
  }
687
744
  },
688
745
  });
@@ -690,26 +747,26 @@ async function main() {
690
747
  try {
691
748
  await executor.execute(context);
692
749
  if (dryRun) {
693
- logger_1.Logger.warning('Dry-run complete. Re-run without dry-run to generate.');
750
+ logger_1.Logger.warning((0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.WARNING_DRY_RUN_RERUN));
694
751
  process.exit(0);
695
752
  }
696
- logger_1.Logger.header('Generation Complete!');
697
- logger_1.Logger.success(`Monorepo created at: ${logger_1.Logger.path(monorepoPath)}`);
753
+ logger_1.Logger.header((0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.SUCCESS_GENERATION_COMPLETE));
754
+ logger_1.Logger.success((0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.SUCCESS_MONOREPO_CREATED, { path: logger_1.Logger.path(monorepoPath) }));
698
755
  const apiProject = projects.find(p => p.type === 'api');
699
756
  if (apiProject) {
700
- logger_1.Logger.warning(`\nIMPORTANT: Update ${apiProject.name}/.env with your configuration`);
757
+ logger_1.Logger.warning(`\n` + (0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.WARNING_UPDATE_ENV_FILE, { name: apiProject.name }));
701
758
  }
702
759
  if (devcontainerChoice === 'mongodb' || devcontainerChoice === 'mongodb-replicaset') {
703
- logger_1.Logger.warning(`IMPORTANT: Update .devcontainer/.env with your MongoDB configuration`);
760
+ logger_1.Logger.warning((0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.WARNING_UPDATE_DEVCONTAINER_ENV));
704
761
  }
705
- logger_1.Logger.section('Next steps:');
762
+ logger_1.Logger.section((0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.SECTION_NEXT_STEPS));
706
763
  logger_1.Logger.dim(` cd ${workspaceName}`);
707
764
  if (apiProject) {
708
- logger_1.Logger.dim(` # Update ${apiProject.name}/.env with your settings`);
765
+ logger_1.Logger.dim(` ${(0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.SECTION_NEXT_STEPS_UPDATE_ENV, { name: apiProject.name })}`);
709
766
  }
710
767
  logger_1.Logger.dim(` yarn build:dev`);
711
768
  logger_1.Logger.dim(` yarn serve:dev`);
712
- logger_1.Logger.section('Generated projects:');
769
+ logger_1.Logger.section((0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.SECTION_GENERATED_PROJECTS));
713
770
  projects.forEach(p => {
714
771
  if (p.enabled) {
715
772
  logger_1.Logger.dim(` ${p.type.padEnd(12)} ${p.name}`);
@@ -717,14 +774,14 @@ async function main() {
717
774
  });
718
775
  }
719
776
  catch (error) {
720
- logger_1.Logger.error('Generation failed');
777
+ logger_1.Logger.error((0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.GENERATION_FAILED));
721
778
  console.error(error);
722
779
  process.exit(1);
723
780
  }
724
781
  }
725
782
  if (require.main === module) {
726
783
  main().catch((err) => {
727
- logger_1.Logger.error('Fatal error');
784
+ logger_1.Logger.error((0, i18n_1.getStarterTranslation)(i18n_1.StarterStringKey.ERROR_FATAL));
728
785
  console.error(err);
729
786
  process.exit(1);
730
787
  });