rapidkit 0.11.2 → 0.12.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 (47) hide show
  1. package/README.md +99 -408
  2. package/dist/index.js +508 -279
  3. package/dist/package.json +1 -1
  4. package/package.json +1 -1
  5. package/templates/generator.js +175 -0
  6. package/templates/kits/fastapi-standard/.rapidkit/__init__.py.j2 +1 -0
  7. package/templates/kits/fastapi-standard/.rapidkit/activate.j2 +24 -0
  8. package/templates/kits/fastapi-standard/.rapidkit/cli.py.j2 +257 -0
  9. package/templates/kits/fastapi-standard/.rapidkit/project.json.j2 +7 -0
  10. package/templates/kits/fastapi-standard/.rapidkit/rapidkit.j2 +98 -0
  11. package/templates/kits/fastapi-standard/Makefile.j2 +41 -0
  12. package/templates/kits/fastapi-standard/README.md.j2 +4 -4
  13. package/templates/kits/fastapi-standard/pyproject.toml.j2 +1 -0
  14. package/templates/kits/fastapi-standard/rapidkit.j2 +50 -0
  15. package/templates/kits/fastapi-standard/src/main.py.j2 +15 -12
  16. package/templates/kits/nestjs-standard/.env.example.j2 +16 -0
  17. package/templates/kits/nestjs-standard/.eslintrc.js.j2 +25 -0
  18. package/templates/kits/nestjs-standard/.gitignore.j2 +26 -0
  19. package/templates/kits/nestjs-standard/.node-version.j2 +1 -0
  20. package/templates/kits/nestjs-standard/.nvmrc.j2 +1 -0
  21. package/templates/kits/nestjs-standard/.prettierrc.j2 +7 -0
  22. package/templates/kits/nestjs-standard/.rapidkit/activate.j2 +25 -0
  23. package/templates/kits/nestjs-standard/.rapidkit/project.json.j2 +7 -0
  24. package/templates/kits/nestjs-standard/.rapidkit/rapidkit.j2 +227 -0
  25. package/templates/kits/nestjs-standard/README.md.j2 +97 -0
  26. package/templates/kits/nestjs-standard/jest.config.ts.j2 +21 -0
  27. package/templates/kits/nestjs-standard/nest-cli.json.j2 +10 -0
  28. package/templates/kits/nestjs-standard/package.json.j2 +75 -0
  29. package/templates/kits/nestjs-standard/rapidkit.j2 +5 -0
  30. package/templates/kits/nestjs-standard/src/app.controller.ts.j2 +12 -0
  31. package/templates/kits/nestjs-standard/src/app.module.ts.j2 +23 -0
  32. package/templates/kits/nestjs-standard/src/app.service.ts.j2 +11 -0
  33. package/templates/kits/nestjs-standard/src/config/configuration.ts.j2 +9 -0
  34. package/templates/kits/nestjs-standard/src/config/index.ts.j2 +2 -0
  35. package/templates/kits/nestjs-standard/src/config/validation.ts.j2 +11 -0
  36. package/templates/kits/nestjs-standard/src/examples/dto/create-note.dto.ts.j2 +11 -0
  37. package/templates/kits/nestjs-standard/src/examples/examples.controller.ts.j2 +24 -0
  38. package/templates/kits/nestjs-standard/src/examples/examples.module.ts.j2 +10 -0
  39. package/templates/kits/nestjs-standard/src/examples/examples.service.ts.j2 +33 -0
  40. package/templates/kits/nestjs-standard/src/main.ts.j2 +51 -0
  41. package/templates/kits/nestjs-standard/src/modules/index.ts.j2 +3 -0
  42. package/templates/kits/nestjs-standard/test/app.controller.spec.ts.j2 +22 -0
  43. package/templates/kits/nestjs-standard/test/app.e2e-spec.ts.j2 +48 -0
  44. package/templates/kits/nestjs-standard/test/examples.controller.spec.ts.j2 +28 -0
  45. package/templates/kits/nestjs-standard/test/jest-e2e.json.j2 +15 -0
  46. package/templates/kits/nestjs-standard/tsconfig.build.json.j2 +12 -0
  47. package/templates/kits/nestjs-standard/tsconfig.json.j2 +26 -0
