create-turbo-mono 1.0.0

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 (54) hide show
  1. package/.claude/settings.local.json +14 -0
  2. package/README.md +182 -0
  3. package/dist/index.d.ts +3 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +118 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/scaffold.d.ts +8 -0
  8. package/dist/scaffold.d.ts.map +1 -0
  9. package/dist/scaffold.js +42 -0
  10. package/dist/scaffold.js.map +1 -0
  11. package/dist/templates/backend.d.ts +2 -0
  12. package/dist/templates/backend.d.ts.map +1 -0
  13. package/dist/templates/backend.js +424 -0
  14. package/dist/templates/backend.js.map +1 -0
  15. package/dist/templates/cicd.d.ts +3 -0
  16. package/dist/templates/cicd.d.ts.map +1 -0
  17. package/dist/templates/cicd.js +307 -0
  18. package/dist/templates/cicd.js.map +1 -0
  19. package/dist/templates/docker.d.ts +3 -0
  20. package/dist/templates/docker.d.ts.map +1 -0
  21. package/dist/templates/docker.js +458 -0
  22. package/dist/templates/docker.js.map +1 -0
  23. package/dist/templates/docs.d.ts +3 -0
  24. package/dist/templates/docs.d.ts.map +1 -0
  25. package/dist/templates/docs.js +71 -0
  26. package/dist/templates/docs.js.map +1 -0
  27. package/dist/templates/frontend.d.ts +2 -0
  28. package/dist/templates/frontend.d.ts.map +1 -0
  29. package/dist/templates/frontend.js +441 -0
  30. package/dist/templates/frontend.js.map +1 -0
  31. package/dist/templates/root.d.ts +3 -0
  32. package/dist/templates/root.d.ts.map +1 -0
  33. package/dist/templates/root.js +210 -0
  34. package/dist/templates/root.js.map +1 -0
  35. package/dist/templates/shared.d.ts +2 -0
  36. package/dist/templates/shared.d.ts.map +1 -0
  37. package/dist/templates/shared.js +696 -0
  38. package/dist/templates/shared.js.map +1 -0
  39. package/dist/utils.d.ts +5 -0
  40. package/dist/utils.d.ts.map +1 -0
  41. package/dist/utils.js +34 -0
  42. package/dist/utils.js.map +1 -0
  43. package/package.json +40 -0
  44. package/src/index.ts +138 -0
  45. package/src/scaffold.ts +51 -0
  46. package/src/templates/backend.ts +460 -0
  47. package/src/templates/cicd.ts +334 -0
  48. package/src/templates/docker.ts +503 -0
  49. package/src/templates/docs.ts +74 -0
  50. package/src/templates/frontend.ts +469 -0
  51. package/src/templates/root.ts +216 -0
  52. package/src/templates/shared.ts +820 -0
  53. package/src/utils.ts +31 -0
  54. package/tsconfig.json +20 -0
