@exanderal/stackcraft 0.1.1 → 0.2.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.
- package/README.md +79 -8
- package/dist/create/index.d.ts.map +1 -1
- package/dist/create/index.js +24 -1
- package/dist/create/index.js.map +1 -1
- package/dist/create/scaffold.d.ts.map +1 -1
- package/dist/create/scaffold.js +8 -2
- package/dist/create/scaffold.js.map +1 -1
- package/dist/create/scaffolders/__tests__/web-vite.test.js +1 -0
- package/dist/create/scaffolders/__tests__/web-vite.test.js.map +1 -1
- package/dist/create/scaffolders/api-nestjs-graphql.d.ts +3 -0
- package/dist/create/scaffolders/api-nestjs-graphql.d.ts.map +1 -0
- package/dist/create/scaffolders/api-nestjs-graphql.js +31 -0
- package/dist/create/scaffolders/api-nestjs-graphql.js.map +1 -0
- package/dist/create/scaffolders/api-nestjs-rest.d.ts.map +1 -1
- package/dist/create/scaffolders/api-nestjs-rest.js +19 -2
- package/dist/create/scaffolders/api-nestjs-rest.js.map +1 -1
- package/dist/create/types.d.ts +3 -1
- package/dist/create/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/templates/api-nestjs-graphql/.prettierrc +4 -0
- package/templates/api-nestjs-graphql/eslint.config.mjs +34 -0
- package/templates/api-nestjs-graphql/nest-cli.json +8 -0
- package/templates/api-nestjs-graphql/package.json +81 -0
- package/templates/api-nestjs-graphql/project.json +21 -0
- package/templates/api-nestjs-graphql/src/app.module.ts +21 -0
- package/templates/api-nestjs-graphql/src/common/entities/base.entity.ts +21 -0
- package/templates/api-nestjs-graphql/src/common/repositories/entity.repository.ts +21 -0
- package/templates/api-nestjs-graphql/src/common/repositories/readonly-entity.repository.ts +22 -0
- package/templates/api-nestjs-graphql/src/common/services/entity.service.ts +24 -0
- package/templates/api-nestjs-graphql/src/common/services/readonly-entity.service.ts +23 -0
- package/templates/api-nestjs-graphql/src/main.ts +8 -0
- package/templates/api-nestjs-graphql/src/modules/database/database.module.ts +18 -0
- package/templates/api-nestjs-graphql/src/modules/health/__tests__/health.controller.spec.ts +20 -0
- package/templates/api-nestjs-graphql/src/modules/health/__tests__/health.service.spec.ts +18 -0
- package/templates/api-nestjs-graphql/src/modules/health/health.controller.ts +12 -0
- package/templates/api-nestjs-graphql/src/modules/health/health.module.ts +9 -0
- package/templates/api-nestjs-graphql/src/modules/health/health.service.ts +8 -0
- package/templates/api-nestjs-graphql/test/app.e2e-spec.ts +29 -0
- package/templates/api-nestjs-graphql/test/jest-e2e.json +9 -0
- package/templates/api-nestjs-graphql/tsconfig.build.json +4 -0
- package/templates/api-nestjs-graphql/tsconfig.json +21 -0
- package/templates/api-nestjs-rest/package.json +5 -2
- package/templates/api-nestjs-rest/project.json +1 -1
- package/templates/api-nestjs-rest/src/app.module.ts +8 -5
- package/templates/api-nestjs-rest/src/common/entities/base.entity.ts +16 -0
- package/templates/api-nestjs-rest/src/common/repositories/entity.repository.ts +21 -0
- package/templates/api-nestjs-rest/src/common/repositories/readonly-entity.repository.ts +22 -0
- package/templates/api-nestjs-rest/src/common/services/entity.service.ts +24 -0
- package/templates/api-nestjs-rest/src/common/services/readonly-entity.service.ts +23 -0
- package/templates/api-nestjs-rest/src/modules/database/database.module.ts +18 -0
- package/templates/api-nestjs-rest/src/modules/health/__tests__/health.controller.spec.ts +20 -0
- package/templates/api-nestjs-rest/src/modules/health/__tests__/health.service.spec.ts +18 -0
- package/templates/api-nestjs-rest/src/modules/health/health.controller.ts +12 -0
- package/templates/api-nestjs-rest/src/modules/health/health.module.ts +9 -0
- package/templates/api-nestjs-rest/src/modules/health/health.service.ts +8 -0
- package/templates/api-nestjs-rest/test/app.e2e-spec.ts +9 -5
- package/templates/base/package.json +5 -1
- package/templates/base/pnpm-workspace.yaml +1 -0
- package/templates/base/tools/generators/controller/files/__fileName__.controller.ts__tmpl__ +36 -0
- package/templates/base/tools/generators/controller/index.js +22 -0
- package/templates/base/tools/generators/controller/schema.json +18 -0
- package/templates/base/tools/generators/generators.json +19 -0
- package/templates/base/tools/generators/module/files/__fileName__.model.ts__tmpl__ +8 -0
- package/templates/base/tools/generators/module/files/__fileName__.module.ts__tmpl__ +12 -0
- package/templates/base/tools/generators/module/files/__fileName__.repository.ts__tmpl__ +15 -0
- package/templates/base/tools/generators/module/files/__fileName__.service.ts__tmpl__ +11 -0
- package/templates/base/tools/generators/module/files/__tests__/__fileName__.integration.spec.ts__tmpl__ +31 -0
- package/templates/base/tools/generators/module/graphql-files/__fileName__.model.ts__tmpl__ +11 -0
- package/templates/base/tools/generators/module/index.js +26 -0
- package/templates/base/tools/generators/module/schema.json +23 -0
- package/templates/base/tools/generators/package.json +6 -0
- package/templates/base/tools/generators/resolver/files/__fileName__.resolver.ts__tmpl__ +28 -0
- package/templates/base/tools/generators/resolver/index.js +22 -0
- package/templates/base/tools/generators/resolver/schema.json +18 -0
- package/templates/web-nextjs/package.json +3 -0
- package/templates/web-nextjs/postcss.config.mjs +7 -0
- package/templates/web-nextjs/src/app/globals.css +1 -0
- package/templates/web-nextjs/src/components/TemplateComponent/TemplateComponent.behaviour.ts +39 -0
- package/templates/web-nextjs/src/components/TemplateComponent/TemplateComponent.tsx +14 -0
- package/templates/web-vite/package.json +2 -0
- package/templates/web-vite/src/components/TemplateComponent/TemplateComponent.behaviour.ts +39 -0
- package/templates/web-vite/src/components/TemplateComponent/TemplateComponent.tsx +14 -0
- package/templates/web-vite/src/index.css +1 -8
- package/templates/web-vite/vite.config.ts +3 -3
- package/templates/api-nestjs-rest/src/app.controller.spec.ts +0 -22
- package/templates/api-nestjs-rest/src/app.controller.ts +0 -12
- package/templates/api-nestjs-rest/src/app.service.ts +0 -8
- package/templates/web-nextjs/app/globals.css +0 -10
- /package/templates/web-nextjs/{app → src/app}/favicon.ico +0 -0
- /package/templates/web-nextjs/{app → src/app}/layout.tsx +0 -0
- /package/templates/web-nextjs/{app → src/app}/page.tsx +0 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Module } from '@nestjs/common';
|
|
2
|
+
import { TypeOrmModule } from '@nestjs/typeorm';
|
|
3
|
+
|
|
4
|
+
@Module({
|
|
5
|
+
imports: [
|
|
6
|
+
TypeOrmModule.forRoot({
|
|
7
|
+
type: '{{dbType}}' as 'postgres' | 'mysql',
|
|
8
|
+
host: process.env.DB_HOST ?? 'localhost',
|
|
9
|
+
port: parseInt(process.env.DB_PORT ?? '{{dbPort}}', 10),
|
|
10
|
+
username: process.env.DB_USER ?? 'postgres',
|
|
11
|
+
password: process.env.DB_PASSWORD ?? '',
|
|
12
|
+
database: process.env.DB_NAME ?? '{{projectName}}',
|
|
13
|
+
entities: [],
|
|
14
|
+
synchronize: process.env.NODE_ENV !== 'production',
|
|
15
|
+
}),
|
|
16
|
+
],
|
|
17
|
+
})
|
|
18
|
+
export class DatabaseModule {}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Test, TestingModule } from '@nestjs/testing';
|
|
2
|
+
import { HealthController } from './health.controller';
|
|
3
|
+
import { HealthService } from './health.service';
|
|
4
|
+
|
|
5
|
+
describe('HealthController', () => {
|
|
6
|
+
let controller: HealthController;
|
|
7
|
+
|
|
8
|
+
beforeEach(async () => {
|
|
9
|
+
const module: TestingModule = await Test.createTestingModule({
|
|
10
|
+
controllers: [HealthController],
|
|
11
|
+
providers: [HealthService],
|
|
12
|
+
}).compile();
|
|
13
|
+
|
|
14
|
+
controller = module.get<HealthController>(HealthController);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('returns ok status', () => {
|
|
18
|
+
expect(controller.check()).toEqual({ status: 'ok' });
|
|
19
|
+
});
|
|
20
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Test, TestingModule } from '@nestjs/testing';
|
|
2
|
+
import { HealthService } from './health.service';
|
|
3
|
+
|
|
4
|
+
describe('HealthService', () => {
|
|
5
|
+
let service: HealthService;
|
|
6
|
+
|
|
7
|
+
beforeEach(async () => {
|
|
8
|
+
const module: TestingModule = await Test.createTestingModule({
|
|
9
|
+
providers: [HealthService],
|
|
10
|
+
}).compile();
|
|
11
|
+
|
|
12
|
+
service = module.get<HealthService>(HealthService);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('returns ok status', () => {
|
|
16
|
+
expect(service.check()).toEqual({ status: 'ok' });
|
|
17
|
+
});
|
|
18
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Controller, Get } from '@nestjs/common';
|
|
2
|
+
import { HealthService } from './health.service';
|
|
3
|
+
|
|
4
|
+
@Controller('health')
|
|
5
|
+
export class HealthController {
|
|
6
|
+
constructor(private readonly healthService: HealthService) {}
|
|
7
|
+
|
|
8
|
+
@Get()
|
|
9
|
+
check() {
|
|
10
|
+
return this.healthService.check();
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Module } from '@nestjs/common';
|
|
2
|
+
import { HealthController } from './health.controller';
|
|
3
|
+
import { HealthService } from './health.service';
|
|
4
|
+
|
|
5
|
+
@Module({
|
|
6
|
+
controllers: [HealthController],
|
|
7
|
+
providers: [HealthService],
|
|
8
|
+
})
|
|
9
|
+
export class HealthModule {}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { INestApplication } from '@nestjs/common';
|
|
2
|
+
import { Test, TestingModule } from '@nestjs/testing';
|
|
3
|
+
import * as request from 'supertest';
|
|
4
|
+
import { App } from 'supertest/types';
|
|
5
|
+
import { AppModule } from './../src/app.module';
|
|
6
|
+
|
|
7
|
+
describe('App (e2e)', () => {
|
|
8
|
+
let app: INestApplication<App>;
|
|
9
|
+
|
|
10
|
+
beforeEach(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
|
+
afterEach(async () => {
|
|
20
|
+
await app.close();
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('/health (GET)', () => {
|
|
24
|
+
return request(app.getHttpServer())
|
|
25
|
+
.get('/health')
|
|
26
|
+
.expect(200)
|
|
27
|
+
.expect({ status: 'ok' });
|
|
28
|
+
});
|
|
29
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"module": "commonjs",
|
|
4
|
+
"declaration": true,
|
|
5
|
+
"removeComments": true,
|
|
6
|
+
"emitDecoratorMetadata": true,
|
|
7
|
+
"experimentalDecorators": true,
|
|
8
|
+
"allowSyntheticDefaultImports": true,
|
|
9
|
+
"target": "ES2023",
|
|
10
|
+
"sourceMap": true,
|
|
11
|
+
"outDir": "./dist",
|
|
12
|
+
"baseUrl": "./",
|
|
13
|
+
"incremental": true,
|
|
14
|
+
"skipLibCheck": true,
|
|
15
|
+
"strictNullChecks": true,
|
|
16
|
+
"forceConsistentCasingInFileNames": true,
|
|
17
|
+
"noImplicitAny": false,
|
|
18
|
+
"strictBindCallApply": false,
|
|
19
|
+
"noFallthroughCasesInSwitch": false
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"name": "{{projectName}}-
|
|
2
|
+
"name": "{{projectName}}-backend",
|
|
3
3
|
"version": "0.0.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"author": "",
|
|
@@ -22,10 +22,13 @@
|
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"@nestjs/common": "^11.0.1",
|
|
25
|
+
"@nestjs/config": "^3.0.0",
|
|
25
26
|
"@nestjs/core": "^11.0.1",
|
|
26
27
|
"@nestjs/platform-express": "^11.0.1",
|
|
28
|
+
"@nestjs/typeorm": "^10.0.0",
|
|
27
29
|
"reflect-metadata": "^0.2.2",
|
|
28
|
-
"rxjs": "^7.8.1"
|
|
30
|
+
"rxjs": "^7.8.1",
|
|
31
|
+
"typeorm": "^0.3.0"
|
|
29
32
|
},
|
|
30
33
|
"devDependencies": {
|
|
31
34
|
"@eslint/eslintrc": "^3.2.0",
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { Module } from '@nestjs/common';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { ConfigModule } from '@nestjs/config';
|
|
3
|
+
import { DatabaseModule } from './modules/database/database.module';
|
|
4
|
+
import { HealthModule } from './modules/health/health.module';
|
|
4
5
|
|
|
5
6
|
@Module({
|
|
6
|
-
imports: [
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
imports: [
|
|
8
|
+
ConfigModule.forRoot({ isGlobal: true }),
|
|
9
|
+
DatabaseModule,
|
|
10
|
+
HealthModule,
|
|
11
|
+
],
|
|
9
12
|
})
|
|
10
13
|
export class AppModule {}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CreateDateColumn,
|
|
3
|
+
PrimaryGeneratedColumn,
|
|
4
|
+
UpdateDateColumn,
|
|
5
|
+
} from 'typeorm';
|
|
6
|
+
|
|
7
|
+
export abstract class BaseEntity {
|
|
8
|
+
@PrimaryGeneratedColumn('uuid')
|
|
9
|
+
id: string;
|
|
10
|
+
|
|
11
|
+
@CreateDateColumn()
|
|
12
|
+
createdAt: Date;
|
|
13
|
+
|
|
14
|
+
@UpdateDateColumn()
|
|
15
|
+
updatedAt: Date;
|
|
16
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { DeepPartial } from 'typeorm';
|
|
2
|
+
import { BaseEntity } from '../entities/base.entity';
|
|
3
|
+
import { ReadonlyEntityRepository } from './readonly-entity.repository';
|
|
4
|
+
|
|
5
|
+
export abstract class EntityRepository<
|
|
6
|
+
T extends BaseEntity,
|
|
7
|
+
> extends ReadonlyEntityRepository<T> {
|
|
8
|
+
async create(data: DeepPartial<T>): Promise<T> {
|
|
9
|
+
const entity = this.repo.create(data);
|
|
10
|
+
return this.repo.save(entity);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async update(id: string, data: DeepPartial<T>): Promise<T> {
|
|
14
|
+
await this.repo.update(id, data as any);
|
|
15
|
+
return this.findById(id) as Promise<T>;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async remove(id: string): Promise<void> {
|
|
19
|
+
await this.repo.delete(id);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { FindManyOptions, FindOptionsWhere, In, Repository } from 'typeorm';
|
|
2
|
+
import { BaseEntity } from '../entities/base.entity';
|
|
3
|
+
|
|
4
|
+
export abstract class ReadonlyEntityRepository<T extends BaseEntity> {
|
|
5
|
+
constructor(protected readonly repo: Repository<T>) {}
|
|
6
|
+
|
|
7
|
+
findAll(options?: FindManyOptions<T>): Promise<T[]> {
|
|
8
|
+
return this.repo.find(options);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
findByIds(ids: string[]): Promise<T[]> {
|
|
12
|
+
return this.repo.findBy({ id: In(ids) } as FindOptionsWhere<T>);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
findById(id: string): Promise<T | null> {
|
|
16
|
+
return this.repo.findOneBy({ id } as FindOptionsWhere<T>);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
findOne(where: FindOptionsWhere<T>): Promise<T | null> {
|
|
20
|
+
return this.repo.findOneBy(where);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { DeepPartial } from 'typeorm';
|
|
2
|
+
import { BaseEntity } from '../entities/base.entity';
|
|
3
|
+
import { EntityRepository } from '../repositories/entity.repository';
|
|
4
|
+
import { ReadonlyEntityService } from './readonly-entity.service';
|
|
5
|
+
|
|
6
|
+
export abstract class EntityService<
|
|
7
|
+
T extends BaseEntity,
|
|
8
|
+
> extends ReadonlyEntityService<T> {
|
|
9
|
+
constructor(protected readonly repository: EntityRepository<T>) {
|
|
10
|
+
super(repository);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
create(data: DeepPartial<T>): Promise<T> {
|
|
14
|
+
return this.repository.create(data);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
update(id: string, data: DeepPartial<T>): Promise<T> {
|
|
18
|
+
return this.repository.update(id, data);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
remove(id: string): Promise<void> {
|
|
22
|
+
return this.repository.remove(id);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { FindManyOptions, FindOptionsWhere } from 'typeorm';
|
|
2
|
+
import { BaseEntity } from '../entities/base.entity';
|
|
3
|
+
import { ReadonlyEntityRepository } from '../repositories/readonly-entity.repository';
|
|
4
|
+
|
|
5
|
+
export abstract class ReadonlyEntityService<T extends BaseEntity> {
|
|
6
|
+
constructor(protected readonly repository: ReadonlyEntityRepository<T>) {}
|
|
7
|
+
|
|
8
|
+
findAll(options?: FindManyOptions<T>): Promise<T[]> {
|
|
9
|
+
return this.repository.findAll(options);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
findByIds(ids: string[]): Promise<T[]> {
|
|
13
|
+
return this.repository.findByIds(ids);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
findById(id: string): Promise<T | null> {
|
|
17
|
+
return this.repository.findById(id);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
findOne(where: FindOptionsWhere<T>): Promise<T | null> {
|
|
21
|
+
return this.repository.findOne(where);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Module } from '@nestjs/common';
|
|
2
|
+
import { TypeOrmModule } from '@nestjs/typeorm';
|
|
3
|
+
|
|
4
|
+
@Module({
|
|
5
|
+
imports: [
|
|
6
|
+
TypeOrmModule.forRoot({
|
|
7
|
+
type: '{{dbType}}' as 'postgres' | 'mysql',
|
|
8
|
+
host: process.env.DB_HOST ?? 'localhost',
|
|
9
|
+
port: parseInt(process.env.DB_PORT ?? '{{dbPort}}', 10),
|
|
10
|
+
username: process.env.DB_USER ?? 'postgres',
|
|
11
|
+
password: process.env.DB_PASSWORD ?? '',
|
|
12
|
+
database: process.env.DB_NAME ?? '{{projectName}}',
|
|
13
|
+
entities: [],
|
|
14
|
+
synchronize: process.env.NODE_ENV !== 'production',
|
|
15
|
+
}),
|
|
16
|
+
],
|
|
17
|
+
})
|
|
18
|
+
export class DatabaseModule {}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Test, TestingModule } from '@nestjs/testing';
|
|
2
|
+
import { HealthController } from './health.controller';
|
|
3
|
+
import { HealthService } from './health.service';
|
|
4
|
+
|
|
5
|
+
describe('HealthController', () => {
|
|
6
|
+
let controller: HealthController;
|
|
7
|
+
|
|
8
|
+
beforeEach(async () => {
|
|
9
|
+
const module: TestingModule = await Test.createTestingModule({
|
|
10
|
+
controllers: [HealthController],
|
|
11
|
+
providers: [HealthService],
|
|
12
|
+
}).compile();
|
|
13
|
+
|
|
14
|
+
controller = module.get<HealthController>(HealthController);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('returns ok status', () => {
|
|
18
|
+
expect(controller.check()).toEqual({ status: 'ok' });
|
|
19
|
+
});
|
|
20
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Test, TestingModule } from '@nestjs/testing';
|
|
2
|
+
import { HealthService } from './health.service';
|
|
3
|
+
|
|
4
|
+
describe('HealthService', () => {
|
|
5
|
+
let service: HealthService;
|
|
6
|
+
|
|
7
|
+
beforeEach(async () => {
|
|
8
|
+
const module: TestingModule = await Test.createTestingModule({
|
|
9
|
+
providers: [HealthService],
|
|
10
|
+
}).compile();
|
|
11
|
+
|
|
12
|
+
service = module.get<HealthService>(HealthService);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('returns ok status', () => {
|
|
16
|
+
expect(service.check()).toEqual({ status: 'ok' });
|
|
17
|
+
});
|
|
18
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Controller, Get } from '@nestjs/common';
|
|
2
|
+
import { HealthService } from './health.service';
|
|
3
|
+
|
|
4
|
+
@Controller('health')
|
|
5
|
+
export class HealthController {
|
|
6
|
+
constructor(private readonly healthService: HealthService) {}
|
|
7
|
+
|
|
8
|
+
@Get()
|
|
9
|
+
check() {
|
|
10
|
+
return this.healthService.check();
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Module } from '@nestjs/common';
|
|
2
|
+
import { HealthController } from './health.controller';
|
|
3
|
+
import { HealthService } from './health.service';
|
|
4
|
+
|
|
5
|
+
@Module({
|
|
6
|
+
controllers: [HealthController],
|
|
7
|
+
providers: [HealthService],
|
|
8
|
+
})
|
|
9
|
+
export class HealthModule {}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { Test, TestingModule } from '@nestjs/testing';
|
|
2
1
|
import { INestApplication } from '@nestjs/common';
|
|
2
|
+
import { Test, TestingModule } from '@nestjs/testing';
|
|
3
3
|
import * as request from 'supertest';
|
|
4
4
|
import { App } from 'supertest/types';
|
|
5
5
|
import { AppModule } from './../src/app.module';
|
|
6
6
|
|
|
7
|
-
describe('
|
|
7
|
+
describe('App (e2e)', () => {
|
|
8
8
|
let app: INestApplication<App>;
|
|
9
9
|
|
|
10
10
|
beforeEach(async () => {
|
|
@@ -16,10 +16,14 @@ describe('AppController (e2e)', () => {
|
|
|
16
16
|
await app.init();
|
|
17
17
|
});
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
afterEach(async () => {
|
|
20
|
+
await app.close();
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('/health (GET)', () => {
|
|
20
24
|
return request(app.getHttpServer())
|
|
21
|
-
.get('/')
|
|
25
|
+
.get('/health')
|
|
22
26
|
.expect(200)
|
|
23
|
-
.expect('
|
|
27
|
+
.expect({ status: 'ok' });
|
|
24
28
|
});
|
|
25
29
|
});
|
|
@@ -6,9 +6,13 @@
|
|
|
6
6
|
"dev": "nx run-many -t dev",
|
|
7
7
|
"build": "nx run-many -t build",
|
|
8
8
|
"test": "nx run-many -t test",
|
|
9
|
-
"lint": "nx run-many -t lint"
|
|
9
|
+
"lint": "nx run-many -t lint",
|
|
10
|
+
"generate:module": "nx g @local/generators:module",
|
|
11
|
+
"generate:resolver": "nx g @local/generators:resolver",
|
|
12
|
+
"generate:controller": "nx g @local/generators:controller"
|
|
10
13
|
},
|
|
11
14
|
"devDependencies": {
|
|
15
|
+
"@nx/devkit": "^20.0.0",
|
|
12
16
|
"nx": "^20.0.0"
|
|
13
17
|
}
|
|
14
18
|
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Controller,
|
|
3
|
+
Delete,
|
|
4
|
+
Get,
|
|
5
|
+
Param,
|
|
6
|
+
ParseUUIDPipe,
|
|
7
|
+
Query,
|
|
8
|
+
} from '@nestjs/common';
|
|
9
|
+
import { FindManyOptions } from 'typeorm';
|
|
10
|
+
import { <%= className %>Model } from '../../modules/<%= fileName %>/<%= fileName %>.model';
|
|
11
|
+
import { <%= className %>Service } from '../../modules/<%= fileName %>/<%= fileName %>.service';
|
|
12
|
+
|
|
13
|
+
@Controller('<%= fileName %>s')
|
|
14
|
+
export class <%= className %>Controller {
|
|
15
|
+
constructor(private readonly service: <%= className %>Service) {}
|
|
16
|
+
|
|
17
|
+
@Get()
|
|
18
|
+
findAll(@Query() query: FindManyOptions<<%= className %>Model>) {
|
|
19
|
+
return this.service.findAll(query);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
@Get('by-ids')
|
|
23
|
+
findByIds(@Query('ids') ids: string) {
|
|
24
|
+
return this.service.findByIds(ids.split(','));
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
@Get(':id')
|
|
28
|
+
findById(@Param('id', ParseUUIDPipe) id: string) {
|
|
29
|
+
return this.service.findById(id);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
@Delete(':id')
|
|
33
|
+
remove(@Param('id', ParseUUIDPipe) id: string) {
|
|
34
|
+
return this.service.remove(id);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
const { formatFiles, generateFiles, names } = require('@nx/devkit');
|
|
2
|
+
const { execSync } = require('node:child_process');
|
|
3
|
+
const { join } = require('node:path');
|
|
4
|
+
|
|
5
|
+
module.exports = async function (tree, options) {
|
|
6
|
+
const n = names(options.name);
|
|
7
|
+
const controllerPath = `apps/backend/src/api/${n.fileName}`;
|
|
8
|
+
|
|
9
|
+
generateFiles(tree, join(__dirname, 'files'), controllerPath, { ...n, tmpl: '' });
|
|
10
|
+
|
|
11
|
+
await formatFiles(tree);
|
|
12
|
+
|
|
13
|
+
console.log(`\n✓ Controller created at ${controllerPath}/`);
|
|
14
|
+
console.log(` → Import ${n.className}Module and register ${n.className}Controller in your module\n`);
|
|
15
|
+
|
|
16
|
+
return () => {
|
|
17
|
+
execSync(`npx prettier --write ${controllerPath}`, {
|
|
18
|
+
cwd: tree.root,
|
|
19
|
+
stdio: 'inherit',
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/schema",
|
|
3
|
+
"cli": "nx",
|
|
4
|
+
"id": "controller",
|
|
5
|
+
"title": "Create a REST controller",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"properties": {
|
|
8
|
+
"name": {
|
|
9
|
+
"type": "string",
|
|
10
|
+
"description": "Module name to generate a controller for (e.g. trainer)",
|
|
11
|
+
"$default": {
|
|
12
|
+
"$source": "argv",
|
|
13
|
+
"index": 0
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"required": ["name"]
|
|
18
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"generators": {
|
|
3
|
+
"module": {
|
|
4
|
+
"factory": "./module/index",
|
|
5
|
+
"schema": "./module/schema.json",
|
|
6
|
+
"description": "Create a NestJS domain module (model, repository, service)"
|
|
7
|
+
},
|
|
8
|
+
"resolver": {
|
|
9
|
+
"factory": "./resolver/index",
|
|
10
|
+
"schema": "./resolver/schema.json",
|
|
11
|
+
"description": "Create a GraphQL resolver in src/resolvers/"
|
|
12
|
+
},
|
|
13
|
+
"controller": {
|
|
14
|
+
"factory": "./controller/index",
|
|
15
|
+
"schema": "./controller/schema.json",
|
|
16
|
+
"description": "Create a REST controller in src/api/"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Module } from '@nestjs/common';
|
|
2
|
+
import { TypeOrmModule } from '@nestjs/typeorm';
|
|
3
|
+
import { <%= className %>Model } from './<%= fileName %>.model';
|
|
4
|
+
import { <%= className %>Repository } from './<%= fileName %>.repository';
|
|
5
|
+
import { <%= className %>Service } from './<%= fileName %>.service';
|
|
6
|
+
|
|
7
|
+
@Module({
|
|
8
|
+
imports: [TypeOrmModule.forFeature([<%= className %>Model])],
|
|
9
|
+
providers: [<%= className %>Service, <%= className %>Repository],
|
|
10
|
+
exports: [<%= className %>Service, <%= className %>Repository],
|
|
11
|
+
})
|
|
12
|
+
export class <%= className %>Module {}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Injectable } from '@nestjs/common';
|
|
2
|
+
import { InjectRepository } from '@nestjs/typeorm';
|
|
3
|
+
import { Repository } from 'typeorm';
|
|
4
|
+
import { EntityRepository } from '../../common/repositories/entity.repository';
|
|
5
|
+
import { <%= className %>Model } from './<%= fileName %>.model';
|
|
6
|
+
|
|
7
|
+
@Injectable()
|
|
8
|
+
export class <%= className %>Repository extends EntityRepository<<%= className %>Model> {
|
|
9
|
+
constructor(
|
|
10
|
+
@InjectRepository(<%= className %>Model)
|
|
11
|
+
repo: Repository<<%= className %>Model>,
|
|
12
|
+
) {
|
|
13
|
+
super(repo);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Injectable } from '@nestjs/common';
|
|
2
|
+
import { EntityService } from '../../common/services/entity.service';
|
|
3
|
+
import { <%= className %>Model } from './<%= fileName %>.model';
|
|
4
|
+
import { <%= className %>Repository } from './<%= fileName %>.repository';
|
|
5
|
+
|
|
6
|
+
@Injectable()
|
|
7
|
+
export class <%= className %>Service extends EntityService<<%= className %>Model> {
|
|
8
|
+
constructor(repository: <%= className %>Repository) {
|
|
9
|
+
super(repository);
|
|
10
|
+
}
|
|
11
|
+
}
|