@mbc-cqrs-serverless/cli 0.1.49-beta.0 → 0.1.51-beta.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 (109) hide show
  1. package/README.md +94 -63
  2. package/dist/actions/generate.action.js +44 -0
  3. package/dist/actions/new.action.get-package-version.spec.js +29 -0
  4. package/dist/actions/new.action.is-latest-version.spec.js +36 -0
  5. package/dist/actions/new.action.js +12 -6
  6. package/dist/actions/new.action.spec.js +84 -0
  7. package/dist/actions/new.action.update-env-local.spec.js +35 -0
  8. package/dist/actions/new.action.use-package-version.spec.js +46 -0
  9. package/dist/actions/ui.action.js +7 -5
  10. package/dist/commands/command.input.js +2 -0
  11. package/dist/commands/generate.command.js +24 -0
  12. package/dist/commands/index.js +2 -0
  13. package/dist/index.js +13 -2
  14. package/dist/runners/abstract.runner.js +44 -0
  15. package/dist/runners/schematic.runner.js +21 -0
  16. package/dist/schematics/collection.json +34 -0
  17. package/dist/schematics/index.js +17 -0
  18. package/dist/schematics/lib/controller/controller.factory.js +40 -0
  19. package/dist/schematics/lib/controller/controller.factory.spec.js +79 -0
  20. package/dist/schematics/lib/controller/files/__name@dasherize__.controller.ts +11 -0
  21. package/dist/schematics/lib/controller/schema.json +18 -0
  22. package/dist/schematics/lib/controller/units/__name@dasherize__.controller.__specFileSuffix__.ts +19 -0
  23. package/dist/schematics/lib/dto/dto.factory.js +32 -0
  24. package/dist/schematics/lib/dto/dto.factory.spec.js +128 -0
  25. package/dist/schematics/lib/dto/files/dto/__name@dasherize__-attributes.dto.ts +6 -0
  26. package/dist/schematics/lib/dto/files/dto/__name@dasherize__-command.dto.ts +16 -0
  27. package/dist/schematics/lib/dto/files/dto/__name@dasherize__-create.dto.ts +18 -0
  28. package/dist/schematics/lib/dto/files/dto/__name@dasherize__-search.dto.ts +2 -0
  29. package/dist/schematics/lib/dto/files/dto/__name@dasherize__-update.dto.ts +34 -0
  30. package/dist/schematics/lib/dto/schema.json +18 -0
  31. package/dist/schematics/lib/entity/entity.factory.js +30 -0
  32. package/dist/schematics/lib/entity/entity.factory.spec.js +86 -0
  33. package/dist/schematics/lib/entity/files/entity/__name@dasherize__-command.entity.ts +12 -0
  34. package/dist/schematics/lib/entity/files/entity/__name@dasherize__-data-list.entity.ts +12 -0
  35. package/dist/schematics/lib/entity/files/entity/__name@dasherize__-data.entity.ts +12 -0
  36. package/dist/schematics/lib/entity/schema.json +18 -0
  37. package/dist/schematics/lib/module/files/async/__name@dasherize__.controller.ts +74 -0
  38. package/dist/schematics/lib/module/files/async/__name@dasherize__.module.ts +19 -0
  39. package/dist/schematics/lib/module/files/async/__name@dasherize__.service.ts +164 -0
  40. package/dist/schematics/lib/module/files/async/dto/__name@dasherize__-attributes.dto.ts +6 -0
  41. package/dist/schematics/lib/module/files/async/dto/__name@dasherize__-command.dto.ts +16 -0
  42. package/dist/schematics/lib/module/files/async/dto/__name@dasherize__-create.dto.ts +18 -0
  43. package/dist/schematics/lib/module/files/async/dto/__name@dasherize__-search.dto.ts +2 -0
  44. package/dist/schematics/lib/module/files/async/dto/__name@dasherize__-update.dto.ts +34 -0
  45. package/dist/schematics/lib/module/files/async/entity/__name@dasherize__-command.entity.ts +12 -0
  46. package/dist/schematics/lib/module/files/async/entity/__name@dasherize__-data-list.entity.ts +12 -0
  47. package/dist/schematics/lib/module/files/async/entity/__name@dasherize__-data.entity.ts +12 -0
  48. package/dist/schematics/lib/module/files/async/handler/__name@dasherize__-rds.handler.ts +62 -0
  49. package/dist/schematics/lib/module/files/sync/__name@dasherize__.controller.ts +74 -0
  50. package/dist/schematics/lib/module/files/sync/__name@dasherize__.module.ts +19 -0
  51. package/dist/schematics/lib/module/files/sync/__name@dasherize__.service.ts +164 -0
  52. package/dist/schematics/lib/module/files/sync/dto/__name@dasherize__-attributes.dto.ts +6 -0
  53. package/dist/schematics/lib/module/files/sync/dto/__name@dasherize__-command.dto.ts +16 -0
  54. package/dist/schematics/lib/module/files/sync/dto/__name@dasherize__-create.dto.ts +18 -0
  55. package/dist/schematics/lib/module/files/sync/dto/__name@dasherize__-search.dto.ts +2 -0
  56. package/dist/schematics/lib/module/files/sync/dto/__name@dasherize__-update.dto.ts +34 -0
  57. package/dist/schematics/lib/module/files/sync/entity/__name@dasherize__-command.entity.ts +12 -0
  58. package/dist/schematics/lib/module/files/sync/entity/__name@dasherize__-data-list.entity.ts +12 -0
  59. package/dist/schematics/lib/module/files/sync/entity/__name@dasherize__-data.entity.ts +12 -0
  60. package/dist/schematics/lib/module/files/sync/handler/__name@dasherize__-rds.handler.ts +62 -0
  61. package/dist/schematics/lib/module/module.factory.js +204 -0
  62. package/dist/schematics/lib/module/module.factory.spec.js +188 -0
  63. package/dist/schematics/lib/module/schema.json +28 -0
  64. package/dist/schematics/lib/module/units/__name@dasherize__.controller.__specFileSuffix__.ts +19 -0
  65. package/dist/schematics/lib/module/units/__name@dasherize__.service.__specFileSuffix__.ts +19 -0
  66. package/dist/schematics/lib/service/files/__name@dasherize__.service.ts +12 -0
  67. package/dist/schematics/lib/service/schema.json +18 -0
  68. package/dist/schematics/lib/service/service.factory.js +40 -0
  69. package/dist/schematics/lib/service/service.factory.spec.js +81 -0
  70. package/dist/schematics/lib/service/units/__name@dasherize__.service.__specFileSuffix__.ts +19 -0
  71. package/dist/schematics/schematic.colection.js +60 -0
  72. package/dist/schematics/schematic.option.js +44 -0
  73. package/dist/schematics/utils/check-files-exist.js +13 -0
  74. package/dist/schematics/utils/index.js +17 -0
  75. package/dist/ui/index.js +18 -0
  76. package/dist/ui/logger.js +54 -0
  77. package/dist/ui/message.js +6 -0
  78. package/dist/utils/formatting.js +18 -0
  79. package/dist/utils/index.js +18 -0
  80. package/dist/utils/local-binaries.js +20 -0
  81. package/package.json +14 -5
  82. package/templates/.env.local +1 -1
  83. package/templates/README.md +1 -1
  84. package/templates/infra/README.md +6 -1
  85. package/templates/infra/libs/infra-stack.ts +1 -1
  86. package/templates/infra-local/docker-compose.yml +1 -1
  87. package/templates/infra-local/serverless.yml +19 -21
  88. package/templates/infra-local/swagger.json +396 -0
  89. package/templates/package.json +1 -0
  90. package/templates/prisma/dynamodbs/cqrs.json +1 -1
  91. package/templates/prisma/schema.prisma +4 -7
  92. package/templates/src/helpers/id.ts +12 -0
  93. package/templates/src/helpers/index.ts +1 -0
  94. package/templates/src/main.module.ts +2 -2
  95. package/templates/src/{master/dto/master-attributes.dto.ts → sample/dto/sample-attributes.dto.ts} +2 -2
  96. package/templates/src/{master/dto/master-command.dto.ts → sample/dto/sample-command.dto.ts} +4 -4
  97. package/templates/src/sample/entity/sample-command.entity.ts +13 -0
  98. package/templates/src/sample/entity/sample-data-list.entity.ts +13 -0
  99. package/templates/src/sample/entity/sample-data.entity.ts +13 -0
  100. package/templates/src/{master/handler/master-rds.handler.ts → sample/handler/sample-rds.handler.ts} +5 -7
  101. package/templates/src/{master/master.controller.ts → sample/sample.controller.ts} +22 -22
  102. package/templates/src/sample/sample.module.ts +19 -0
  103. package/templates/src/{master/master.service.ts → sample/sample.service.ts} +12 -12
  104. package/templates/test/api.http +25 -0
  105. package/templates/tsconfig.json +1 -1
  106. package/templates/src/master/entity/master-command.entity.ts +0 -13
  107. package/templates/src/master/entity/master-data-list.entity.ts +0 -13
  108. package/templates/src/master/entity/master-data.entity.ts +0 -13
  109. package/templates/src/master/master.module.ts +0 -19