@@ -0,0 +1,23 @@
1
+ import { Module } from '@nestjs/common';
2
+ import { ConfigModule } from '@nestjs/config';
3
+
4
+ import configuration from './config/configuration';
5
+ import { validationSchema } from './config/validation';
6
+ import { AppController } from './app.controller';
7
+ import { AppService } from './app.service';
8
+ import { ExamplesModule } from './examples/examples.module';
9
+
10
+ @Module({
11
+ imports: [
12
+ ConfigModule.forRoot({
13
+ isGlobal: true,
14
+ load: [configuration],
15
+ validationSchema,
16
+ expandVariables: true,
17
+ }),
18
+ ExamplesModule,
19
+ ],
20
+ controllers: [AppController],
21
+ providers: [AppService],
22
+ })
23
+ export class AppModule {}
@@ -0,0 +1,11 @@
1
+ import { Injectable } from '@nestjs/common';
2
+
3
+ @Injectable()
4
+ export class AppService {
5
+ getHealth() {
6
+ return {
7
+ status: 'ok',
8
+ timestamp: new Date().toISOString(),
9
+ };
10
+ }
11
+ }
@@ -0,0 +1,9 @@
1
+ import { registerAs } from '@nestjs/config';
2
+
3
+ export default registerAs('app', () => ({
4
+ name: process.env.APP_NAME ?? '{{ project_name }}',
5
+ env: process.env.NODE_ENV ?? 'development',
6
+ host: process.env.HOST ?? '0.0.0.0',
7
+ port: parseInt(process.env.PORT ?? '8000', 10),
8
+ logLevel: process.env.LOG_LEVEL ?? 'info',
9
+ }));
@@ -0,0 +1,2 @@
1
+ export { default } from './configuration';
2
+ export * from './validation';
@@ -0,0 +1,11 @@
1
+ import * as Joi from 'joi';
2
+
3
+ export const validationSchema = Joi.object({
4
+ APP_NAME: Joi.string().default('{{ project_name }}'),
5
+ NODE_ENV: Joi.string().valid('development', 'production', 'test').default('development'),
6
+ HOST: Joi.string().hostname().default('0.0.0.0'),
7
+ PORT: Joi.number().port().default(8000),
8
+ LOG_LEVEL: Joi.string()
9
+ .valid('error', 'warn', 'log', 'debug', 'verbose')
10
+ .default('log'),
11
+ });
@@ -0,0 +1,11 @@
1
+ import { IsString, MaxLength } from 'class-validator';
2
+
3
+ export class CreateNoteDto {
4
+ @IsString()
5
+ @MaxLength(80)
6
+ title!: string;
7
+
8
+ @IsString()
9
+ @MaxLength(500)
10
+ body!: string;
11
+ }
@@ -0,0 +1,24 @@
1
+ import { Body, Controller, Get, Param, ParseIntPipe, Post } from '@nestjs/common';
2
+
3
+ import { CreateNoteDto } from './dto/create-note.dto';
4
+ import { ExamplesService } from './examples.service';
5
+
6
+ @Controller('examples/notes')
7
+ export class ExamplesController {
8
+ constructor(private readonly examplesService: ExamplesService) {}
9
+
10
+ @Post()
11
+ create(@Body() payload: CreateNoteDto) {
12
+ return this.examplesService.create(payload);
13
+ }
14
+
15
+ @Get()
16
+ findAll() {
17
+ return this.examplesService.findAll();
18
+ }
19
+
20
+ @Get(':id')
21
+ findOne(@Param('id', ParseIntPipe) id: number) {
22
+ return this.examplesService.findOne(id);
23
+ }
24
+ }
@@ -0,0 +1,10 @@
1
+ import { Module } from '@nestjs/common';
2
+
3
+ import { ExamplesController } from './examples.controller';
4
+ import { ExamplesService } from './examples.service';
5
+
6
+ @Module({
7
+ controllers: [ExamplesController],
8
+ providers: [ExamplesService],
9
+ })
10
+ export class ExamplesModule {}
@@ -0,0 +1,33 @@
1
+ import { Injectable, NotFoundException } from '@nestjs/common';
2
+
3
+ import { CreateNoteDto } from './dto/create-note.dto';
4
+
5
+ export interface ExampleNote {
6
+ id: number;
7
+ title: string;
8
+ body: string;
9
+ }
10
+
11
+ @Injectable()
12
+ export class ExamplesService {
13
+ private notes: ExampleNote[] = [];
14
+ private sequence = 1;
15
+
16
+ create(payload: CreateNoteDto): ExampleNote {
17
+ const note: ExampleNote = { id: this.sequence++, ...payload };
18
+ this.notes.push(note);
19
+ return note;
20
+ }
21
+
22
+ findAll(): ExampleNote[] {
23
+ return [...this.notes];
24
+ }
25
+
26
+ findOne(id: number): ExampleNote {
27
+ const note = this.notes.find((entry) => entry.id === id);
28
+ if (!note) {
29
+ throw new NotFoundException('Note not found');
30
+ }
31
+ return note;
32
+ }
33
+ }
@@ -0,0 +1,51 @@
1
+ import { Logger } from '@nestjs/common';
2
+ import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
3
+ import { NestFactory } from '@nestjs/core';
4
+ import helmet from 'helmet';
5
+ import compression from 'compression';
6
+
7
+ import { AppModule } from './app.module';
8
+
9
+ async function bootstrap() {
10
+ const app = await NestFactory.create(AppModule, {
11
+ bufferLogs: true,
12
+ });
13
+
14
+ const logger = new Logger('Bootstrap');
15
+
16
+ app.use(helmet());
17
+ app.use(compression());
18
+
19
+ app.enableCors({
20
+ origin: '*',
21
+ credentials: true,
22
+ });
23
+
24
+ const port = parseInt(process.env.PORT ?? '8000', 10);
25
+ const host = process.env.HOST ?? '0.0.0.0';
26
+
27
+ // Enable Swagger docs in development or when explicitly requested.
28
+ const enableDocs = process.env.RAPIDKIT_ENABLE_SWAGGER === '1' || process.env.NODE_ENV !== 'production';
29
+ if (enableDocs) {
30
+ const config = new DocumentBuilder()
31
+ .setTitle('{{ project_name }} API')
32
+ .setDescription('{{ description }}')
33
+ .setVersion('{{ app_version }}')
34
+ .addBearerAuth()
35
+ .build();
36
+
37
+ const document = SwaggerModule.createDocument(app, config);
38
+ SwaggerModule.setup('docs', app, document);
39
+ }
40
+
41
+ await app.listen(port, host);
42
+
43
+ logger.log(`🚀 Application is running on http://${host}:${port}`);
44
+ logger.log(`📚 API docs available at http://${host}:${port}/docs`);
45
+ }
46
+
47
+ bootstrap().catch((error) => {
48
+ // eslint-disable-next-line no-console
49
+ console.error('❌ Failed to bootstrap application', error);
50
+ process.exit(1);
51
+ });
@@ -0,0 +1,3 @@
1
+ // Central export for RapidKit modules
2
+ // Add module exports here as needed
3
+ export const rapidkitModules = [];
@@ -0,0 +1,22 @@
1
+ import { Test, TestingModule } from '@nestjs/testing';
2
+
3
+ import { AppController } from '../src/app.controller';
4
+ import { AppService } from '../src/app.service';
5
+
6
+ describe('AppController', () => {
7
+ let appController: AppController;
8
+
9
+ beforeEach(async () => {
10
+ const app: TestingModule = await Test.createTestingModule({
11
+ controllers: [AppController],
12
+ providers: [AppService],
13
+ }).compile();
14
+
15
+ appController = app.get<AppController>(AppController);
16
+ });
17
+
18
+ it('should return health status', () => {
19
+ const result = appController.getHealth();
20
+ expect(result).toHaveProperty('status', 'ok');
21
+ });
22
+ });
@@ -0,0 +1,48 @@
1
+ import { Test, TestingModule } from '@nestjs/testing';
2
+ import { INestApplication } from '@nestjs/common';
3
+ import request from 'supertest';
4
+
5
+ import { AppModule } from '../src/app.module';
6
+
7
+ describe('AppController (e2e)', () => {
8
+ let app: INestApplication;
9
+
10
+ beforeAll(async () => {
11
+ const moduleFixture: TestingModule = await Test.createTestingModule({
12
+ imports: [AppModule],
13
+ }).compile();
14
+
15
+ app = moduleFixture.createNestApplication();
16
+ await app.init();
17
+ });
18
+
19
+ afterAll(async () => {
20
+ await app.close();
21
+ });
22
+
23
+ it('/health (GET)', () => {
24
+ return request(app.getHttpServer()).get('/health').expect(200).expect({
25
+ status: 'ok',
26
+ timestamp: expect.any(String),
27
+ });
28
+ });
29
+
30
+ it('/examples/notes (POST + GET)', async () => {
31
+ const server = app.getHttpServer();
32
+ const createResponse = await request(server)
33
+ .post('/examples/notes')
34
+ .send({ title: 'test', body: 'e2e test note' })
35
+ .expect(201);
36
+
37
+ const noteId = createResponse.body.id;
38
+
39
+ await request(server)
40
+ .get('/examples/notes')
41
+ .expect(200)
42
+ .expect((res) => {
43
+ expect(res.body).toEqual(
44
+ expect.arrayContaining([expect.objectContaining({ id: noteId, title: 'test' })]),
45
+ );
46
+ });
47
+ });
48
+ });
@@ -0,0 +1,28 @@
1
+ import { Test, TestingModule } from '@nestjs/testing';
2
+
3
+ import { ExamplesController } from '../src/examples/examples.controller';
4
+ import { ExamplesService } from '../src/examples/examples.service';
5
+
6
+ describe('ExamplesController', () => {
7
+ let controller: ExamplesController;
8
+
9
+ beforeEach(async () => {
10
+ const module: TestingModule = await Test.createTestingModule({
11
+ controllers: [ExamplesController],
12
+ providers: [ExamplesService],
13
+ }).compile();
14
+
15
+ controller = module.get<ExamplesController>(ExamplesController);
16
+ });
17
+
18
+ it('creates and retrieves notes', () => {
19
+ const created = controller.create({ title: 'spec', body: 'covered by tests' });
20
+ expect(created).toMatchObject({ id: 1, title: 'spec' });
21
+
22
+ const list = controller.findAll();
23
+ expect(list).toHaveLength(1);
24
+
25
+ const single = controller.findOne(created.id);
26
+ expect(single).toMatchObject({ id: created.id, title: 'spec' });
27
+ });
28
+ });
@@ -0,0 +1,15 @@
1
+ {
2
+ "moduleFileExtensions": ["js", "json", "ts"],
3
+ "rootDir": "../",
4
+ "testEnvironment": "node",
5
+ "testRegex": ".e2e-spec.ts$",
6
+ "transform": {
7
+ "^.+\\.ts$": "ts-jest"
8
+ },
9
+ "setupFiles": ["dotenv/config"],
10
+ "moduleNameMapper": {
11
+ "^@config/(.*)$": "<rootDir>/src/config/$1",
12
+ "^@modules/(.*)$": "<rootDir>/src/modules/$1",
13
+ "^@shared/(.*)$": "<rootDir>/src/shared/$1"
14
+ }
15
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "./dist",
5
+ "declaration": true,
6
+ "sourceMap": false,
7
+ "removeComments": true,
8
+ "incremental": false
9
+ },
10
+ "exclude": ["node_modules", "test", "src/**/*.spec.ts", "src/**/*.e2e-spec.ts"],
11
+ "include": ["src/**/*.ts"]
12
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "compilerOptions": {
3
+ "module": "commonjs",
4
+ "declaration": true,
5
+ "removeComments": true,
6
+ "emitDecoratorMetadata": true,
7
+ "experimentalDecorators": true,
8
+ "allowSyntheticDefaultImports": true,
9
+ "target": "es2021",
10
+ "sourceMap": true,
11
+ "outDir": "./dist",
12
+ "baseUrl": "./",
13
+ "incremental": true,
14
+ "strict": true,
15
+ "skipLibCheck": true,
16
+ "moduleResolution": "node",
17
+ "esModuleInterop": true,
18
+ "paths": {
19
+ "@config/*": ["src/config/*"],
20
+ "@modules/*": ["src/modules/*"],
21
+ "@shared/*": ["src/shared/*"]
22
+ }
23
+ },
24
+ "exclude": ["node_modules", "dist"],
25
+ "include": ["src/**/*.ts", "test/**/*.ts"]
26
+ }