create-tigra 2.7.0 → 2.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/create-tigra.js +110 -102
- package/package.json +1 -1
package/bin/create-tigra.js
CHANGED
|
@@ -123,13 +123,122 @@ function replaceVariables(content, variables) {
|
|
|
123
123
|
return result;
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
+
function registerAddCommand(program) {
|
|
127
|
+
program
|
|
128
|
+
.command('add <module>')
|
|
129
|
+
.description('Add a module to an existing Tigra project')
|
|
130
|
+
.action(async (moduleName) => {
|
|
131
|
+
console.log();
|
|
132
|
+
console.log(chalk.bold(' Create Tigra') + chalk.dim(` v${VERSION}`) + chalk.dim(' — add module'));
|
|
133
|
+
console.log();
|
|
134
|
+
|
|
135
|
+
const projectDir = process.cwd();
|
|
136
|
+
|
|
137
|
+
// Detect if we're inside a Tigra project
|
|
138
|
+
const hasServer = await fs.pathExists(path.join(projectDir, 'server', 'src', 'modules', 'auth'));
|
|
139
|
+
const hasClient = await fs.pathExists(path.join(projectDir, 'client', 'src', 'features', 'auth'));
|
|
140
|
+
|
|
141
|
+
if (!hasServer || !hasClient) {
|
|
142
|
+
console.error(chalk.red(' This does not appear to be a Tigra project.'));
|
|
143
|
+
console.error(chalk.dim(' Run this command from the root of your project (the folder containing server/ and client/).'));
|
|
144
|
+
console.log();
|
|
145
|
+
process.exit(1);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const availableModules = ['email-verification'];
|
|
149
|
+
|
|
150
|
+
if (!availableModules.includes(moduleName)) {
|
|
151
|
+
console.error(chalk.red(` Unknown module: "${moduleName}"`));
|
|
152
|
+
console.log();
|
|
153
|
+
console.log(chalk.dim(' Available modules:'));
|
|
154
|
+
for (const m of availableModules) {
|
|
155
|
+
console.log(chalk.cyan(` - ${m}`));
|
|
156
|
+
}
|
|
157
|
+
console.log();
|
|
158
|
+
process.exit(1);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (moduleName === 'email-verification') {
|
|
162
|
+
// Check if already applied
|
|
163
|
+
const alreadyApplied = await fs.pathExists(
|
|
164
|
+
path.join(projectDir, 'server', 'src', 'modules', 'auth', 'verification.service.ts'),
|
|
165
|
+
);
|
|
166
|
+
if (alreadyApplied) {
|
|
167
|
+
console.log(chalk.yellow(' Email verification is already installed in this project.'));
|
|
168
|
+
console.log();
|
|
169
|
+
process.exit(0);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const spinner = ora('Adding email verification module...').start();
|
|
173
|
+
|
|
174
|
+
try {
|
|
175
|
+
const { applyEmailVerificationModule } = await import(
|
|
176
|
+
'../lib/patchers/email-verification.patcher.js'
|
|
177
|
+
);
|
|
178
|
+
await applyEmailVerificationModule(projectDir);
|
|
179
|
+
|
|
180
|
+
// Set REQUIRE_USER_VERIFICATION=true in .env if it's currently false
|
|
181
|
+
for (const envFile of ['server/.env.example', 'server/.env']) {
|
|
182
|
+
const envPath = path.join(projectDir, envFile);
|
|
183
|
+
if (await fs.pathExists(envPath)) {
|
|
184
|
+
const content = await fs.readFile(envPath, 'utf-8');
|
|
185
|
+
if (content.includes('REQUIRE_USER_VERIFICATION=false')) {
|
|
186
|
+
await fs.writeFile(
|
|
187
|
+
envPath,
|
|
188
|
+
content.replace('REQUIRE_USER_VERIFICATION=false', 'REQUIRE_USER_VERIFICATION=true'),
|
|
189
|
+
'utf-8',
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
spinner.succeed('Email verification module added!');
|
|
196
|
+
} catch (error) {
|
|
197
|
+
spinner.fail('Failed to add email verification module');
|
|
198
|
+
console.error(chalk.red(`\n ${error.message}\n`));
|
|
199
|
+
process.exit(1);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const dim = chalk.dim;
|
|
203
|
+
const cyan = chalk.cyan;
|
|
204
|
+
const green = chalk.green;
|
|
205
|
+
|
|
206
|
+
console.log();
|
|
207
|
+
console.log(green(' ✓ ') + 'Files added:');
|
|
208
|
+
console.log(dim(' server/src/modules/auth/verification.service.ts'));
|
|
209
|
+
console.log(dim(' server/src/modules/auth/verification.controller.ts'));
|
|
210
|
+
console.log(dim(' client/src/features/auth/services/verification.service.ts'));
|
|
211
|
+
console.log(dim(' client/src/features/auth/hooks/useVerification.ts'));
|
|
212
|
+
console.log();
|
|
213
|
+
console.log(green(' ✓ ') + 'Files patched:');
|
|
214
|
+
console.log(dim(' auth.routes.ts, auth.schemas.ts, auth.service.ts, auth.repo.ts'));
|
|
215
|
+
console.log(dim(' rate-limit.config.ts, api-endpoints.ts, error.ts, useAuth.ts'));
|
|
216
|
+
console.log(dim(' postman/collection.json'));
|
|
217
|
+
console.log();
|
|
218
|
+
console.log(green(' ✓ ') + 'REQUIRE_USER_VERIFICATION=true in server/.env');
|
|
219
|
+
console.log();
|
|
220
|
+
console.log(dim(' Next steps:'));
|
|
221
|
+
console.log(cyan(' 1 ') + 'Set ' + chalk.bold('RESEND_API_KEY') + ' in server/.env');
|
|
222
|
+
console.log(cyan(' 2 ') + 'Restart the server');
|
|
223
|
+
console.log();
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
|
|
126
228
|
async function main() {
|
|
127
229
|
const program = new Command();
|
|
128
230
|
|
|
231
|
+
// Define the add subcommand BEFORE the default command so Commander recognizes it
|
|
129
232
|
program
|
|
130
233
|
.name('create-tigra')
|
|
131
234
|
.description('Create a production-ready full-stack app with Next.js + Fastify + Prisma + Redis')
|
|
132
|
-
.version(VERSION)
|
|
235
|
+
.version(VERSION);
|
|
236
|
+
|
|
237
|
+
// ─── Add module subcommand ────────────────────────────────────
|
|
238
|
+
registerAddCommand(program);
|
|
239
|
+
|
|
240
|
+
// ─── Default: scaffold new project ────────────────────────────
|
|
241
|
+
program
|
|
133
242
|
.argument('[project-name]', 'Name for your new project')
|
|
134
243
|
.action(async (projectNameArg) => {
|
|
135
244
|
console.log();
|
|
@@ -330,107 +439,6 @@ async function main() {
|
|
|
330
439
|
console.log();
|
|
331
440
|
});
|
|
332
441
|
|
|
333
|
-
// ─── Add module to existing project ───────────────────────────
|
|
334
|
-
program
|
|
335
|
-
.command('add <module>')
|
|
336
|
-
.description('Add a module to an existing Tigra project')
|
|
337
|
-
.action(async (moduleName) => {
|
|
338
|
-
console.log();
|
|
339
|
-
console.log(chalk.bold(' Create Tigra') + chalk.dim(` v${VERSION}`) + chalk.dim(' — add module'));
|
|
340
|
-
console.log();
|
|
341
|
-
|
|
342
|
-
const projectDir = process.cwd();
|
|
343
|
-
|
|
344
|
-
// Detect if we're inside a Tigra project
|
|
345
|
-
const hasServer = await fs.pathExists(path.join(projectDir, 'server', 'src', 'modules', 'auth'));
|
|
346
|
-
const hasClient = await fs.pathExists(path.join(projectDir, 'client', 'src', 'features', 'auth'));
|
|
347
|
-
|
|
348
|
-
if (!hasServer || !hasClient) {
|
|
349
|
-
console.error(chalk.red(' This does not appear to be a Tigra project.'));
|
|
350
|
-
console.error(chalk.dim(' Run this command from the root of your project (the folder containing server/ and client/).'));
|
|
351
|
-
console.log();
|
|
352
|
-
process.exit(1);
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
const availableModules = ['email-verification'];
|
|
356
|
-
|
|
357
|
-
if (!availableModules.includes(moduleName)) {
|
|
358
|
-
console.error(chalk.red(` Unknown module: "${moduleName}"`));
|
|
359
|
-
console.log();
|
|
360
|
-
console.log(chalk.dim(' Available modules:'));
|
|
361
|
-
for (const m of availableModules) {
|
|
362
|
-
console.log(chalk.cyan(` - ${m}`));
|
|
363
|
-
}
|
|
364
|
-
console.log();
|
|
365
|
-
process.exit(1);
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
if (moduleName === 'email-verification') {
|
|
369
|
-
// Check if already applied
|
|
370
|
-
const alreadyApplied = await fs.pathExists(
|
|
371
|
-
path.join(projectDir, 'server', 'src', 'modules', 'auth', 'verification.service.ts'),
|
|
372
|
-
);
|
|
373
|
-
if (alreadyApplied) {
|
|
374
|
-
console.log(chalk.yellow(' Email verification is already installed in this project.'));
|
|
375
|
-
console.log();
|
|
376
|
-
process.exit(0);
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
const spinner = ora('Adding email verification module...').start();
|
|
380
|
-
|
|
381
|
-
try {
|
|
382
|
-
const { applyEmailVerificationModule } = await import(
|
|
383
|
-
'../lib/patchers/email-verification.patcher.js'
|
|
384
|
-
);
|
|
385
|
-
await applyEmailVerificationModule(projectDir);
|
|
386
|
-
|
|
387
|
-
// Set REQUIRE_USER_VERIFICATION=true in .env if it's currently false
|
|
388
|
-
for (const envFile of ['server/.env.example', 'server/.env']) {
|
|
389
|
-
const envPath = path.join(projectDir, envFile);
|
|
390
|
-
if (await fs.pathExists(envPath)) {
|
|
391
|
-
const content = await fs.readFile(envPath, 'utf-8');
|
|
392
|
-
if (content.includes('REQUIRE_USER_VERIFICATION=false')) {
|
|
393
|
-
await fs.writeFile(
|
|
394
|
-
envPath,
|
|
395
|
-
content.replace('REQUIRE_USER_VERIFICATION=false', 'REQUIRE_USER_VERIFICATION=true'),
|
|
396
|
-
'utf-8',
|
|
397
|
-
);
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
spinner.succeed('Email verification module added!');
|
|
403
|
-
} catch (error) {
|
|
404
|
-
spinner.fail('Failed to add email verification module');
|
|
405
|
-
console.error(chalk.red(`\n ${error.message}\n`));
|
|
406
|
-
process.exit(1);
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
const dim = chalk.dim;
|
|
410
|
-
const cyan = chalk.cyan;
|
|
411
|
-
const green = chalk.green;
|
|
412
|
-
|
|
413
|
-
console.log();
|
|
414
|
-
console.log(green(' ✓ ') + 'Files added:');
|
|
415
|
-
console.log(dim(' server/src/modules/auth/verification.service.ts'));
|
|
416
|
-
console.log(dim(' server/src/modules/auth/verification.controller.ts'));
|
|
417
|
-
console.log(dim(' client/src/features/auth/services/verification.service.ts'));
|
|
418
|
-
console.log(dim(' client/src/features/auth/hooks/useVerification.ts'));
|
|
419
|
-
console.log();
|
|
420
|
-
console.log(green(' ✓ ') + 'Files patched:');
|
|
421
|
-
console.log(dim(' auth.routes.ts, auth.schemas.ts, auth.service.ts, auth.repo.ts'));
|
|
422
|
-
console.log(dim(' rate-limit.config.ts, api-endpoints.ts, error.ts, useAuth.ts'));
|
|
423
|
-
console.log(dim(' postman/collection.json'));
|
|
424
|
-
console.log();
|
|
425
|
-
console.log(green(' ✓ ') + 'REQUIRE_USER_VERIFICATION=true in server/.env');
|
|
426
|
-
console.log();
|
|
427
|
-
console.log(dim(' Next steps:'));
|
|
428
|
-
console.log(cyan(' 1 ') + 'Set ' + chalk.bold('RESEND_API_KEY') + ' in server/.env');
|
|
429
|
-
console.log(cyan(' 2 ') + 'Restart the server');
|
|
430
|
-
console.log();
|
|
431
|
-
}
|
|
432
|
-
});
|
|
433
|
-
|
|
434
442
|
program.parse();
|
|
435
443
|
}
|
|
436
444
|
|