@@ -0,0 +1,19 @@
1
+ import { CommandModule } from '@mbc-cqrs-serverless/core'
2
+ import { Module } from '@nestjs/common'
3
+
4
+ <% if (schema) { %>import { <%= classify(name) %>DataSyncRdsHandler } from './handler/<%= dasherize(name) %>-rds.handler'<% } %>
5
+ import { <%= classify(name) %>Controller } from './<%= dasherize(name) %>.controller'
6
+ import { <%= classify(name) %>Service } from './<%= dasherize(name) %>.service'
7
+
8
+ @Module({
9
+ imports: [
10
+ CommandModule.register({
11
+ tableName: '<%= dasherize(name) %>',
12
+ <% if (schema) { %>dataSyncHandlers: [<%= classify(name) %>DataSyncRdsHandler],<% }
13
+ else { %>dataSyncHandlers: [],<% } %>
14
+ }),
15
+ ],
16
+ controllers: [<%= classify(name) %>Controller],
17
+ providers: [<%= classify(name) %>Service],
18
+ })
19
+ export class <%= classify(name) %>Module {}
@@ -0,0 +1,164 @@
1
+ import {
2
+ CommandPartialInputModel,
3
+ CommandService,
4
+ DataService,
5
+ DetailDto,
6
+ generateId,
7
+ getUserContext,
8
+ IInvoke,
9
+ toISOStringWithTimezone,
10
+ VERSION_FIRST,
11
+ } from '@mbc-cqrs-serverless/core'
12
+ import { KEY_SEPARATOR } from '@mbc-cqrs-serverless/core'
13
+ import {
14
+ BadRequestException,
15
+ Injectable,
16
+ Logger,
17
+ NotFoundException,
18
+ } from '@nestjs/common'
19
+ import { Prisma } from '@prisma/client'
20
+ import { getOrderBys, parsePk } from 'src/helpers'
21
+ import { PrismaService } from 'src/prisma'
22
+ import { ulid } from 'ulid'
23
+
24
+ import { <%= classify(name) %>CommandDto } from './dto/<%= dasherize(name) %>-command.dto'
25
+ import { <%= classify(name) %>CreateDto } from './dto/<%= dasherize(name) %>-create.dto'
26
+ import { <%= classify(name) %>SearchDto } from './dto/<%= dasherize(name) %>-search.dto'
27
+ import { <%= classify(name) %>UpdateDto } from './dto/<%= dasherize(name) %>-update.dto'
28
+ import { <%= classify(name) %>DataEntity } from './entity/<%= dasherize(name) %>-data.entity'
29
+ import { <%= classify(name) %>DataListEntity } from './entity/<%= dasherize(name) %>-data-list.entity'
30
+
31
+ @Injectable()
32
+ export class <%= classify(name) %>Service {
33
+ private readonly logger = new Logger(<%= classify(name) %>Service.name)
34
+
35
+ constructor(
36
+ private readonly commandService: CommandService,
37
+ private readonly dataService: DataService,
38
+ <% if (schema) { %>private readonly prismaService: PrismaService,<% } %>
39
+ ) {}
40
+
41
+ async create(
42
+ createDto: <%= classify(name) %>CreateDto,
43
+ opts: { invokeContext: IInvoke },
44
+ ): Promise<<%= classify(name) %>DataEntity> {
45
+ const { tenantCode } = getUserContext(opts.invokeContext)
46
+ const pk = `<%= name.toUpperCase() %>${KEY_SEPARATOR}${tenantCode}`
47
+ const sk = ulid()
48
+ const <%= camelize(name) %> = new <%= classify(name) %>CommandDto({
49
+ pk,
50
+ sk,
51
+ id: generateId(pk, sk),
52
+ tenantCode,
53
+ code: sk,
54
+ type: '<%= name.toUpperCase() %>',
55
+ version: VERSION_FIRST,
56
+ name: createDto.name,
57
+ attributes: createDto.attributes,
58
+ })
59
+ const item = await this.commandService.publishSync(<%= camelize(name) %>, opts)
60
+ return new <%= classify(name) %>DataEntity(item as <%= classify(name) %>DataEntity)
61
+ }
62
+
63
+ async findOne(detailDto: DetailDto): Promise<<%= classify(name) %>DataEntity> {
64
+ const item = await this.dataService.getItem(detailDto)
65
+ if (!item) {
66
+ throw new NotFoundException('<%= classify(name) %> not found!')
67
+ }
68
+ this.logger.debug('item:', item)
69
+ return new <%= classify(name) %>DataEntity(item as <%= classify(name) %>DataEntity)
70
+ }
71
+
72
+ <% if (schema) { %>async findAll(
73
+ tenantCode: string,
74
+ searchDto: <%= classify(name) %>SearchDto,
75
+ ): Promise<<%= classify(name) %>DataListEntity> {
76
+ const where: Prisma.<%= classify(name) %>WhereInput = {
77
+ isDeleted: false,
78
+ tenantCode,
79
+ }
80
+
81
+ const { pageSize = 10, page = 1, orderBys = ['-createdAt'] } = searchDto
82
+
83
+ const [total, items] = await Promise.all([
84
+ this.prismaService.<%= camelize(name) %>.count({ where }),
85
+ this.prismaService.<%= camelize(name) %>.findMany({
86
+ where,
87
+ take: pageSize,
88
+ skip: pageSize * (page - 1),
89
+ orderBy: getOrderBys<Prisma.<%= classify(name) %>OrderByWithRelationInput>(orderBys),
90
+ }),
91
+ ])
92
+
93
+ return new <%= classify(name) %>DataListEntity({
94
+ total,
95
+ items: items.map(
96
+ (item) =>
97
+ new <%= classify(name) %>DataEntity({
98
+ ...item,
99
+ attributes: {
100
+ value: item.attributes as object,
101
+ },
102
+ }),
103
+ ),
104
+ })
105
+ }<% } %>
106
+
107
+ async update(
108
+ detailDto: DetailDto,
109
+ updateDto: <%= classify(name) %>UpdateDto,
110
+ opts: { invokeContext: IInvoke },
111
+ ): Promise<<%= classify(name) %>DataEntity> {
112
+ const userContext = getUserContext(opts.invokeContext)
113
+ const { tenantCode } = parsePk(detailDto.pk)
114
+ if (userContext.tenantCode !== tenantCode) {
115
+ throw new BadRequestException('Invalid tenant code')
116
+ }
117
+ const data = (await this.dataService.getItem(detailDto)) as <%= classify(name) %>DataEntity
118
+ if (!data) {
119
+ throw new NotFoundException('<%= classify(name) %> not found!')
120
+ }
121
+ const commandDto = new <%= classify(name) %>CommandDto({
122
+ pk: data.pk,
123
+ sk: data.sk,
124
+ version: data.version,
125
+ name: updateDto.name ?? data.name,
126
+ isDeleted: updateDto.isDeleted ?? data.isDeleted,
127
+ attributes: {
128
+ ...data.attributes,
129
+ ...updateDto.attributes,
130
+ },
131
+ })
132
+ const item = await this.commandService.publishPartialUpdateSync(
133
+ commandDto,
134
+ opts,
135
+ )
136
+ return new <%= classify(name) %>DataEntity(item as <%= classify(name) %>DataEntity)
137
+ }
138
+
139
+ async remove(key: DetailDto, opts: { invokeContext: IInvoke }) {
140
+ const userContext = getUserContext(opts.invokeContext)
141
+ const { tenantCode } = parsePk(key.pk)
142
+
143
+ if (userContext.tenantCode !== tenantCode) {
144
+ throw new BadRequestException('Invalid tenant code')
145
+ }
146
+
147
+ const data = (await this.dataService.getItem(key)) as <%= classify(name) %>DataEntity
148
+ if (!data) {
149
+ throw new NotFoundException()
150
+ }
151
+ const commandDto: CommandPartialInputModel = {
152
+ pk: data.pk,
153
+ sk: data.sk,
154
+ version: data.version,
155
+ isDeleted: true,
156
+ }
157
+ const item = await this.commandService.publishPartialUpdateSync(
158
+ commandDto,
159
+ opts,
160
+ )
161
+
162
+ return new <%= classify(name) %>DataEntity(item as any)
163
+ }
164
+ }
@@ -0,0 +1,6 @@
1
+ import { IsObject } from 'class-validator'
2
+
3
+ export class <%= classify(name) %>Attributes {
4
+ @IsObject()
5
+ value: object
6
+ }
@@ -0,0 +1,16 @@
1
+ import { CommandDto } from '@mbc-cqrs-serverless/core'
2
+ import { Type } from 'class-transformer'
3
+ import { ValidateNested } from 'class-validator'
4
+
5
+ import { <%= classify(name) %>Attributes } from './<%= dasherize(name) %>-attributes.dto'
6
+
7
+ export class <%= classify(name) %>CommandDto extends CommandDto {
8
+ @Type(() => <%= classify(name) %>Attributes)
9
+ @ValidateNested()
10
+ attributes: <%= classify(name) %>Attributes
11
+
12
+ constructor(partial: Partial<<%= classify(name) %>CommandDto>) {
13
+ super()
14
+ Object.assign(this, partial)
15
+ }
16
+ }
@@ -0,0 +1,18 @@
1
+ import { Type } from 'class-transformer'
2
+ import { IsOptional, IsString, ValidateNested } from 'class-validator'
3
+
4
+ import { <%= classify(name) %>Attributes } from './<%= dasherize(name) %>-attributes.dto'
5
+
6
+ export class <%= classify(name) %>CreateDto {
7
+ @IsString()
8
+ name: string
9
+
10
+ @Type(() => <%= classify(name) %>Attributes)
11
+ @ValidateNested()
12
+ @IsOptional()
13
+ attributes?: <%= classify(name) %>Attributes
14
+
15
+ constructor(partial: Partial<<%= classify(name) %>CreateDto>) {
16
+ Object.assign(this, partial)
17
+ }
18
+ }
@@ -0,0 +1,2 @@
1
+ import { SearchDto } from '@mbc-cqrs-serverless/core'
2
+ export class <%= classify(name) %>SearchDto extends SearchDto {}
@@ -0,0 +1,34 @@
1
+ import { PartialType } from '@nestjs/swagger'
2
+ import { Transform, Type } from 'class-transformer'
3
+ import {
4
+ IsBoolean,
5
+ IsOptional,
6
+ IsString,
7
+ ValidateNested,
8
+ } from 'class-validator'
9
+
10
+ import { <%= classify(name) %>Attributes } from './<%= dasherize(name) %>-attributes.dto'
11
+
12
+ export class <%= classify(name) %>UpdateAttributes extends PartialType(<%= classify(name) %>Attributes) {}
13
+
14
+ export class <%= classify(name) %>UpdateDto {
15
+ @IsString()
16
+ @IsOptional()
17
+ name?: string
18
+
19
+ @IsBoolean()
20
+ @Transform(({ value }) =>
21
+ value === 'true' ? true : value === 'false' ? false : value,
22
+ )
23
+ @IsOptional()
24
+ isDeleted?: boolean
25
+
26
+ @Type(() => <%= classify(name) %>UpdateAttributes)
27
+ @ValidateNested()
28
+ @IsOptional()
29
+ attributes?: <%= classify(name) %>UpdateAttributes
30
+
31
+ constructor(partial: Partial<<%= classify(name) %>UpdateDto>) {
32
+ Object.assign(this, partial)
33
+ }
34
+ }
@@ -0,0 +1,12 @@
1
+ import { CommandEntity } from '@mbc-cqrs-serverless/core'
2
+
3
+ import { <%= classify(name) %>Attributes } from '../dto/<%= dasherize(name) %>-attributes.dto'
4
+
5
+ export class <%= classify(name) %>CommandEntity extends CommandEntity {
6
+ attributes: <%= classify(name) %>Attributes
7
+
8
+ constructor(partial: Partial<<%= classify(name) %>CommandEntity>) {
9
+ super()
10
+ Object.assign(this, partial)
11
+ }
12
+ }
@@ -0,0 +1,12 @@
1
+ import { DataListEntity } from '@mbc-cqrs-serverless/core'
2
+
3
+ import { <%= classify(name) %>DataEntity } from './<%= dasherize(name) %>-data.entity'
4
+
5
+ export class <%= classify(name) %>DataListEntity extends DataListEntity {
6
+ items: <%= classify(name) %>DataEntity[]
7
+
8
+ constructor(partial: Partial<<%= classify(name) %>DataListEntity>) {
9
+ super(partial)
10
+ Object.assign(this, partial)
11
+ }
12
+ }
@@ -0,0 +1,12 @@
1
+ import { DataEntity } from '@mbc-cqrs-serverless/core'
2
+
3
+ import { <%= classify(name) %>Attributes } from '../dto/<%= dasherize(name) %>-attributes.dto'
4
+
5
+ export class <%= classify(name) %>DataEntity extends DataEntity {
6
+ attributes: <%= classify(name) %>Attributes
7
+
8
+ constructor(partial: Partial<<%= classify(name) %>DataEntity>) {
9
+ super(partial)
10
+ Object.assign(this, partial)
11
+ }
12
+ }
@@ -0,0 +1,62 @@
1
+ import {
2
+ CommandModel,
3
+ IDataSyncHandler,
4
+ removeSortKeyVersion,
5
+ } from '@mbc-cqrs-serverless/core'
6
+ import { Injectable, Logger } from '@nestjs/common'
7
+ import { PrismaService } from 'src/prisma'
8
+
9
+ import { <%= classify(name) %>Attributes } from '../dto/<%= dasherize(name) %>-attributes.dto'
10
+
11
+ @Injectable()
12
+ export class <%= classify(name) %>DataSyncRdsHandler implements IDataSyncHandler {
13
+ private readonly logger = new Logger(<%= classify(name) %>DataSyncRdsHandler.name)
14
+
15
+ constructor(private readonly prismaService: PrismaService) {}
16
+
17
+ async up(cmd: CommandModel): Promise<any> {
18
+ this.logger.debug(cmd)
19
+ const sk = removeSortKeyVersion(cmd.sk)
20
+ const attrs = cmd.attributes as <%= classify(name) %>Attributes
21
+ await this.prismaService.<%= camelize(name) %>.upsert({
22
+ where: {
23
+ id: cmd.id,
24
+ },
25
+ update: {
26
+ csk: cmd.sk,
27
+ name: cmd.name,
28
+ version: cmd.version,
29
+ seq: cmd.seq,
30
+ isDeleted: cmd.isDeleted || false,
31
+ updatedAt: cmd.updatedAt,
32
+ updatedBy: cmd.updatedBy,
33
+ updatedIp: cmd.updatedIp,
34
+ // attributes
35
+ attributes: attrs.value,
36
+ },
37
+ create: {
38
+ id: cmd.id,
39
+ cpk: cmd.pk,
40
+ csk: cmd.sk,
41
+ pk: cmd.pk,
42
+ sk,
43
+ code: sk,
44
+ name: cmd.name,
45
+ version: cmd.version,
46
+ tenantCode: cmd.tenantCode,
47
+ seq: cmd.seq,
48
+ createdAt: cmd.createdAt,
49
+ createdBy: cmd.createdBy,
50
+ createdIp: cmd.createdIp,
51
+ updatedAt: cmd.updatedAt,
52
+ updatedBy: cmd.updatedBy,
53
+ updatedIp: cmd.updatedIp,
54
+ // attributes
55
+ attributes: attrs.value,
56
+ },
57
+ })
58
+ }
59
+ async down(cmd: CommandModel): Promise<any> {
60
+ this.logger.debug(cmd)
61
+ }
62
+ }
@@ -0,0 +1,204 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.main = main;
37
+ const core_1 = require("@angular-devkit/core");
38
+ const schematics_1 = require("@angular-devkit/schematics");
39
+ const ts = __importStar(require("typescript"));
40
+ const yaml_1 = require("yaml");
41
+ function main(options) {
42
+ return (tree, _context) => {
43
+ const filePath = (0, core_1.normalize)(`/src/${core_1.strings.dasherize(options.name)}/${core_1.strings.dasherize(options.name)}.module.ts`);
44
+ const isFileExists = tree.exists(filePath);
45
+ if (isFileExists) {
46
+ _context.logger.info(`Module file already exists at: ${filePath}`);
47
+ return;
48
+ }
49
+ updateMainModule(tree, options);
50
+ updateCdkInfraStack(tree, options);
51
+ updateCqrsTable(tree, options);
52
+ updateServerlessYaml(tree, options);
53
+ if (options.schema) {
54
+ updatePrismaSchema(tree, options);
55
+ }
56
+ return (0, schematics_1.chain)([createModule(options), createUnitTest(options)]);
57
+ };
58
+ }
59
+ // create rule
60
+ function createModule(options) {
61
+ return (0, schematics_1.mergeWith)((0, schematics_1.apply)((0, schematics_1.url)(`./files/${options.mode}`), [
62
+ options.schema ? (0, schematics_1.noop)() : (0, schematics_1.filter)((path) => !path.endsWith('.handler.ts')),
63
+ (0, schematics_1.template)({
64
+ ...core_1.strings,
65
+ ...options,
66
+ }),
67
+ (0, schematics_1.move)((0, core_1.normalize)(`/src/${core_1.strings.dasherize(options.name)}`)),
68
+ ]));
69
+ }
70
+ function createUnitTest(options) {
71
+ return (0, schematics_1.mergeWith)((0, schematics_1.apply)((0, schematics_1.url)('./units'), [
72
+ (0, schematics_1.template)({
73
+ ...core_1.strings,
74
+ ...options,
75
+ specFileSuffix: 'spec',
76
+ }),
77
+ (0, schematics_1.move)((0, core_1.normalize)(`/test/unit/${core_1.strings.dasherize(options.name)}`)),
78
+ ]));
79
+ }
80
+ // modify main.module.ts
81
+ function updateMainModule(tree, options) {
82
+ const mainModulePath = 'src/main.module.ts';
83
+ const isMainModulePathExists = tree.exists(mainModulePath);
84
+ if (isMainModulePathExists) {
85
+ const fileBuffer = tree.read(mainModulePath);
86
+ const content = fileBuffer.toString('utf-8');
87
+ const lines = content.split('\n');
88
+ lines.splice(5, 0, `import { ${core_1.strings.classify(options.name)}Module } from './${core_1.strings.dasherize(options.name)}/${core_1.strings.dasherize(options.name)}.module'`);
89
+ lines.splice(23, 0, ` ${core_1.strings.classify(options.name)}Module,`);
90
+ const newContent = lines.join('\n');
91
+ tree.overwrite(mainModulePath, newContent);
92
+ return tree;
93
+ }
94
+ }
95
+ // modify infra cdk
96
+ function updateCdkInfraStack(tree, options) {
97
+ const infraStackPath = 'infra/libs/infra-stack.ts';
98
+ const isInfraStackExists = tree.exists(infraStackPath);
99
+ if (isInfraStackExists) {
100
+ const fileBuffer = tree.read(infraStackPath);
101
+ const content = fileBuffer.toString('utf-8');
102
+ const sourceFile = ts.createSourceFile(infraStackPath, content, ts.ScriptTarget.Latest, true);
103
+ const updatedContent = updateTableNamesArray(sourceFile, [`${core_1.strings.dasherize(options.name)}-command`], content);
104
+ tree.overwrite(infraStackPath, updatedContent);
105
+ return tree;
106
+ }
107
+ }
108
+ function updateTableNamesArray(sourceFile, newTableNames, content) {
109
+ let updatedContent = content;
110
+ const visit = (node) => {
111
+ if (ts.isVariableDeclaration(node) &&
112
+ node.name.getText() === 'tableNames' &&
113
+ ts.isArrayLiteralExpression(node.initializer)) {
114
+ // Extract existing table names
115
+ const existingElements = node.initializer.elements.map((element) => element.getText().replace(/['"]/g, ''));
116
+ // Append new table names, ensuring no duplicates
117
+ const updatedTableNames = Array.from(new Set([...existingElements, ...newTableNames]));
118
+ // Generate the updated array string
119
+ const newArray = `[${updatedTableNames.map((name) => `'${name}'`).join(', ')}]`;
120
+ // Replace the existing array with the new array
121
+ updatedContent =
122
+ updatedContent.slice(0, node.initializer.getStart()) +
123
+ newArray +
124
+ updatedContent.slice(node.initializer.getEnd());
125
+ }
126
+ ts.forEachChild(node, visit);
127
+ };
128
+ visit(sourceFile);
129
+ return updatedContent;
130
+ }
131
+ // modify cqrs.json
132
+ function updateCqrsTable(tree, options) {
133
+ const cqrsTablePath = 'prisma/dynamodbs/cqrs.json';
134
+ const isCqrsTableExists = tree.exists(cqrsTablePath);
135
+ if (isCqrsTableExists) {
136
+ const fileContent = tree.read(cqrsTablePath)?.toString();
137
+ const jsonContent = JSON.parse(fileContent.toString());
138
+ jsonContent.push(core_1.strings.dasherize(options.name));
139
+ tree.overwrite(cqrsTablePath, JSON.stringify(jsonContent, null, 2));
140
+ return tree;
141
+ }
142
+ }
143
+ // modify prisma.schema
144
+ function updatePrismaSchema(tree, options) {
145
+ const schemaPath = 'prisma/schema.prisma';
146
+ const isSchemaExists = tree.exists(schemaPath);
147
+ if (isSchemaExists) {
148
+ const fileContent = tree.read(schemaPath)?.toString('utf-8');
149
+ const stringToAppend = generateModelTemplate(options.name);
150
+ const updatedContent = fileContent + stringToAppend;
151
+ tree.overwrite(schemaPath, updatedContent);
152
+ return tree;
153
+ }
154
+ }
155
+ // modify serverless.yaml
156
+ function updateServerlessYaml(tree, options) {
157
+ const serverlessPath = 'infra-local/serverless.yml';
158
+ const isServerlessExists = tree.exists(serverlessPath);
159
+ if (isServerlessExists) {
160
+ const fileContent = tree.read(serverlessPath)?.toString('utf-8');
161
+ const newStreamEvent = {
162
+ type: 'dynamodb',
163
+ maximumRetryAttempts: 10,
164
+ arn: '${env:LOCAL_DDB_%%TABLE_NAME%%_STREAM}'.replace('%%TABLE_NAME%%', options.name.toUpperCase()),
165
+ filterPatterns: [{ eventName: ['INSERT'] }],
166
+ };
167
+ const doc = (0, yaml_1.parseDocument)(fileContent);
168
+ const mainFunction = doc.getIn(['functions', 'main']);
169
+ const events = mainFunction.get('events');
170
+ events.items.push({ stream: newStreamEvent });
171
+ const updatedYamlContent = (0, yaml_1.stringify)(doc);
172
+ tree.overwrite(serverlessPath, updatedYamlContent);
173
+ return tree;
174
+ }
175
+ }
176
+ const generateModelTemplate = (name) => `
177
+ model ${core_1.strings.classify(name)} {
178
+ id String @id
179
+ cpk String // コマンド用PK
180
+ csk String // コマンド用SK
181
+ pk String // データ用PK, ${name.toUpperCase()}#tenantCode (テナントコード)
182
+ sk String // データ用SK, マスタ種別コード#マスタコード
183
+ tenantCode String @map("tenant_code") // テナントコード, 【テナントコードマスタ】
184
+ seq Int @default(0) // 並び順, 採番機能を使用する
185
+ code String // レコードのコード, マスタ種別コード#マスタコード
186
+ name String // レコード名, 名前
187
+ version Int // バージョン
188
+ isDeleted Boolean @default(false) @map("is_deleted") // 削除フラグ
189
+ createdBy String @default("") @map("created_by") // 作成者
190
+ createdIp String @default("") @map("created_ip") // 作成IP, IPv6も考慮する
191
+ createdAt DateTime @default(now()) @map("created_at") @db.Timestamp(0) // 作成日時
192
+ updatedBy String @default("") @map("updated_by") // 更新者
193
+ updatedIp String @default("") @map("updated_ip") // 更新IP, IPv6も考慮する
194
+ updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamp(0) // 更新日時
195
+
196
+ attributes Json? @map("attributes")
197
+
198
+ @@unique([cpk, csk])
199
+ @@unique([pk, sk])
200
+ @@unique([tenantCode, code])
201
+ @@index([tenantCode, name])
202
+ @@map("${core_1.strings.underscore(name)}s")
203
+ }
204
+ `;