@@ -0,0 +1,460 @@
1
+ import fs from 'fs-extra';
2
+ import path from 'path';
3
+ import { toPascalCase, toKebabCase } from '../utils';
4
+
5
+ export async function createBackendApp(
6
+ targetDir: string,
7
+ appName: string
8
+ ): Promise<void> {
9
+ const kebabName = toKebabCase(appName);
10
+ const pascalName = toPascalCase(appName);
11
+ const appDir = path.join(targetDir, 'apps', 'backend', kebabName);
12
+
13
+ // Create full NestJS structure (matching 'nest new')
14
+ await fs.ensureDir(path.join(appDir, 'src'));
15
+ await fs.ensureDir(path.join(appDir, 'test'));
16
+
17
+ // package.json (matching nest new)
18
+ const packageJson = {
19
+ name: `@repo/${kebabName}`,
20
+ version: '0.0.1',
21
+ description: '',
22
+ author: '',
23
+ private: true,
24
+ license: 'UNLICENSED',
25
+ scripts: {
26
+ build: 'nest build',
27
+ format: 'prettier --write "src/**/*.ts" "test/**/*.ts"',
28
+ dev: 'nest start --watch',
29
+ 'start:dev': 'nest start --watch',
30
+ 'start:debug': 'nest start --debug --watch',
31
+ start: 'node dist/main',
32
+ 'start:prod': 'node dist/main',
33
+ lint: 'eslint "{src,apps,libs,test}/**/*.ts" --fix',
34
+ test: 'jest',
35
+ 'test:watch': 'jest --watch',
36
+ 'test:cov': 'jest --coverage',
37
+ 'test:debug': 'node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInWorker',
38
+ 'test:e2e': 'jest --config ./test/jest-e2e.json',
39
+ 'type-check': 'tsc --noEmit',
40
+ clean: 'rm -rf dist',
41
+ 'db:generate': 'pnpm --filter @repo/database db:generate',
42
+ },
43
+ dependencies: {
44
+ '@nestjs/common': '^10.0.0',
45
+ '@nestjs/core': '^10.0.0',
46
+ '@nestjs/platform-express': '^10.0.0',
47
+ '@nestjs/config': '^3.1.1',
48
+ '@repo/database': 'workspace:*',
49
+ '@repo/shared-backend': 'workspace:*',
50
+ '@repo/shared-common': 'workspace:*',
51
+ 'class-validator': '^0.14.0',
52
+ 'class-transformer': '^0.5.1',
53
+ 'reflect-metadata': '^0.2.0',
54
+ rxjs: '^7.8.1',
55
+ },
56
+ devDependencies: {
57
+ '@nestjs/cli': '^10.0.0',
58
+ '@nestjs/schematics': '^10.0.0',
59
+ '@nestjs/testing': '^10.0.0',
60
+ '@repo/tsconfig': 'workspace:*',
61
+ '@types/express': '^4.17.17',
62
+ '@types/jest': '^29.5.2',
63
+ '@types/node': '^20.3.1',
64
+ '@types/supertest': '^2.0.12',
65
+ '@typescript-eslint/eslint-plugin': '^6.0.0',
66
+ '@typescript-eslint/parser': '^6.0.0',
67
+ eslint: '^8.42.0',
68
+ 'eslint-config-prettier': '^9.0.0',
69
+ 'eslint-plugin-prettier': '^5.0.0',
70
+ jest: '^29.5.0',
71
+ prettier: '^3.0.0',
72
+ 'source-map-support': '^0.5.21',
73
+ supertest: '^6.3.3',
74
+ 'ts-jest': '^29.1.0',
75
+ 'ts-loader': '^9.4.3',
76
+ 'ts-node': '^10.9.1',
77
+ 'tsconfig-paths': '^4.2.0',
78
+ typescript: '^5.1.3',
79
+ },
80
+ jest: {
81
+ moduleFileExtensions: ['js', 'json', 'ts'],
82
+ rootDir: 'src',
83
+ testRegex: '.*\\.spec\\.ts$',
84
+ transform: {
85
+ '^.+\\.(t|j)s$': 'ts-jest',
86
+ },
87
+ collectCoverageFrom: ['**/*.(t|j)s'],
88
+ coverageDirectory: '../coverage',
89
+ testEnvironment: 'node',
90
+ },
91
+ };
92
+
93
+ await fs.writeJson(path.join(appDir, 'package.json'), packageJson, {
94
+ spaces: 2,
95
+ });
96
+
97
+ // tsconfig.json
98
+ const tsConfig = {
99
+ extends: '@repo/tsconfig/nestjs.json',
100
+ compilerOptions: {
101
+ module: 'commonjs',
102
+ declaration: true,
103
+ removeComments: true,
104
+ emitDecoratorMetadata: true,
105
+ experimentalDecorators: true,
106
+ allowSyntheticDefaultImports: true,
107
+ target: 'ES2021',
108
+ sourceMap: true,
109
+ outDir: './dist',
110
+ baseUrl: './',
111
+ incremental: true,
112
+ skipLibCheck: true,
113
+ strictNullChecks: false,
114
+ noImplicitAny: false,
115
+ strictBindCallApply: false,
116
+ forceConsistentCasingInFileNames: false,
117
+ noFallthroughCasesInSwitch: false,
118
+ },
119
+ };
120
+
121
+ await fs.writeJson(path.join(appDir, 'tsconfig.json'), tsConfig, {
122
+ spaces: 2,
123
+ });
124
+
125
+ // tsconfig.build.json
126
+ const tsBuildConfig = {
127
+ extends: './tsconfig.json',
128
+ exclude: ['node_modules', 'test', 'dist', '**/*spec.ts'],
129
+ };
130
+
131
+ await fs.writeJson(path.join(appDir, 'tsconfig.build.json'), tsBuildConfig, {
132
+ spaces: 2,
133
+ });
134
+
135
+ // nest-cli.json
136
+ const nestCliConfig = {
137
+ $schema: 'https://json.schemastore.org/nest-cli',
138
+ collection: '@nestjs/schematics',
139
+ sourceRoot: 'src',
140
+ compilerOptions: {
141
+ deleteOutDir: true,
142
+ },
143
+ };
144
+
145
+ await fs.writeJson(path.join(appDir, 'nest-cli.json'), nestCliConfig, {
146
+ spaces: 2,
147
+ });
148
+
149
+ // .eslintrc.js
150
+ const eslintConfig = `module.exports = {
151
+ parser: '@typescript-eslint/parser',
152
+ parserOptions: {
153
+ project: 'tsconfig.json',
154
+ tsconfigRootDir: __dirname,
155
+ sourceType: 'module',
156
+ },
157
+ plugins: ['@typescript-eslint/eslint-plugin'],
158
+ extends: [
159
+ 'plugin:@typescript-eslint/recommended',
160
+ 'plugin:prettier/recommended',
161
+ ],
162
+ root: true,
163
+ env: {
164
+ node: true,
165
+ jest: true,
166
+ },
167
+ ignorePatterns: ['.eslintrc.js'],
168
+ rules: {
169
+ '@typescript-eslint/interface-name-prefix': 'off',
170
+ '@typescript-eslint/explicit-function-return-type': 'off',
171
+ '@typescript-eslint/explicit-module-boundary-types': 'off',
172
+ '@typescript-eslint/no-explicit-any': 'off',
173
+ },
174
+ };
175
+ `;
176
+
177
+ await fs.writeFile(path.join(appDir, '.eslintrc.js'), eslintConfig);
178
+
179
+ // .prettierrc
180
+ const prettierConfig = {
181
+ singleQuote: true,
182
+ trailingComma: 'all',
183
+ };
184
+
185
+ await fs.writeJson(path.join(appDir, '.prettierrc'), prettierConfig, {
186
+ spaces: 2,
187
+ });
188
+
189
+ // src/main.ts
190
+ const mainTs = `import { NestFactory } from '@nestjs/core';
191
+ import { ValidationPipe } from '@nestjs/common';
192
+ import { AppModule } from './app.module';
193
+
194
+ async function bootstrap() {
195
+ const app = await NestFactory.create(AppModule);
196
+
197
+ app.useGlobalPipes(
198
+ new ValidationPipe({
199
+ whitelist: true,
200
+ transform: true,
201
+ }),
202
+ );
203
+
204
+ app.enableCors();
205
+
206
+ const port = process.env.PORT || 3000;
207
+ await app.listen(port);
208
+
209
+ console.log(\`Application is running on: \${await app.getUrl()}\`);
210
+ }
211
+ bootstrap();
212
+ `;
213
+
214
+ await fs.writeFile(path.join(appDir, 'src', 'main.ts'), mainTs);
215
+
216
+ // src/app.module.ts
217
+ const appModuleTs = `import { Module } from '@nestjs/common';
218
+ import { ConfigModule } from '@nestjs/config';
219
+ import { AppController } from './app.controller';
220
+ import { AppService } from './app.service';
221
+
222
+ @Module({
223
+ imports: [
224
+ ConfigModule.forRoot({
225
+ isGlobal: true,
226
+ }),
227
+ ],
228
+ controllers: [AppController],
229
+ providers: [AppService],
230
+ })
231
+ export class AppModule {}
232
+ `;
233
+
234
+ await fs.writeFile(path.join(appDir, 'src', 'app.module.ts'), appModuleTs);
235
+
236
+ // src/app.controller.ts
237
+ const appControllerTs = `import { Controller, Get } from '@nestjs/common';
238
+ import { AppService } from './app.service';
239
+
240
+ @Controller()
241
+ export class AppController {
242
+ constructor(private readonly appService: AppService) {}
243
+
244
+ @Get()
245
+ getHello(): string {
246
+ return this.appService.getHello();
247
+ }
248
+ }
249
+ `;
250
+
251
+ await fs.writeFile(
252
+ path.join(appDir, 'src', 'app.controller.ts'),
253
+ appControllerTs
254
+ );
255
+
256
+ // src/app.controller.spec.ts
257
+ const appControllerSpecTs = `import { Test, TestingModule } from '@nestjs/testing';
258
+ import { AppController } from './app.controller';
259
+ import { AppService } from './app.service';
260
+
261
+ describe('AppController', () => {
262
+ let appController: AppController;
263
+
264
+ beforeEach(async () => {
265
+ const app: TestingModule = await Test.createTestingModule({
266
+ controllers: [AppController],
267
+ providers: [AppService],
268
+ }).compile();
269
+
270
+ appController = app.get<AppController>(AppController);
271
+ });
272
+
273
+ describe('root', () => {
274
+ it('should return "Hello World!"', () => {
275
+ expect(appController.getHello()).toBe('Hello World!');
276
+ });
277
+ });
278
+ });
279
+ `;
280
+
281
+ await fs.writeFile(
282
+ path.join(appDir, 'src', 'app.controller.spec.ts'),
283
+ appControllerSpecTs
284
+ );
285
+
286
+ // src/app.service.ts
287
+ const appServiceTs = `import { Injectable } from '@nestjs/common';
288
+
289
+ @Injectable()
290
+ export class AppService {
291
+ getHello(): string {
292
+ return 'Hello World!';
293
+ }
294
+ }
295
+ `;
296
+
297
+ await fs.writeFile(path.join(appDir, 'src', 'app.service.ts'), appServiceTs);
298
+
299
+ // test/app.e2e-spec.ts
300
+ const appE2eSpecTs = `import { Test, TestingModule } from '@nestjs/testing';
301
+ import { INestApplication } from '@nestjs/common';
302
+ import * as request from 'supertest';
303
+ import { AppModule } from './../src/app.module';
304
+
305
+ describe('AppController (e2e)', () => {
306
+ let app: INestApplication;
307
+
308
+ beforeEach(async () => {
309
+ const moduleFixture: TestingModule = await Test.createTestingModule({
310
+ imports: [AppModule],
311
+ }).compile();
312
+
313
+ app = moduleFixture.createNestApplication();
314
+ await app.init();
315
+ });
316
+
317
+ it('/ (GET)', () => {
318
+ return request(app.getHttpServer())
319
+ .get('/')
320
+ .expect(200)
321
+ .expect('Hello World!');
322
+ });
323
+ });
324
+ `;
325
+
326
+ await fs.writeFile(path.join(appDir, 'test', 'app.e2e-spec.ts'), appE2eSpecTs);
327
+
328
+ // test/jest-e2e.json
329
+ const jestE2eConfig = {
330
+ moduleFileExtensions: ['js', 'json', 'ts'],
331
+ rootDir: '.',
332
+ testEnvironment: 'node',
333
+ testRegex: '.e2e-spec.ts$',
334
+ transform: {
335
+ '^.+\\.(t|j)s$': 'ts-jest',
336
+ },
337
+ };
338
+
339
+ await fs.writeJson(path.join(appDir, 'test', 'jest-e2e.json'), jestE2eConfig, {
340
+ spaces: 2,
341
+ });
342
+
343
+ // .gitignore
344
+ const gitignore = `# compiled output
345
+ /dist
346
+ /node_modules
347
+
348
+ # Logs
349
+ logs
350
+ *.log
351
+ npm-debug.log*
352
+ pnpm-debug.log*
353
+ yarn-debug.log*
354
+ yarn-error.log*
355
+ lerna-debug.log*
356
+
357
+ # OS
358
+ .DS_Store
359
+
360
+ # Tests
361
+ /coverage
362
+ /.nyc_output
363
+
364
+ # IDEs and editors
365
+ /.idea
366
+ .project
367
+ .classpath
368
+ .c9/
369
+ *.launch
370
+ .settings/
371
+ *.sublime-workspace
372
+
373
+ # IDE - VSCode
374
+ .vscode/*
375
+ !.vscode/settings.json
376
+ !.vscode/tasks.json
377
+ !.vscode/launch.json
378
+ !.vscode/extensions.json
379
+
380
+ # dotenv environment variable files
381
+ .env
382
+ .env.development.local
383
+ .env.test.local
384
+ .env.production.local
385
+ .env.local
386
+
387
+ # temp directory
388
+ .temp
389
+ .tmp
390
+
391
+ # Runtime data
392
+ pids
393
+ *.pid
394
+ *.seed
395
+ *.pid.lock
396
+
397
+ # Diagnostic reports (https://nodejs.org/api/report.html)
398
+ report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
399
+ `;
400
+
401
+ await fs.writeFile(path.join(appDir, '.gitignore'), gitignore);
402
+
403
+ // .env.example
404
+ const envExample = `PORT=3000
405
+ DATABASE_URL="postgresql://user:password@localhost:5432/${kebabName}?schema=public"
406
+ `;
407
+
408
+ await fs.writeFile(path.join(appDir, '.env.example'), envExample);
409
+ await fs.writeFile(path.join(appDir, '.env'), envExample);
410
+
411
+ // README.md
412
+ const readme = `# ${pascalName}
413
+
414
+ ## Description
415
+
416
+ [Nest](https://github.com/nestjs/nest) framework TypeScript starter repository.
417
+
418
+ ## Installation
419
+
420
+ \`\`\`bash
421
+ $ pnpm install
422
+ \`\`\`
423
+
424
+ ## Running the app
425
+
426
+ \`\`\`bash
427
+ # development
428
+ $ pnpm run dev
429
+
430
+ # watch mode
431
+ $ pnpm run start:dev
432
+
433
+ # production mode
434
+ $ pnpm run start:prod
435
+ \`\`\`
436
+
437
+ ## Test
438
+
439
+ \`\`\`bash
440
+ # unit tests
441
+ $ pnpm run test
442
+
443
+ # e2e tests
444
+ $ pnpm run test:e2e
445
+
446
+ # test coverage
447
+ $ pnpm run test:cov
448
+ \`\`\`
449
+
450
+ ## Support
451
+
452
+ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please [read more here](https://docs.nestjs.com/support).
453
+
454
+ ## License
455
+
456
+ Nest is [MIT licensed](LICENSE).
457
+ `;
458
+
459
+ await fs.writeFile(path.join(appDir, 'README.md'), readme);
460
+ }