@exanderal/stackcraft 0.4.2 → 0.5.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 +57 -8
- package/dist/create/index.d.ts +1 -1
- package/dist/create/index.d.ts.map +1 -1
- package/dist/create/index.js +34 -14
- package/dist/create/index.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.map +1 -1
- package/dist/create/scaffolders/api-nestjs-graphql.js +14 -17
- package/dist/create/scaffolders/api-nestjs-graphql.js.map +1 -1
- package/dist/create/scaffolders/api-nestjs-rest.d.ts.map +1 -1
- package/dist/create/scaffolders/api-nestjs-rest.js +14 -17
- package/dist/create/scaffolders/api-nestjs-rest.js.map +1 -1
- package/dist/create/scaffolders/orm.d.ts +6 -0
- package/dist/create/scaffolders/orm.d.ts.map +1 -0
- package/dist/create/scaffolders/orm.js +271 -0
- package/dist/create/scaffolders/orm.js.map +1 -0
- package/dist/create/scaffolders/setup-docker.js +33 -6
- package/dist/create/scaffolders/setup-docker.js.map +1 -1
- package/dist/create/scaffolders/utils/copy.d.ts.map +1 -1
- package/dist/create/scaffolders/utils/copy.js +1 -0
- package/dist/create/scaffolders/utils/copy.js.map +1 -1
- package/dist/create/types.d.ts +2 -0
- package/dist/create/types.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/templates/api-nestjs-graphql/package.json +1 -3
- package/templates/api-nestjs-rest/package.json +1 -3
- package/templates/base/tools/generators/module/graphql-files/__fileName__.model.ts__tmpl__ +10 -8
- package/templates/base/tools/generators/module/index.js +0 -4
- package/templates/base/tools/generators/module/schema.json +0 -6
- package/templates/orm-kysely/scripts/migration-create.ts +30 -0
- package/templates/orm-kysely/src/common/repositories/entity.repository.ts +33 -0
- package/templates/orm-kysely/src/common/repositories/readonly-entity.repository.ts +46 -0
- package/templates/orm-kysely/src/database/database.types.ts +17 -0
- package/templates/orm-kysely/src/database/migrations/.gitkeep +0 -0
- package/templates/orm-kysely/src/database/seeds/seed.ts +12 -0
- package/templates/orm-kysely/src/database/utils/columns.ts +32 -0
- package/templates/orm-kysely/src/database/utils/index.ts +3 -0
- package/templates/orm-kysely/src/database/utils/indexes.ts +20 -0
- package/templates/orm-kysely/src/database/utils/tables.ts +7 -0
- package/templates/orm-kysely/src/modules/database/database.module.ts +9 -0
- package/templates/orm-kysely/tools/generators/module/files/__fileName__.model.ts__tmpl__ +16 -0
- package/templates/orm-kysely/tools/generators/module/files/__fileName__.module.ts__tmpl__ +9 -0
- package/templates/orm-kysely/tools/generators/module/files/__fileName__.repository.ts__tmpl__ +26 -0
- package/templates/orm-kysely/tools/generators/module/files/__fileName__.service.ts__tmpl__ +28 -0
- package/templates/orm-kysely/tools/generators/module/files/__tests__/__fileName__.integration.spec.ts__tmpl__ +23 -0
- package/templates/orm-kysely/tools/generators/module/graphql-files/__fileName__.model.ts__tmpl__ +24 -0
- package/templates/orm-prisma/prisma/schema.prisma +8 -0
- package/templates/orm-prisma/prisma/seeds/seed.ts +16 -0
- package/templates/orm-prisma/src/modules/database/database.module.ts +8 -0
- package/templates/orm-prisma/src/modules/prisma/prisma.module.ts +9 -0
- package/templates/orm-prisma/src/modules/prisma/prisma.service.ts +9 -0
- package/templates/orm-prisma/tools/generators/module/files/__fileName__.model.ts__tmpl__ +15 -0
- package/templates/orm-prisma/tools/generators/module/files/__fileName__.module.ts__tmpl__ +9 -0
- package/templates/orm-prisma/tools/generators/module/files/__fileName__.repository.ts__tmpl__ +28 -0
- package/templates/orm-prisma/tools/generators/module/files/__fileName__.service.ts__tmpl__ +28 -0
- package/templates/orm-prisma/tools/generators/module/files/__tests__/__fileName__.integration.spec.ts__tmpl__ +23 -0
- package/templates/orm-prisma/tools/generators/module/graphql-files/__fileName__.model.ts__tmpl__ +23 -0
- package/templates/api-nestjs-graphql/src/common/entities/base.entity.ts +0 -21
- package/templates/api-nestjs-graphql/src/common/repositories/entity.repository.ts +0 -21
- package/templates/api-nestjs-graphql/src/common/repositories/readonly-entity.repository.ts +0 -22
- package/templates/api-nestjs-graphql/src/common/services/entity.service.ts +0 -24
- package/templates/api-nestjs-graphql/src/common/services/readonly-entity.service.ts +0 -23
- package/templates/api-nestjs-graphql/src/modules/database/database.module.ts +0 -18
- package/templates/api-nestjs-rest/src/common/entities/base.entity.ts +0 -16
- package/templates/api-nestjs-rest/src/common/repositories/entity.repository.ts +0 -21
- package/templates/api-nestjs-rest/src/common/repositories/readonly-entity.repository.ts +0 -22
- package/templates/api-nestjs-rest/src/common/services/entity.service.ts +0 -24
- package/templates/api-nestjs-rest/src/common/services/readonly-entity.service.ts +0 -23
- package/templates/api-nestjs-rest/src/modules/database/database.module.ts +0 -18
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { sql, CreateTableBuilder } from 'kysely';
|
|
2
|
+
|
|
3
|
+
export function withUuid<T extends string, C extends string>(
|
|
4
|
+
builder: CreateTableBuilder<T, C>,
|
|
5
|
+
dialect: 'postgres' | 'mysql' = 'postgres',
|
|
6
|
+
) {
|
|
7
|
+
const defaultFn =
|
|
8
|
+
dialect === 'mysql' ? sql`(UUID())` : sql`gen_random_uuid()`;
|
|
9
|
+
return builder.addColumn('id', 'uuid', (col) =>
|
|
10
|
+
col.primaryKey().defaultTo(defaultFn),
|
|
11
|
+
);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function withTimestamps<T extends string, C extends string>(
|
|
15
|
+
builder: CreateTableBuilder<T, C>,
|
|
16
|
+
) {
|
|
17
|
+
return builder
|
|
18
|
+
.addColumn('created_at', 'timestamptz', (col) =>
|
|
19
|
+
col.notNull().defaultTo(sql`now()`),
|
|
20
|
+
)
|
|
21
|
+
.addColumn('updated_at', 'timestamptz', (col) =>
|
|
22
|
+
col.notNull().defaultTo(sql`now()`),
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Shorthand: uuid primary key + timestamps
|
|
27
|
+
export function withDefaults<T extends string, C extends string>(
|
|
28
|
+
builder: CreateTableBuilder<T, C>,
|
|
29
|
+
dialect: 'postgres' | 'mysql' = 'postgres',
|
|
30
|
+
) {
|
|
31
|
+
return withTimestamps(withUuid(builder, dialect));
|
|
32
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Kysely } from 'kysely';
|
|
2
|
+
|
|
3
|
+
export async function createIndex(
|
|
4
|
+
db: Kysely<any>,
|
|
5
|
+
table: string,
|
|
6
|
+
columns: string | string[],
|
|
7
|
+
opts?: { unique?: boolean; name?: string },
|
|
8
|
+
) {
|
|
9
|
+
const cols = Array.isArray(columns) ? columns : [columns];
|
|
10
|
+
const name = opts?.name ?? `idx_${table}_${cols.join('_')}`;
|
|
11
|
+
let b = db.schema.createIndex(name).on(table).columns(cols);
|
|
12
|
+
if (opts?.unique) b = (b as any).unique();
|
|
13
|
+
await b.execute();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const createUniqueIndex = (
|
|
17
|
+
db: Kysely<any>,
|
|
18
|
+
table: string,
|
|
19
|
+
columns: string | string[],
|
|
20
|
+
) => createIndex(db, table, columns, { unique: true });
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Define this table in src/database/database.types.ts:
|
|
2
|
+
//
|
|
3
|
+
// export interface <%= className %>sTable {
|
|
4
|
+
// id: Generated<string>
|
|
5
|
+
// created_at: Generated<Date>
|
|
6
|
+
// updated_at: Generated<Date>
|
|
7
|
+
// }
|
|
8
|
+
//
|
|
9
|
+
// Then add to Database interface:
|
|
10
|
+
// <%= fileName %>s: <%= className %>sTable
|
|
11
|
+
|
|
12
|
+
export interface <%= className %> {
|
|
13
|
+
id: string;
|
|
14
|
+
createdAt: Date;
|
|
15
|
+
updatedAt: Date;
|
|
16
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Module } from '@nestjs/common';
|
|
2
|
+
import { <%= className %>Repository } from './<%= fileName %>.repository';
|
|
3
|
+
import { <%= className %>Service } from './<%= fileName %>.service';
|
|
4
|
+
|
|
5
|
+
@Module({
|
|
6
|
+
providers: [<%= className %>Service, <%= className %>Repository],
|
|
7
|
+
exports: [<%= className %>Service, <%= className %>Repository],
|
|
8
|
+
})
|
|
9
|
+
export class <%= className %>Module {}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Injectable } from '@nestjs/common';
|
|
2
|
+
import { EntityRepository } from '../../common/repositories/entity.repository';
|
|
3
|
+
import { KyselyService } from '../../modules/database/kysely.service';
|
|
4
|
+
import type { <%= className %> } from './<%= fileName %>.model';
|
|
5
|
+
|
|
6
|
+
// Add properties to enable filtering, e.g.:
|
|
7
|
+
// export type <%= className %>Filters = { id?: string }
|
|
8
|
+
export type <%= className %>Filters = Record<string, never>
|
|
9
|
+
|
|
10
|
+
@Injectable()
|
|
11
|
+
export class <%= className %>Repository extends EntityRepository<<%= className %>, <%= className %>Filters> {
|
|
12
|
+
protected table = '<%= fileName %>s';
|
|
13
|
+
|
|
14
|
+
constructor(kyselyService: KyselyService) {
|
|
15
|
+
super(kyselyService.db);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// protected filters = {
|
|
19
|
+
// id: where('<%= fileName %>s.id'),
|
|
20
|
+
// };
|
|
21
|
+
|
|
22
|
+
// protected override queryable() {
|
|
23
|
+
// return super.queryable()
|
|
24
|
+
// .innerJoin('other_table', 'other_table.id', '<%= fileName %>s.other_id')
|
|
25
|
+
// }
|
|
26
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Injectable } from '@nestjs/common';
|
|
2
|
+
import type { <%= className %> } from './<%= fileName %>.model';
|
|
3
|
+
import { <%= className %>Repository } from './<%= fileName %>.repository';
|
|
4
|
+
|
|
5
|
+
@Injectable()
|
|
6
|
+
export class <%= className %>Service {
|
|
7
|
+
constructor(private readonly repository: <%= className %>Repository) {}
|
|
8
|
+
|
|
9
|
+
findAll() {
|
|
10
|
+
return this.repository.findAll();
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
findById(id: string) {
|
|
14
|
+
return this.repository.findById(id);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
create(data: Omit<<%= className %>, 'id' | 'createdAt' | 'updatedAt'>) {
|
|
18
|
+
return this.repository.create(data);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
update(id: string, data: Partial<Omit<<%= className %>, 'id' | 'createdAt' | 'updatedAt'>>) {
|
|
22
|
+
return this.repository.update(id, data);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
remove(id: string) {
|
|
26
|
+
return this.repository.remove(id);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Test } from '@nestjs/testing';
|
|
2
|
+
import { KyselyService } from '../../modules/database/kysely.service';
|
|
3
|
+
import { <%= className %>Module } from '../<%= fileName %>.module';
|
|
4
|
+
import { <%= className %>Service } from '../<%= fileName %>.service';
|
|
5
|
+
|
|
6
|
+
describe('<%= className %>Service', () => {
|
|
7
|
+
let service: <%= className %>Service;
|
|
8
|
+
|
|
9
|
+
beforeAll(async () => {
|
|
10
|
+
const module = await Test.createTestingModule({
|
|
11
|
+
imports: [<%= className %>Module],
|
|
12
|
+
})
|
|
13
|
+
.overrideProvider(KyselyService)
|
|
14
|
+
.useValue({ db: {} })
|
|
15
|
+
.compile();
|
|
16
|
+
|
|
17
|
+
service = module.get(<%= className %>Service);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('is defined', () => {
|
|
21
|
+
expect(service).toBeDefined();
|
|
22
|
+
});
|
|
23
|
+
});
|
package/templates/orm-kysely/tools/generators/module/graphql-files/__fileName__.model.ts__tmpl__
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Field, ID, ObjectType } from '@nestjs/graphql';
|
|
2
|
+
|
|
3
|
+
// Define this table in src/database/database.types.ts:
|
|
4
|
+
//
|
|
5
|
+
// export interface <%= className %>sTable {
|
|
6
|
+
// id: Generated<string>
|
|
7
|
+
// created_at: Generated<Date>
|
|
8
|
+
// updated_at: Generated<Date>
|
|
9
|
+
// }
|
|
10
|
+
//
|
|
11
|
+
// Then add to Database interface:
|
|
12
|
+
// <%= fileName %>s: <%= className %>sTable
|
|
13
|
+
|
|
14
|
+
@ObjectType()
|
|
15
|
+
export class <%= className %> {
|
|
16
|
+
@Field(() => ID)
|
|
17
|
+
id: string;
|
|
18
|
+
|
|
19
|
+
@Field(() => String)
|
|
20
|
+
createdAt: Date;
|
|
21
|
+
|
|
22
|
+
@Field(() => String)
|
|
23
|
+
updatedAt: Date;
|
|
24
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { PrismaClient } from '@prisma/client';
|
|
2
|
+
|
|
3
|
+
const prisma = new PrismaClient();
|
|
4
|
+
|
|
5
|
+
async function main() {
|
|
6
|
+
// Example:
|
|
7
|
+
// await prisma.user.create({ data: { email: 'admin@example.com', name: 'Admin' } });
|
|
8
|
+
console.log('Seed complete.');
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
main()
|
|
12
|
+
.catch((e) => {
|
|
13
|
+
console.error(e);
|
|
14
|
+
process.exit(1);
|
|
15
|
+
})
|
|
16
|
+
.finally(() => prisma.$disconnect());
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// Add this model to prisma/schema.prisma:
|
|
2
|
+
//
|
|
3
|
+
// model <%= className %> {
|
|
4
|
+
// id String @id @default(cuid())
|
|
5
|
+
// createdAt DateTime @default(now())
|
|
6
|
+
// updatedAt DateTime @updatedAt
|
|
7
|
+
// }
|
|
8
|
+
//
|
|
9
|
+
// Then run: pnpm migration:run
|
|
10
|
+
|
|
11
|
+
export type <%= className %> = {
|
|
12
|
+
id: string;
|
|
13
|
+
createdAt: Date;
|
|
14
|
+
updatedAt: Date;
|
|
15
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Module } from '@nestjs/common';
|
|
2
|
+
import { <%= className %>Repository } from './<%= fileName %>.repository';
|
|
3
|
+
import { <%= className %>Service } from './<%= fileName %>.service';
|
|
4
|
+
|
|
5
|
+
@Module({
|
|
6
|
+
providers: [<%= className %>Service, <%= className %>Repository],
|
|
7
|
+
exports: [<%= className %>Service, <%= className %>Repository],
|
|
8
|
+
})
|
|
9
|
+
export class <%= className %>Module {}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Injectable } from '@nestjs/common';
|
|
2
|
+
import { PrismaService } from '../../modules/prisma/prisma.service';
|
|
3
|
+
import type { <%= className %> } from './<%= fileName %>.model';
|
|
4
|
+
|
|
5
|
+
@Injectable()
|
|
6
|
+
export class <%= className %>Repository {
|
|
7
|
+
constructor(private readonly prisma: PrismaService) {}
|
|
8
|
+
|
|
9
|
+
findAll() {
|
|
10
|
+
return this.prisma.<%= fileName %>.findMany();
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
findById(id: string) {
|
|
14
|
+
return this.prisma.<%= fileName %>.findUnique({ where: { id } });
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
create(data: Omit<<%= className %>, 'id' | 'createdAt' | 'updatedAt'>) {
|
|
18
|
+
return this.prisma.<%= fileName %>.create({ data });
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
update(id: string, data: Partial<Omit<<%= className %>, 'id' | 'createdAt' | 'updatedAt'>>) {
|
|
22
|
+
return this.prisma.<%= fileName %>.update({ where: { id }, data });
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
remove(id: string) {
|
|
26
|
+
return this.prisma.<%= fileName %>.delete({ where: { id } });
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Injectable } from '@nestjs/common';
|
|
2
|
+
import type { <%= className %> } from './<%= fileName %>.model';
|
|
3
|
+
import { <%= className %>Repository } from './<%= fileName %>.repository';
|
|
4
|
+
|
|
5
|
+
@Injectable()
|
|
6
|
+
export class <%= className %>Service {
|
|
7
|
+
constructor(private readonly repository: <%= className %>Repository) {}
|
|
8
|
+
|
|
9
|
+
findAll(): Promise<<%= className %>[]> {
|
|
10
|
+
return this.repository.findAll();
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
findById(id: string): Promise<<%= className %> | null> {
|
|
14
|
+
return this.repository.findById(id);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
create(data: Omit<<%= className %>, 'id' | 'createdAt' | 'updatedAt'>): Promise<<%= className %>> {
|
|
18
|
+
return this.repository.create(data);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
update(id: string, data: Partial<Omit<<%= className %>, 'id' | 'createdAt' | 'updatedAt'>>): Promise<<%= className %>> {
|
|
22
|
+
return this.repository.update(id, data);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
remove(id: string): Promise<<%= className %>> {
|
|
26
|
+
return this.repository.remove(id);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Test } from '@nestjs/testing';
|
|
2
|
+
import { PrismaService } from '../../modules/prisma/prisma.service';
|
|
3
|
+
import { <%= className %>Module } from '../<%= fileName %>.module';
|
|
4
|
+
import { <%= className %>Service } from '../<%= fileName %>.service';
|
|
5
|
+
|
|
6
|
+
describe('<%= className %>Service', () => {
|
|
7
|
+
let service: <%= className %>Service;
|
|
8
|
+
|
|
9
|
+
beforeAll(async () => {
|
|
10
|
+
const module = await Test.createTestingModule({
|
|
11
|
+
imports: [<%= className %>Module],
|
|
12
|
+
})
|
|
13
|
+
.overrideProvider(PrismaService)
|
|
14
|
+
.useValue({})
|
|
15
|
+
.compile();
|
|
16
|
+
|
|
17
|
+
service = module.get(<%= className %>Service);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('is defined', () => {
|
|
21
|
+
expect(service).toBeDefined();
|
|
22
|
+
});
|
|
23
|
+
});
|
package/templates/orm-prisma/tools/generators/module/graphql-files/__fileName__.model.ts__tmpl__
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Field, ID, ObjectType } from '@nestjs/graphql';
|
|
2
|
+
|
|
3
|
+
// Add this model to prisma/schema.prisma:
|
|
4
|
+
//
|
|
5
|
+
// model <%= className %> {
|
|
6
|
+
// id String @id @default(cuid())
|
|
7
|
+
// createdAt DateTime @default(now())
|
|
8
|
+
// updatedAt DateTime @updatedAt
|
|
9
|
+
// }
|
|
10
|
+
//
|
|
11
|
+
// Then run: pnpm migration:run
|
|
12
|
+
|
|
13
|
+
@ObjectType()
|
|
14
|
+
export class <%= className %> {
|
|
15
|
+
@Field(() => ID)
|
|
16
|
+
id: string;
|
|
17
|
+
|
|
18
|
+
@Field(() => String)
|
|
19
|
+
createdAt: Date;
|
|
20
|
+
|
|
21
|
+
@Field(() => String)
|
|
22
|
+
updatedAt: Date;
|
|
23
|
+
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { Field, ID, ObjectType } from '@nestjs/graphql';
|
|
2
|
-
import {
|
|
3
|
-
CreateDateColumn,
|
|
4
|
-
PrimaryGeneratedColumn,
|
|
5
|
-
UpdateDateColumn,
|
|
6
|
-
} from 'typeorm';
|
|
7
|
-
|
|
8
|
-
@ObjectType({ isAbstract: true })
|
|
9
|
-
export abstract class BaseEntity {
|
|
10
|
-
@Field(() => ID)
|
|
11
|
-
@PrimaryGeneratedColumn('uuid')
|
|
12
|
-
id: string;
|
|
13
|
-
|
|
14
|
-
@Field()
|
|
15
|
-
@CreateDateColumn()
|
|
16
|
-
createdAt: Date;
|
|
17
|
-
|
|
18
|
-
@Field()
|
|
19
|
-
@UpdateDateColumn()
|
|
20
|
-
updatedAt: Date;
|
|
21
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
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 {}
|
|
@@ -1,16 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
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
|
-
}
|