@othree.io/chisel-sdk 4.0.0 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/README.md +207 -1
  2. package/lib/cjs/aws/index.d.ts.map +1 -0
  3. package/lib/cjs/aws/index.js.map +1 -0
  4. package/lib/cjs/aws/read.d.ts +44 -0
  5. package/lib/cjs/aws/read.d.ts.map +1 -0
  6. package/lib/{aws → cjs/aws}/read.js +65 -48
  7. package/lib/cjs/aws/read.js.map +1 -0
  8. package/lib/cjs/aws/write.d.ts +23 -0
  9. package/lib/cjs/aws/write.d.ts.map +1 -0
  10. package/lib/{aws → cjs/aws}/write.js +56 -34
  11. package/lib/cjs/aws/write.js.map +1 -0
  12. package/lib/cjs/iac/index.d.ts +28 -0
  13. package/lib/cjs/iac/index.d.ts.map +1 -0
  14. package/lib/{iac → cjs/iac}/index.js +23 -8
  15. package/lib/cjs/iac/index.js.map +1 -0
  16. package/lib/cjs/iac/read.d.ts +50 -0
  17. package/lib/cjs/iac/read.d.ts.map +1 -0
  18. package/lib/{iac → cjs/iac}/read.js +58 -32
  19. package/lib/cjs/iac/read.js.map +1 -0
  20. package/lib/cjs/iac/shared.d.ts +14 -0
  21. package/lib/cjs/iac/shared.d.ts.map +1 -0
  22. package/lib/{iac → cjs/iac}/shared.js +12 -8
  23. package/lib/cjs/iac/shared.js.map +1 -0
  24. package/lib/cjs/iac/types.d.ts +28 -0
  25. package/lib/cjs/iac/types.d.ts.map +1 -0
  26. package/lib/cjs/iac/types.js +26 -0
  27. package/lib/cjs/iac/types.js.map +1 -0
  28. package/lib/cjs/iac/write.d.ts +32 -0
  29. package/lib/cjs/iac/write.d.ts.map +1 -0
  30. package/lib/{iac → cjs/iac}/write.js +40 -17
  31. package/lib/cjs/iac/write.js.map +1 -0
  32. package/lib/cjs/index.d.ts.map +1 -0
  33. package/lib/cjs/index.js.map +1 -0
  34. package/lib/esm/aws/index.js +3 -0
  35. package/lib/esm/aws/index.js.map +1 -0
  36. package/lib/esm/aws/read.js +119 -0
  37. package/lib/esm/aws/read.js.map +1 -0
  38. package/lib/esm/aws/write.js +99 -0
  39. package/lib/esm/aws/write.js.map +1 -0
  40. package/lib/esm/iac/index.js +66 -0
  41. package/lib/esm/iac/index.js.map +1 -0
  42. package/lib/esm/iac/read.js +168 -0
  43. package/lib/esm/iac/read.js.map +1 -0
  44. package/lib/esm/iac/shared.js +32 -0
  45. package/lib/esm/iac/shared.js.map +1 -0
  46. package/lib/esm/iac/types.js +23 -0
  47. package/lib/esm/iac/types.js.map +1 -0
  48. package/lib/esm/iac/write.js +92 -0
  49. package/lib/esm/iac/write.js.map +1 -0
  50. package/lib/esm/index.js +3 -0
  51. package/lib/esm/index.js.map +1 -0
  52. package/package.json +50 -21
  53. package/.gitlab-ci.yml +0 -29
  54. package/lib/aws/index.d.ts.map +0 -1
  55. package/lib/aws/index.js.map +0 -1
  56. package/lib/aws/read.d.ts +0 -35
  57. package/lib/aws/read.d.ts.map +0 -1
  58. package/lib/aws/read.js.map +0 -1
  59. package/lib/aws/write.d.ts +0 -24
  60. package/lib/aws/write.d.ts.map +0 -1
  61. package/lib/aws/write.js.map +0 -1
  62. package/lib/iac/index.d.ts +0 -24
  63. package/lib/iac/index.d.ts.map +0 -1
  64. package/lib/iac/index.js.map +0 -1
  65. package/lib/iac/read.d.ts +0 -48
  66. package/lib/iac/read.d.ts.map +0 -1
  67. package/lib/iac/read.js.map +0 -1
  68. package/lib/iac/shared.d.ts +0 -12
  69. package/lib/iac/shared.d.ts.map +0 -1
  70. package/lib/iac/shared.js.map +0 -1
  71. package/lib/iac/types.d.ts +0 -13
  72. package/lib/iac/types.d.ts.map +0 -1
  73. package/lib/iac/types.js +0 -14
  74. package/lib/iac/types.js.map +0 -1
  75. package/lib/iac/write.d.ts +0 -29
  76. package/lib/iac/write.d.ts.map +0 -1
  77. package/lib/iac/write.js.map +0 -1
  78. package/lib/index.d.ts.map +0 -1
  79. package/lib/index.js.map +0 -1
  80. package/release.config.js +0 -4
  81. /package/lib/{aws → cjs/aws}/index.d.ts +0 -0
  82. /package/lib/{aws → cjs/aws}/index.js +0 -0
  83. /package/lib/{index.d.ts → cjs/index.d.ts} +0 -0
  84. /package/lib/{index.js → cjs/index.js} +0 -0
@@ -0,0 +1,168 @@
1
+ import { Duration } from 'aws-cdk-lib';
2
+ import { core, dynamo, lambda, sns, sqs, stack } from '@othree.io/cdk';
3
+ import { DeduplicationScope, Queue } from 'aws-cdk-lib/aws-sqs';
4
+ import { Topic } from 'aws-cdk-lib/aws-sns';
5
+ import { AttributeType, BillingMode, Table } from 'aws-cdk-lib/aws-dynamodb';
6
+ import { Architecture, Runtime, Tracing } from 'aws-cdk-lib/aws-lambda';
7
+ import { Empty, Optional } from '@othree.io/optional';
8
+ import { SqsEventSource } from 'aws-cdk-lib/aws-lambda-event-sources';
9
+ const defaultLambdaConfiguration = {
10
+ runtime: Runtime.NODEJS_20_X,
11
+ tracing: Tracing.ACTIVE,
12
+ timeout: Duration.seconds(30),
13
+ memorySize: 256,
14
+ architecture: Architecture.ARM_64,
15
+ };
16
+ export const createTopicSubscribersStack = (app, context, input) => {
17
+ const withId = core.id({
18
+ version: input.version,
19
+ input: {
20
+ prefix: Optional(context.project.naming).map(_ => _.prefix).orElse(undefined),
21
+ suffix: context.project.env,
22
+ },
23
+ });
24
+ const defaultConfiguration = stack.withDefaultConfiguration(input.projectMetadata, 'TopicSubscribersStack');
25
+ const topicSubscribersStack = stack.withStack({ defaultConfiguration, app })({
26
+ id: withId(`${input.boundedContext}-TopicSubscribers`),
27
+ });
28
+ const account = core.getStackAccountFromEnv();
29
+ const newQueue = sqs.withQueue({
30
+ defaultConfiguration: { visibilityTimeout: Duration.seconds(30) },
31
+ stack: topicSubscribersStack,
32
+ });
33
+ const redriveDLQ = newQueue({
34
+ id: `${withId(`${input.boundedContext}-Projection-RedriveDLQ`)}.fifo`,
35
+ });
36
+ const dlqName = withId(`${input.boundedContext}-Projection-EventsDLQ`);
37
+ const dlq = newQueue({
38
+ id: dlqName
39
+ });
40
+ const dlqArn = sqs.queueArnFromName({ account })(dlqName);
41
+ const eventQueues = input.topics.map((topic, idx) => {
42
+ const queueName = `${withId(`${input.boundedContext}-Projection-EventsQueue-${idx + 1}`)}.fifo`;
43
+ const queue = newQueue({
44
+ id: queueName,
45
+ }, {
46
+ fifo: true,
47
+ contentBasedDeduplication: true,
48
+ visibilityTimeout: Duration.seconds(30),
49
+ deduplicationScope: DeduplicationScope.MESSAGE_GROUP,
50
+ deadLetterQueue: {
51
+ queue: redriveDLQ,
52
+ maxReceiveCount: 4,
53
+ },
54
+ });
55
+ sns.withSqsSubscription({
56
+ filterPolicy: sns.withChiselFilterPolicy({
57
+ bcs: [input.boundedContext],
58
+ }),
59
+ })({
60
+ queue: queue,
61
+ dlq: redriveDLQ,
62
+ topic: Topic.fromTopicArn(topicSubscribersStack, `Subscriber-Topic${idx}`, topic),
63
+ });
64
+ const queueArn = sqs.queueArnFromName({ account })(queueName);
65
+ return queueArn;
66
+ });
67
+ return {
68
+ stack: topicSubscribersStack,
69
+ eventQueues: eventQueues,
70
+ dlq: dlqArn
71
+ };
72
+ };
73
+ const mapGSIKeyTypeToAttributeType = (type) => {
74
+ const typeMap = {
75
+ 'string': AttributeType.STRING,
76
+ 'number': AttributeType.NUMBER,
77
+ 'binary': AttributeType.BINARY
78
+ };
79
+ return typeMap[type];
80
+ };
81
+ export const createReadPersistenceStack = (app, context, input) => {
82
+ const withId = core.id({
83
+ version: input.version,
84
+ input: {
85
+ prefix: Optional(context.project.naming).map(_ => _.prefix).orElse(undefined),
86
+ suffix: context.project.env,
87
+ },
88
+ });
89
+ const defaultConfiguration = stack.withDefaultConfiguration(input.projectMetadata, 'ProjectionPersistenceStack');
90
+ const readPersistenceStack = stack.withStack({ defaultConfiguration, app })({
91
+ id: withId(`${input.boundedContext}-ProjectionPersistence`),
92
+ });
93
+ const tableName = withId(`${input.boundedContext}-Projection`);
94
+ const projectionTable = dynamo.withTable({
95
+ defaultConfiguration: { billingMode: BillingMode.PAY_PER_REQUEST },
96
+ stack: readPersistenceStack,
97
+ })({
98
+ id: tableName,
99
+ partitionKey: { type: AttributeType.STRING, name: Optional(input.readSide.tablePk).orElse('id') }
100
+ });
101
+ Optional(input.readSide.globalSecondaryIndexes).map(_ => _.forEach(gsi => {
102
+ projectionTable.addGlobalSecondaryIndex({
103
+ indexName: gsi.indexName,
104
+ partitionKey: { type: mapGSIKeyTypeToAttributeType(gsi.primaryKey.type), name: gsi.primaryKey.name },
105
+ sortKey: { type: mapGSIKeyTypeToAttributeType(gsi.sortKey.type), name: gsi.sortKey.name },
106
+ });
107
+ }));
108
+ const account = core.getStackAccountFromEnv();
109
+ return Object.freeze({
110
+ stack: readPersistenceStack,
111
+ projectionTable: `arn:aws:dynamodb:${account.region}:${account.accountId}:table/${tableName}`,
112
+ });
113
+ };
114
+ export const createReadServicesStack = (app, context, input) => {
115
+ const withId = core.id({
116
+ version: input.version,
117
+ input: {
118
+ prefix: Optional(context.project.naming).map(_ => _.prefix).orElse(undefined),
119
+ suffix: context.project.env,
120
+ },
121
+ });
122
+ const defaultConfiguration = stack.withDefaultConfiguration(input.projectMetadata, 'ReadServicesStack');
123
+ const readServicesStack = stack.withStack({ defaultConfiguration, app })({
124
+ id: withId(`${input.boundedContext}-ReadServices`),
125
+ });
126
+ const createLambda = lambda.withLambda({ stack: readServicesStack, aliasName: 'live' });
127
+ const projectionTable = Table.fromTableArn(readServicesStack, 'ProjectionTable', input.projectionTable);
128
+ const dlq = Queue.fromQueueArn(readServicesStack, 'ProjectionDLQ', input.dlq);
129
+ const environment = {
130
+ PROJECTION_TABLE: projectionTable.tableName,
131
+ PROJECTION_DLQ: input.dlq,
132
+ PROJECTION_PK: Optional(input.readSide.tablePk).orElse('id'),
133
+ DELETE_ON_EVENTS: input.readSide.deleteOnEvents.join(',')
134
+ };
135
+ const updateProjectionHandler = createLambda({
136
+ functionName: withId(`${input.boundedContext}-Projection-SQS-UpdateProjection`),
137
+ codePath: '../codebase/read/dist',
138
+ lambdaConfiguration: defaultLambdaConfiguration,
139
+ environment,
140
+ handler: 'entrypoint.sqs.updateProjection',
141
+ });
142
+ projectionTable.grantReadWriteData(updateProjectionHandler);
143
+ input.eventQueues.forEach((queueArn, idx) => {
144
+ const queue = Queue.fromQueueArn(readServicesStack, `QueueSource${idx}`, queueArn);
145
+ updateProjectionHandler.addEventSource(new SqsEventSource(queue, {
146
+ batchSize: 10,
147
+ maxConcurrency: Optional(context.lambda.functions.find(_ => _.name === updateProjectionHandler.functionName))
148
+ .map(_ => Optional(_.reservedConcurrentExecutions))
149
+ .map(_ => Math.floor(_ / input.eventQueues.length))
150
+ .map(_ => _ < 2 ? Empty() : _)
151
+ .orElse(2),
152
+ reportBatchItemFailures: true,
153
+ }));
154
+ });
155
+ dlq.grantSendMessages(updateProjectionHandler);
156
+ const getById = createLambda({
157
+ functionName: withId(`${input.boundedContext}-Projection-Service-GetById`),
158
+ codePath: '../codebase/read/dist',
159
+ lambdaConfiguration: defaultLambdaConfiguration,
160
+ environment,
161
+ handler: 'entrypoint.services.getById',
162
+ });
163
+ projectionTable.grantReadWriteData(getById);
164
+ return {
165
+ stack: readServicesStack
166
+ };
167
+ };
168
+ //# sourceMappingURL=read.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read.js","sourceRoot":"","sources":["../../../src/iac/read.ts"],"names":[],"mappings":"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","sourcesContent":["import {App, Duration, Stack} from 'aws-cdk-lib'\nimport {ChiselServiceContext} from './types'\nimport {core, dynamo, lambda, sns, sqs, stack} from '@othree.io/cdk'\nimport {DeduplicationScope, Queue} from 'aws-cdk-lib/aws-sqs'\nimport {Topic} from 'aws-cdk-lib/aws-sns'\nimport {AttributeType, BillingMode, Table} from 'aws-cdk-lib/aws-dynamodb'\nimport {Architecture, Runtime, Tracing} from 'aws-cdk-lib/aws-lambda'\nimport {Empty, Optional} from '@othree.io/optional'\nimport {SqsEventSource} from 'aws-cdk-lib/aws-lambda-event-sources'\n\nexport type GSIKeyType = 'string' | 'number' | 'binary'\n\nexport type GSIKey = Readonly<{\n name: string\n type: GSIKeyType\n}>\n\nexport type GSIInput = Readonly<{\n indexName: string\n primaryKey: GSIKey\n sortKey: GSIKey\n}>\n\nexport type ReadSideInput = Readonly<{\n codePath: string\n tablePk?: string\n globalSecondaryIndexes?: Array<GSIInput>\n deleteOnEvents: Array<string>\n}>\n\nexport type ReadSide = Readonly<{\n boundedContext: string\n version: string\n readSide: ReadSideInput\n projectMetadata: stack.ProjectMetadata\n}>\n\nexport type QueueSubscribersInput = ReadSide & Readonly<{\n topics: Array<string>\n}>\n\nexport type QueueSubscribersStackOutput = Readonly<{\n stack: Stack\n eventQueues: Array<string>\n dlq: string\n}>\n\nconst defaultLambdaConfiguration: lambda.LambdaConfiguration = {\n runtime: Runtime.NODEJS_20_X,\n tracing: Tracing.ACTIVE,\n timeout: Duration.seconds(30),\n memorySize: 256,\n architecture: Architecture.ARM_64,\n}\n\nexport const createTopicSubscribersStack = (app: App, context: ChiselServiceContext, input: QueueSubscribersInput): QueueSubscribersStackOutput => {\n const withId = core.id({\n version: input.version,\n input: {\n prefix: Optional(context.project.naming).map(_ => _.prefix).orElse(undefined!),\n suffix: context.project.env,\n },\n })\n\n const defaultConfiguration = stack.withDefaultConfiguration(input.projectMetadata, 'TopicSubscribersStack')\n\n const topicSubscribersStack = stack.withStack({ defaultConfiguration, app })({\n id: withId(`${input.boundedContext}-TopicSubscribers`),\n })\n\n const account = core.getStackAccountFromEnv()\n\n const newQueue = sqs.withQueue({\n defaultConfiguration: { visibilityTimeout: Duration.seconds(30) },\n stack: topicSubscribersStack,\n })\n\n const redriveDLQ = newQueue({\n id: `${withId(`${input.boundedContext}-Projection-RedriveDLQ`)}.fifo`,\n })\n\n const dlqName = withId(`${input.boundedContext}-Projection-EventsDLQ`)\n const dlq = newQueue({\n id: dlqName\n })\n const dlqArn = sqs.queueArnFromName({ account })(dlqName)\n\n const eventQueues = input.topics.map((topic, idx) => {\n const queueName = `${withId(`${input.boundedContext}-Projection-EventsQueue-${idx + 1}`)}.fifo`\n const queue = newQueue({\n id: queueName,\n }, {\n fifo: true,\n contentBasedDeduplication: true,\n visibilityTimeout: Duration.seconds(30),\n deduplicationScope: DeduplicationScope.MESSAGE_GROUP,\n deadLetterQueue: {\n queue: redriveDLQ,\n maxReceiveCount: 4,\n },\n })\n\n sns.withSqsSubscription({\n filterPolicy: sns.withChiselFilterPolicy({\n bcs: [input.boundedContext],\n }),\n })({\n queue: queue,\n dlq: redriveDLQ,\n topic: Topic.fromTopicArn(topicSubscribersStack, `Subscriber-Topic${idx}`, topic),\n })\n\n const queueArn = sqs.queueArnFromName({ account })(queueName)\n\n return queueArn\n })\n\n return {\n stack: topicSubscribersStack,\n eventQueues: eventQueues,\n dlq: dlqArn\n }\n}\n\nexport type ReadPersistenceInput = ReadSide\n\nexport type ReadPersistenceStackOutput = Readonly<{\n stack: Stack\n projectionTable: string\n}>\n\nconst mapGSIKeyTypeToAttributeType = (type: GSIKeyType): AttributeType => {\n const typeMap: Record<GSIKeyType, AttributeType> = {\n 'string': AttributeType.STRING,\n 'number': AttributeType.NUMBER,\n 'binary': AttributeType.BINARY\n }\n return typeMap[type]\n}\n\nexport const createReadPersistenceStack = (app: App, context: ChiselServiceContext, input: ReadPersistenceInput): ReadPersistenceStackOutput => {\n const withId = core.id({\n version: input.version,\n input: {\n prefix: Optional(context.project.naming).map(_ => _.prefix).orElse(undefined!),\n suffix: context.project.env,\n },\n })\n\n const defaultConfiguration = stack.withDefaultConfiguration(input.projectMetadata, 'ProjectionPersistenceStack')\n\n const readPersistenceStack = stack.withStack({ defaultConfiguration, app })({\n id: withId(`${input.boundedContext}-ProjectionPersistence`),\n })\n\n const tableName = withId(`${input.boundedContext}-Projection`)\n const projectionTable = dynamo.withTable({\n defaultConfiguration: { billingMode: BillingMode.PAY_PER_REQUEST },\n stack: readPersistenceStack,\n })({\n id: tableName,\n partitionKey: {type: AttributeType.STRING, name: Optional(input.readSide.tablePk).orElse('id')}\n })\n\n Optional(input.readSide.globalSecondaryIndexes).map(_ => _.forEach(gsi => {\n (projectionTable as Table).addGlobalSecondaryIndex({\n indexName: gsi.indexName,\n partitionKey: {type: mapGSIKeyTypeToAttributeType(gsi.primaryKey.type), name: gsi.primaryKey.name},\n sortKey: {type: mapGSIKeyTypeToAttributeType(gsi.sortKey.type), name: gsi.sortKey.name},\n })\n }))\n\n const account = core.getStackAccountFromEnv()\n\n return Object.freeze({\n stack: readPersistenceStack,\n projectionTable: `arn:aws:dynamodb:${account.region}:${account.accountId}:table/${tableName}`,\n })\n}\n\nexport type ReadServicesInput = ReadSide & Readonly<{\n projectionTable: string\n eventQueues: Array<string>\n dlq: string\n}>\n\nexport type ReadServicesStackOutput = Readonly<{\n stack: Stack\n}>\n\nexport const createReadServicesStack = (app: App, context: ChiselServiceContext, input: ReadServicesInput): ReadServicesStackOutput => {\n const withId = core.id({\n version: input.version,\n input: {\n prefix: Optional(context.project.naming).map(_ => _.prefix).orElse(undefined!),\n suffix: context.project.env,\n },\n })\n\n const defaultConfiguration = stack.withDefaultConfiguration(input.projectMetadata, 'ReadServicesStack')\n\n const readServicesStack = stack.withStack({ defaultConfiguration, app })({\n id: withId(`${input.boundedContext}-ReadServices`),\n })\n\n const createLambda = lambda.withLambda({ stack: readServicesStack, aliasName: 'live' })\n\n const projectionTable = Table.fromTableArn(readServicesStack, 'ProjectionTable', input.projectionTable)\n const dlq = Queue.fromQueueArn(readServicesStack, 'ProjectionDLQ', input.dlq)\n\n const environment = {\n PROJECTION_TABLE: projectionTable.tableName,\n PROJECTION_DLQ: input.dlq,\n PROJECTION_PK: Optional(input.readSide.tablePk).orElse('id'),\n DELETE_ON_EVENTS: input.readSide.deleteOnEvents.join(',')\n }\n\n const updateProjectionHandler = createLambda({\n functionName: withId(`${input.boundedContext}-Projection-SQS-UpdateProjection`),\n codePath: '../codebase/read/dist',\n lambdaConfiguration: defaultLambdaConfiguration,\n environment,\n handler: 'entrypoint.sqs.updateProjection',\n })\n projectionTable.grantReadWriteData(updateProjectionHandler)\n input.eventQueues.forEach((queueArn, idx) => {\n const queue = Queue.fromQueueArn(readServicesStack, `QueueSource${idx}`, queueArn)\n\n updateProjectionHandler.addEventSource(new SqsEventSource(queue, {\n batchSize: 10,\n maxConcurrency: Optional(context.lambda.functions.find(_ => _.name === updateProjectionHandler.functionName))\n .map(_ => Optional(_.reservedConcurrentExecutions))\n .map(_ => Math.floor(_ / input.eventQueues.length))\n .map(_ => _ < 2 ? Empty<number>() : _)\n .orElse(2),\n reportBatchItemFailures: true,\n }))\n })\n dlq.grantSendMessages(updateProjectionHandler)\n\n const getById = createLambda({\n functionName: withId(`${input.boundedContext}-Projection-Service-GetById`),\n codePath: '../codebase/read/dist',\n lambdaConfiguration: defaultLambdaConfiguration,\n environment,\n handler: 'entrypoint.services.getById',\n })\n projectionTable.grantReadWriteData(getById)\n\n return {\n stack: readServicesStack\n }\n}\n"]}
@@ -0,0 +1,32 @@
1
+ import { core, sns, stack } from '@othree.io/cdk';
2
+ import { Optional } from '@othree.io/optional';
3
+ export const createTopicsStack = (app, context, input) => {
4
+ const withId = core.id({
5
+ version: input.version,
6
+ input: {
7
+ prefix: Optional(context.project.naming).map(_ => _.prefix).orElse(undefined),
8
+ suffix: context.project.env,
9
+ },
10
+ });
11
+ const defaultConfiguration = stack.withDefaultConfiguration(input.projectMetadata, 'EventBusStack');
12
+ const eventsStack = stack.withStack({ defaultConfiguration, app })({
13
+ id: withId(`${input.boundedContext}-EventBus`),
14
+ });
15
+ const account = core.getStackAccountFromEnv();
16
+ const range = Array.from(Array(context.chisel.numberOfShards).keys());
17
+ const topics = range.map(idx => {
18
+ const topicName = `${withId(`${input.boundedContext}-Topic-${idx + 1}`)}.fifo`;
19
+ sns.withTopic({ stack: eventsStack })({
20
+ id: topicName,
21
+ }, {
22
+ fifo: true,
23
+ contentBasedDeduplication: true,
24
+ });
25
+ return sns.topicArnFromName({ account })(topicName);
26
+ });
27
+ return Object.freeze({
28
+ stack: eventsStack,
29
+ topics: topics,
30
+ });
31
+ };
32
+ //# sourceMappingURL=shared.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../src/iac/shared.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,IAAI,EAAE,GAAG,EAAE,KAAK,EAAC,MAAM,gBAAgB,CAAA;AAC/C,OAAO,EAAC,QAAQ,EAAC,MAAM,qBAAqB,CAAA;AAa5C,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,GAAQ,EAAE,OAA6B,EAAE,KAAuB,EAAqB,EAAE;IACrH,MAAM,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;QACnB,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,KAAK,EAAE;YACH,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,SAAU,CAAC;YAC9E,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG;SAC9B;KACJ,CAAC,CAAA;IAEF,MAAM,oBAAoB,GAAG,KAAK,CAAC,wBAAwB,CAAC,KAAK,CAAC,eAAe,EAAE,eAAe,CAAC,CAAA;IAEnG,MAAM,WAAW,GAAG,KAAK,CAAC,SAAS,CAAC,EAAE,oBAAoB,EAAE,GAAG,EAAE,CAAC,CAAC;QAC/D,EAAE,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC,cAAc,WAAW,CAAC;KACjD,CAAC,CAAA;IAEF,MAAM,OAAO,GAAG,IAAI,CAAC,sBAAsB,EAAE,CAAA;IAC7C,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,IAAI,EAAE,CAAC,CAAA;IAErE,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;QAC3B,MAAM,SAAS,GAAG,GAAG,MAAM,CAAC,GAAG,KAAK,CAAC,cAAc,UAAU,GAAG,GAAG,CAAC,EAAE,CAAC,OAAO,CAAA;QAE9E,GAAG,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;YAClC,EAAE,EAAE,SAAS;SAChB,EAAE;YACC,IAAI,EAAE,IAAI;YACV,yBAAyB,EAAE,IAAI;SAClC,CAAC,CAAA;QAEF,OAAO,GAAG,CAAC,gBAAgB,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,SAAS,CAAC,CAAA;IACvD,CAAC,CAAC,CAAA;IAEF,OAAO,MAAM,CAAC,MAAM,CAAC;QACjB,KAAK,EAAE,WAAW;QAClB,MAAM,EAAE,MAAM;KACjB,CAAC,CAAA;AACN,CAAC,CAAA","sourcesContent":["import {App, Stack} from 'aws-cdk-lib'\nimport {ChiselServiceContext} from './types'\nimport {core, sns, stack} from '@othree.io/cdk'\nimport {Optional} from '@othree.io/optional'\n\nexport type TopicsStackInput = Readonly<{\n boundedContext: string\n version: string\n projectMetadata: stack.ProjectMetadata\n}>\n\nexport type TopicsStackOutput = Readonly<{\n stack: Stack\n topics: Array<string>\n}>\n\nexport const createTopicsStack = (app: App, context: ChiselServiceContext, input: TopicsStackInput): TopicsStackOutput => {\n const withId = core.id({\n version: input.version,\n input: {\n prefix: Optional(context.project.naming).map(_ => _.prefix).orElse(undefined!),\n suffix: context.project.env,\n },\n })\n\n const defaultConfiguration = stack.withDefaultConfiguration(input.projectMetadata, 'EventBusStack')\n\n const eventsStack = stack.withStack({ defaultConfiguration, app })({\n id: withId(`${input.boundedContext}-EventBus`),\n })\n\n const account = core.getStackAccountFromEnv()\n const range = Array.from(Array(context.chisel.numberOfShards).keys())\n\n const topics = range.map(idx => {\n const topicName = `${withId(`${input.boundedContext}-Topic-${idx + 1}`)}.fifo`\n\n sns.withTopic({ stack: eventsStack })({\n id: topicName,\n }, {\n fifo: true,\n contentBasedDeduplication: true,\n })\n\n return sns.topicArnFromName({ account })(topicName)\n })\n\n return Object.freeze({\n stack: eventsStack,\n topics: topics,\n })\n}\n"]}
@@ -0,0 +1,23 @@
1
+ import { z } from 'zod';
2
+ import { NonEmptyString } from '@othree.io/auditor';
3
+ export const ProjectContextConstraints = z.object({
4
+ naming: z.object({
5
+ prefix: z.string().optional(),
6
+ }).optional(),
7
+ env: NonEmptyString,
8
+ });
9
+ export const LambdaContextConstraints = z.object({
10
+ functions: z.array(z.object({
11
+ name: NonEmptyString,
12
+ reservedConcurrentExecutions: z.number().int().min(1).optional(),
13
+ })),
14
+ });
15
+ export const ChiselConstraints = z.object({
16
+ numberOfShards: z.number().int().min(1),
17
+ });
18
+ export const ChiselServiceContextConstraints = z.object({
19
+ project: ProjectContextConstraints,
20
+ lambda: LambdaContextConstraints,
21
+ chisel: ChiselConstraints,
22
+ });
23
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/iac/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,CAAC,EAAU,MAAM,KAAK,CAAA;AAC9B,OAAO,EAAC,cAAc,EAAC,MAAM,oBAAoB,CAAA;AAWjD,MAAM,CAAC,MAAM,yBAAyB,GAA4B,CAAC,CAAC,MAAM,CAAC;IACvE,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACb,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;KAChC,CAAC,CAAC,QAAQ,EAAE;IACb,GAAG,EAAE,cAAc;CACtB,CAAC,CAAA;AAWF,MAAM,CAAC,MAAM,wBAAwB,GAA2B,CAAC,CAAC,MAAM,CAAC;IACrE,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;QACxB,IAAI,EAAE,cAAc;QACpB,4BAA4B,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;KACnE,CAAC,CAAC;CACN,CAAC,CAAA;AAMF,MAAM,CAAC,MAAM,iBAAiB,GAA2B,CAAC,CAAC,MAAM,CAAC;IAC9D,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;CAC1C,CAAC,CAAA;AAQF,MAAM,CAAC,MAAM,+BAA+B,GAAkC,CAAC,CAAC,MAAM,CAAC;IACnF,OAAO,EAAE,yBAAyB;IAClC,MAAM,EAAE,wBAAwB;IAChC,MAAM,EAAE,iBAAiB;CAC5B,CAAC,CAAA","sourcesContent":["import {z, ZodType} from 'zod'\nimport {NonEmptyString} from '@othree.io/auditor'\n\nexport type NamingContext = Readonly<{\n prefix?: string\n}>\n\nexport type ProjectContext = Readonly<{\n naming?: NamingContext\n env: string\n}>\n\nexport const ProjectContextConstraints: ZodType<ProjectContext> = z.object({\n naming: z.object({\n prefix: z.string().optional(),\n }).optional(),\n env: NonEmptyString,\n})\n\nexport type LambdaFunctionContext = Readonly<{\n name: string\n reservedConcurrentExecutions?: number\n}>\n\nexport type LambdaContext = Readonly<{\n functions: Array<LambdaFunctionContext>\n}>\n\nexport const LambdaContextConstraints: ZodType<LambdaContext> = z.object({\n functions: z.array(z.object({\n name: NonEmptyString,\n reservedConcurrentExecutions: z.number().int().min(1).optional(),\n })),\n})\n\nexport type ChiselContext = Readonly<{\n numberOfShards: number\n}>\n\nexport const ChiselConstraints: ZodType<ChiselContext> = z.object({\n numberOfShards: z.number().int().min(1),\n})\n\nexport type ChiselServiceContext = Readonly<{\n project: ProjectContext\n lambda: LambdaContext\n chisel: ChiselContext\n}>\n\nexport const ChiselServiceContextConstraints: ZodType<ChiselServiceContext> = z.object({\n project: ProjectContextConstraints,\n lambda: LambdaContextConstraints,\n chisel: ChiselConstraints,\n})\n"]}
@@ -0,0 +1,92 @@
1
+ import { Duration } from 'aws-cdk-lib';
2
+ import { core, dynamo, lambda, stack } from '@othree.io/cdk';
3
+ import { AttributeType, BillingMode, Table } from 'aws-cdk-lib/aws-dynamodb';
4
+ import { Architecture, Runtime, Tracing } from 'aws-cdk-lib/aws-lambda';
5
+ import { Topic } from 'aws-cdk-lib/aws-sns';
6
+ import { Optional } from '@othree.io/optional';
7
+ export const createWritePersistenceStack = (app, context, input) => {
8
+ const withId = core.id({
9
+ version: input.version,
10
+ input: {
11
+ prefix: Optional(context.project.naming).map(_ => _.prefix).orElse(undefined),
12
+ suffix: context.project.env,
13
+ },
14
+ });
15
+ const defaultConfiguration = stack.withDefaultConfiguration(input.projectMetadata, 'WritePersistenceStack');
16
+ const writePersistenceStack = stack.withStack({ defaultConfiguration, app })({
17
+ id: withId(`${input.boundedContext}-WritePersistence`),
18
+ });
19
+ const tableName = withId(`${input.boundedContext}-Events`);
20
+ dynamo.withTable({
21
+ defaultConfiguration: { billingMode: BillingMode.PAY_PER_REQUEST },
22
+ stack: writePersistenceStack,
23
+ })({
24
+ id: tableName,
25
+ partitionKey: { name: 'contextId', type: AttributeType.STRING },
26
+ sortKey: { name: 'eventId', type: AttributeType.STRING },
27
+ });
28
+ const account = core.getStackAccountFromEnv();
29
+ return Object.freeze({
30
+ stack: writePersistenceStack,
31
+ eventsTable: `arn:aws:dynamodb:${account.region}:${account.accountId}:table/${tableName}`,
32
+ });
33
+ };
34
+ const defaultLambdaConfiguration = {
35
+ runtime: Runtime.NODEJS_20_X,
36
+ tracing: Tracing.ACTIVE,
37
+ timeout: Duration.seconds(30),
38
+ memorySize: 256,
39
+ architecture: Architecture.ARM_64,
40
+ };
41
+ export const createWriteServicesStack = (app, context, input) => {
42
+ const withId = core.id({
43
+ version: input.version,
44
+ input: {
45
+ prefix: Optional(context.project.naming).map(_ => _.prefix).orElse(undefined),
46
+ suffix: context.project.env,
47
+ },
48
+ });
49
+ const defaultConfiguration = stack.withDefaultConfiguration(input.projectMetadata, 'WriteServicesStack');
50
+ const writeServicesStack = stack.withStack({ defaultConfiguration, app })({
51
+ id: withId(`${input.boundedContext}-WriteServices`),
52
+ });
53
+ const createLambda = lambda.withLambda({ stack: writeServicesStack, aliasName: 'live' });
54
+ const eventsTable = Table.fromTableArn(writeServicesStack, 'EventsTable', input.eventsTable);
55
+ const commandHandlerName = withId(`${input.boundedContext}-Service-CommandHandler`);
56
+ const commandHandler = createLambda({
57
+ functionName: commandHandlerName,
58
+ codePath: input.writeSide.codePath,
59
+ handler: 'entrypoint.actor.handleCommand',
60
+ lambdaConfiguration: defaultLambdaConfiguration,
61
+ environment: {
62
+ EVENTS_TABLE: eventsTable.tableName,
63
+ EVENTS_TOPICS: input.topics.join(','),
64
+ BOUNDED_CONTEXT: input.boundedContext,
65
+ },
66
+ });
67
+ eventsTable.grantReadWriteData(commandHandler);
68
+ input.topics.forEach((topic, idx) => {
69
+ Topic.fromTopicArn(writeServicesStack, `CommandHandlerTopic-${idx}`, topic)
70
+ .grantPublish(commandHandler);
71
+ });
72
+ const getStateHandlerName = withId(`${input.boundedContext}-Service-GetState`);
73
+ const getStateHandler = createLambda({
74
+ functionName: getStateHandlerName,
75
+ codePath: '../codebase/write/dist',
76
+ handler: 'entrypoint.actor.getState',
77
+ lambdaConfiguration: defaultLambdaConfiguration,
78
+ environment: {
79
+ BOUNDED_CONTEXT: input.boundedContext,
80
+ EVENTS_TABLE: eventsTable.tableName,
81
+ },
82
+ });
83
+ eventsTable.grantReadWriteData(getStateHandler);
84
+ const account = core.getStackAccountFromEnv();
85
+ const getLambdaArn = lambda.functionArnFromNameAndAlias({ account, aliasName: 'live' });
86
+ return Object.freeze({
87
+ stack: writeServicesStack,
88
+ handleCommandArn: getLambdaArn(commandHandlerName),
89
+ getStateArn: getLambdaArn(getStateHandlerName),
90
+ });
91
+ };
92
+ //# sourceMappingURL=write.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write.js","sourceRoot":"","sources":["../../../src/iac/write.ts"],"names":[],"mappings":"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","sourcesContent":["import {App, Duration, Stack} from 'aws-cdk-lib'\nimport {core, dynamo, lambda, stack} from '@othree.io/cdk'\nimport {AttributeType, BillingMode, Table} from 'aws-cdk-lib/aws-dynamodb'\nimport {Architecture, Runtime, Tracing} from 'aws-cdk-lib/aws-lambda'\nimport {Topic} from 'aws-cdk-lib/aws-sns'\nimport {ChiselServiceContext} from './types'\nimport {Optional} from '@othree.io/optional'\nexport type WriteSideInput = Readonly<{\n codePath: string\n}>\n\nexport type WritePersistenceStackInput = Readonly<{\n boundedContext: string\n version: string\n writeSide: WriteSideInput\n projectMetadata: stack.ProjectMetadata\n}>\n\nexport type WritePersistenceStackOutput = Readonly<{\n stack: Stack\n eventsTable: string\n}>\n\nexport const createWritePersistenceStack = (app: App, context: ChiselServiceContext, input: WritePersistenceStackInput): WritePersistenceStackOutput => {\n const withId = core.id({\n version: input.version,\n input: {\n prefix: Optional(context.project.naming).map(_ => _.prefix).orElse(undefined!),\n suffix: context.project.env,\n },\n })\n\n const defaultConfiguration = stack.withDefaultConfiguration(input.projectMetadata, 'WritePersistenceStack')\n\n const writePersistenceStack = stack.withStack({ defaultConfiguration, app })({\n id: withId(`${input.boundedContext}-WritePersistence`),\n })\n\n const tableName = withId(`${input.boundedContext}-Events`)\n dynamo.withTable({\n defaultConfiguration: { billingMode: BillingMode.PAY_PER_REQUEST },\n stack: writePersistenceStack,\n })({\n id: tableName,\n partitionKey: { name: 'contextId', type: AttributeType.STRING },\n sortKey: { name: 'eventId', type: AttributeType.STRING },\n })\n\n const account = core.getStackAccountFromEnv()\n\n return Object.freeze({\n stack: writePersistenceStack,\n eventsTable: `arn:aws:dynamodb:${account.region}:${account.accountId}:table/${tableName}`,\n })\n}\n\nexport type WriteServicesInput = Readonly<{\n boundedContext: string\n version: string\n writeSide: WriteSideInput\n topics: Array<string>\n eventsTable: string\n projectMetadata: stack.ProjectMetadata\n}>\n\nexport type WriteServicesStackOutput = Readonly<{\n stack: Stack\n handleCommandArn: string\n getStateArn: string\n}>\n\nconst defaultLambdaConfiguration: lambda.LambdaConfiguration = {\n runtime: Runtime.NODEJS_20_X,\n tracing: Tracing.ACTIVE,\n timeout: Duration.seconds(30),\n memorySize: 256,\n architecture: Architecture.ARM_64,\n}\n\nexport const createWriteServicesStack = (app: App, context: ChiselServiceContext, input: WriteServicesInput): WriteServicesStackOutput => {\n const withId = core.id({\n version: input.version,\n input: {\n prefix: Optional(context.project.naming).map(_ => _.prefix).orElse(undefined!),\n suffix: context.project.env,\n },\n })\n\n const defaultConfiguration = stack.withDefaultConfiguration(input.projectMetadata, 'WriteServicesStack')\n\n const writeServicesStack = stack.withStack({ defaultConfiguration, app })({\n id: withId(`${input.boundedContext}-WriteServices`),\n })\n\n const createLambda = lambda.withLambda({ stack: writeServicesStack, aliasName: 'live' })\n\n const eventsTable = Table.fromTableArn(writeServicesStack, 'EventsTable', input.eventsTable)\n\n const commandHandlerName = withId(`${input.boundedContext}-Service-CommandHandler`)\n const commandHandler = createLambda({\n functionName: commandHandlerName,\n codePath: input.writeSide.codePath,\n handler: 'entrypoint.actor.handleCommand',\n lambdaConfiguration: defaultLambdaConfiguration,\n environment: {\n EVENTS_TABLE: eventsTable.tableName,\n EVENTS_TOPICS: input.topics.join(','),\n BOUNDED_CONTEXT: input.boundedContext,\n },\n })\n\n eventsTable.grantReadWriteData(commandHandler)\n input.topics.forEach((topic, idx) => {\n Topic.fromTopicArn(writeServicesStack, `CommandHandlerTopic-${idx}`, topic)\n .grantPublish(commandHandler)\n })\n\n const getStateHandlerName = withId(`${input.boundedContext}-Service-GetState`)\n const getStateHandler = createLambda({\n functionName: getStateHandlerName,\n codePath: '../codebase/write/dist',\n handler: 'entrypoint.actor.getState',\n lambdaConfiguration: defaultLambdaConfiguration,\n environment: {\n BOUNDED_CONTEXT: input.boundedContext,\n EVENTS_TABLE: eventsTable.tableName,\n },\n })\n eventsTable.grantReadWriteData(getStateHandler)\n\n const account = core.getStackAccountFromEnv()\n const getLambdaArn = lambda.functionArnFromNameAndAlias({ account, aliasName: 'live' })\n\n return Object.freeze({\n stack: writeServicesStack,\n handleCommandArn: getLambdaArn(commandHandlerName),\n getStateArn: getLambdaArn(getStateHandlerName),\n })\n}\n"]}
@@ -0,0 +1,3 @@
1
+ export * as aws from './aws';
2
+ export * as iac from './iac';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,OAAO,CAAA;AAC5B,OAAO,KAAK,GAAG,MAAM,OAAO,CAAA","sourcesContent":["export * as aws from './aws'\nexport * as iac from './iac'\n"]}
package/package.json CHANGED
@@ -1,16 +1,29 @@
1
1
  {
2
2
  "name": "@othree.io/chisel-sdk",
3
- "version": "4.0.0",
3
+ "version": "5.0.0",
4
4
  "description": "Utility functions for Chisel",
5
5
  "private": false,
6
6
  "publishConfig": {
7
7
  "access": "public",
8
8
  "registry": "https://registry.npmjs.org/"
9
9
  },
10
- "main": "lib/index.js",
10
+ "main": "lib/cjs/index.js",
11
+ "module": "lib/esm/index.js",
12
+ "types": "lib/cjs/index.d.ts",
13
+ "exports": {
14
+ ".": {
15
+ "types": "./lib/cjs/index.d.ts",
16
+ "import": "./lib/esm/index.js",
17
+ "require": "./lib/cjs/index.js"
18
+ }
19
+ },
20
+ "files": [
21
+ "lib"
22
+ ],
11
23
  "scripts": {
12
- "test": "jest --passWithNoTests",
13
- "build": "tsc"
24
+ "test": "vitest run --coverage",
25
+ "build": "tsc && tsc -p tsconfig.esm.json",
26
+ "semantic-release": "semantic-release"
14
27
  },
15
28
  "repository": {
16
29
  "type": "git",
@@ -29,25 +42,41 @@
29
42
  },
30
43
  "homepage": "https://gitlab.com/othree.oss/chisel-sdk#readme",
31
44
  "peerDependencies": {
32
- "@othree.io/auditor": "^2.0.0",
33
- "@othree.io/awsome": "^2.0.0",
34
- "@othree.io/cdk": "^4.0.0",
35
- "@othree.io/chisel": "^5.0.0",
36
- "@othree.io/chisel-aws": "^5.1.0",
37
- "@othree.io/excuses": "^1.0.0",
38
- "@othree.io/journal": "^1.0.0",
39
- "@othree.io/projection-utils": "^1.0.0",
40
- "@othree.io/stethoscope": "^1.0.0",
41
- "aws-cdk-lib": "^2.221.0",
45
+ "@othree.io/auditor": "^5.0.0",
46
+ "@othree.io/awsome": "^5.0.0",
47
+ "@othree.io/cdk": "^6.0.0",
48
+ "@othree.io/chisel": "^7.0.0",
49
+ "@othree.io/chisel-aws": "^7.0.0",
50
+ "@othree.io/excuses": "^2.0.0",
51
+ "@othree.io/journal": "^3.0.0",
52
+ "@othree.io/stethoscope": "^5.0.0",
53
+ "aws-cdk-lib": "^2.239.0",
42
54
  "aws-lambda": "^1.0.7",
43
- "aws-xray-sdk-core": "^3.10.3",
44
- "uuid": "^11.1.0"
55
+ "aws-xray-sdk-core": "^3.12.0",
56
+ "uuid": "^13.0.0"
45
57
  },
46
58
  "devDependencies": {
47
- "@types/aws-lambda": "^8.10.157",
48
- "@types/jest": "^30.0.0",
49
- "jest": "^30.2.0",
50
- "ts-jest": "^29.4.5",
51
- "typescript": "^5.9.3"
59
+ "@othree.io/auditor": "^5.0.0",
60
+ "@othree.io/awsome": "^5.0.0",
61
+ "@othree.io/cdk": "^6.0.0",
62
+ "@othree.io/chisel": "^7.0.0",
63
+ "@othree.io/chisel-aws": "^7.0.0",
64
+ "@othree.io/excuses": "^2.0.0",
65
+ "@othree.io/journal": "^3.0.0",
66
+ "@othree.io/stethoscope": "^5.0.0",
67
+ "aws-cdk-lib": "^2.239.0",
68
+ "aws-lambda": "^1.0.7",
69
+ "aws-xray-sdk-core": "^3.12.0",
70
+ "uuid": "^13.0.0",
71
+ "@aws-sdk/client-dynamodb": "^3.788.0",
72
+ "@aws-sdk/client-sns": "^3.787.0",
73
+ "@aws-sdk/client-sqs": "^3.787.0",
74
+ "@othree.io/cerillo": "^3.0.0",
75
+ "@othree.io/optional": "^3.0.0",
76
+ "@types/aws-lambda": "^8.10.160",
77
+ "zod": "^4.1.12",
78
+ "@vitest/coverage-v8": "^4.0.18",
79
+ "typescript": "^5.9.3",
80
+ "vitest": "^4.0.18"
52
81
  }
53
82
  }
package/.gitlab-ci.yml DELETED
@@ -1,29 +0,0 @@
1
- image: node:22-alpine
2
-
3
- cache:
4
- key: ${CI_PIPELINE_ID}
5
- paths:
6
- - node_modules/
7
- - lib/
8
-
9
- build:
10
- stage: build
11
- script:
12
- - npm install && npm run build
13
-
14
- test:
15
- stage: test
16
- script:
17
- - npm test
18
-
19
- deploy:
20
- image: node:22
21
- stage: deploy
22
- variables:
23
- NPM_CONFIG_USERCONFIG: '$CI_PROJECT_DIR/.npmrc'
24
- script:
25
- - cat $NPM > .npmrc
26
- - npx semantic-release
27
- only:
28
- refs:
29
- - main
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/aws/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAA;AACtB,cAAc,SAAS,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/aws/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,yCAAsB;AACtB,0CAAuB"}
package/lib/aws/read.d.ts DELETED
@@ -1,35 +0,0 @@
1
- import { Keys } from '@othree.io/awsome/lib/dynamo';
2
- import { Optional } from '@othree.io/optional';
3
- import { ChiselEvent, TriggeredEvent } from '@othree.io/chisel';
4
- import { SQSRecord } from 'aws-lambda';
5
- export interface ProjectionConfiguration {
6
- readonly projectionTable: string;
7
- readonly projectionDLQ: string;
8
- readonly projectionPk: string;
9
- readonly deleteOnEvents: Array<string>;
10
- }
11
- type CreateProjectionInput = {
12
- readonly boundedContext: string;
13
- readonly getConfiguration?: () => ProjectionConfiguration;
14
- };
15
- type EventState<AggregateRoot, EventType extends ChiselEvent> = Readonly<{
16
- state: AggregateRoot;
17
- event: TriggeredEvent<EventType>;
18
- }>;
19
- export declare const getProcessInput: <AggregateRoot, EventType extends ChiselEvent>(input: SQSRecord) => Promise<Optional<EventState<AggregateRoot, EventType>>>;
20
- export declare const processEvent: <AggregateRoot, EventType extends ChiselEvent>(configuration: ProjectionConfiguration) => (deleteBy: (keys: Keys) => Promise<Optional<boolean>>) => (upsert: (entity: AggregateRoot) => Promise<Optional<AggregateRoot>>) => (eventState: EventState<AggregateRoot, EventType>) => Promise<Optional<AggregateRoot>>;
21
- export declare const getProjectionById: (boundedContext: string, configuration: ProjectionConfiguration) => <AggregateRoot>(getBy: (keys: Keys) => Promise<Optional<Array<AggregateRoot>>>) => (input: GetByIdQuery) => Promise<Optional<AggregateRoot>>;
22
- export interface GetByIdQuery {
23
- readonly id: string;
24
- }
25
- export declare const getConfiguration: () => ProjectionConfiguration;
26
- export declare const getProjectionServices: <AggregateRoot, EventType extends ChiselEvent>(input: CreateProjectionInput) => {
27
- sqs: {
28
- updateProjection: (...args: import("aws-lambda").SQSEvent[]) => Promise<import("aws-lambda").SQSBatchResponse>;
29
- };
30
- services: {
31
- getById: (...args: import("@othree.io/projection-utils").Query<GetByIdQuery>[]) => Promise<AggregateRoot>;
32
- };
33
- };
34
- export {};
35
- //# sourceMappingURL=read.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../../src/aws/read.ts"],"names":[],"mappings":"AAGA,OAAO,EAAQ,IAAI,EAA0B,MAAM,8BAA8B,CAAA;AAEjF,OAAO,EAAC,QAAQ,EAAW,MAAM,qBAAqB,CAAA;AACtD,OAAO,EAAC,WAAW,EAAE,cAAc,EAAC,MAAM,mBAAmB,CAAA;AAG7D,OAAO,EAAC,SAAS,EAAC,MAAM,YAAY,CAAA;AAGpC,MAAM,WAAW,uBAAuB;IACpC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAA;IAChC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,cAAc,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;CACzC;AAED,KAAK,qBAAqB,GAAG;IACzB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,uBAAuB,CAAA;CAC5D,CAAA;AASD,KAAK,UAAU,CAAC,aAAa,EAAE,SAAS,SAAS,WAAW,IAAI,QAAQ,CAAC;IACrE,KAAK,EAAE,aAAa,CAAC;IACrB,KAAK,EAAE,cAAc,CAAC,SAAS,CAAC,CAAA;CACnC,CAAC,CAAA;AAEF,eAAO,MAAM,eAAe,GAAU,aAAa,EAAE,SAAS,SAAS,WAAW,EAAE,OAAO,SAAS,KAAG,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC,CAW5J,CAAA;AAED,eAAO,MAAM,YAAY,GAAI,aAAa,EAAE,SAAS,SAAS,WAAW,EAAE,eAAe,uBAAuB,MAC5G,UAAU,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,MAChD,QAAQ,CAAC,MAAM,EAAE,aAAa,KAAK,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,MAC7D,YAAY,UAAU,CAAC,aAAa,EAAE,SAAS,CAAC,qCAQtD,CAAA;AAET,eAAO,MAAM,iBAAiB,GAAI,gBAAgB,MAAM,EAAE,eAAe,uBAAuB,MAC3F,aAAa,EAAE,OAAO,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,MACnE,OAAO,YAAY,KAAG,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAU3D,CAAA;AAET,MAAM,WAAW,YAAY;IACzB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CACtB;AAED,eAAO,MAAM,gBAAgB,QAAO,uBASnC,CAAA;AAED,eAAO,MAAM,qBAAqB,GAAI,aAAa,EAAE,SAAS,SAAS,WAAW,EAAE,OAAO,qBAAqB;;;;;;;CAmD/G,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"read.js","sourceRoot":"","sources":["../../src/aws/read.ts"],"names":[],"mappings":"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"}
@@ -1,24 +0,0 @@
1
- import { LambdaCommand } from '@othree.io/chisel-aws/lib/lambda-command-handler';
2
- import { ChiselEvent, CommandResult, EventSourceConfiguration } from '@othree.io/chisel';
3
- import { lambda } from '@othree.io/awsome';
4
- import { Optional } from '@othree.io/optional';
5
- import { ChiselDynamoConfiguration, ChiselShardedSnsConfiguration } from '@othree.io/chisel-aws';
6
- import { Reduce } from '@othree.io/chisel/lib/event-source';
7
- import { HandleCommand } from '@othree.io/chisel/lib/actor';
8
- type GetStateQuery = {
9
- readonly contextId: string;
10
- };
11
- export type LambdaActor<AggregateRoot> = {
12
- readonly handleCommand: (event: LambdaCommand) => Promise<CommandResult<AggregateRoot>>;
13
- readonly getState: (event: lambda.Query<GetStateQuery>) => Promise<AggregateRoot>;
14
- };
15
- type CreateLambdaActorInput<AggregateRoot, Event extends ChiselEvent> = {
16
- readonly boundedContext: string;
17
- readonly getInitialState: (contextId: Optional<string>) => Promise<Optional<AggregateRoot>>;
18
- readonly handleCommand: HandleCommand<AggregateRoot>;
19
- readonly reduceEvent: Reduce<AggregateRoot, Event>;
20
- readonly getConfiguration?: () => ChiselDynamoConfiguration & ChiselShardedSnsConfiguration<AggregateRoot> & EventSourceConfiguration<AggregateRoot>;
21
- };
22
- export declare const createActor: <AggregateRoot, Event extends ChiselEvent>(input: CreateLambdaActorInput<AggregateRoot, Event>) => LambdaActor<AggregateRoot>;
23
- export {};
24
- //# sourceMappingURL=write.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"write.d.ts","sourceRoot":"","sources":["../../src/aws/write.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAC,MAAM,kDAAkD,CAAA;AAC9E,OAAO,EAAQ,WAAW,EAAE,aAAa,EAAe,wBAAwB,EAAC,MAAM,mBAAmB,CAAA;AAC1G,OAAO,EAAC,MAAM,EAAC,MAAM,mBAAmB,CAAA;AAExC,OAAO,EAAC,QAAQ,EAAC,MAAM,qBAAqB,CAAA;AAC5C,OAAO,EAGH,yBAAyB,EACzB,6BAA6B,EAEhC,MAAM,uBAAuB,CAAA;AAQ9B,OAAO,EAAY,MAAM,EAAC,MAAM,oCAAoC,CAAA;AAEpE,OAAO,EAAC,aAAa,EAAC,MAAM,6BAA6B,CAAA;AAEzD,KAAK,aAAa,GAAG;IACjB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAC7B,CAAA;AAED,MAAM,MAAM,WAAW,CAAC,aAAa,IAAI;IACrC,QAAQ,CAAC,aAAa,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,OAAO,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC,CAAA;IACvF,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,KAAK,OAAO,CAAC,aAAa,CAAC,CAAA;CACpF,CAAA;AAkCD,KAAK,sBAAsB,CAAC,aAAa,EAAE,KAAK,SAAS,WAAW,IAAI;IACpE,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B,QAAQ,CAAC,eAAe,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,KAAK,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAA;IAC3F,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC,aAAa,CAAC,CAAA;IACpD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,aAAa,EAAE,KAAK,CAAC,CAAA;IAClD,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,yBAAyB,GAAG,6BAA6B,CAAC,aAAa,CAAC,GAAG,wBAAwB,CAAC,aAAa,CAAC,CAAA;CACvJ,CAAA;AAQD,eAAO,MAAM,WAAW,GAAI,aAAa,EAAE,KAAK,SAAS,WAAW,EAAE,OAAO,sBAAsB,CAAC,aAAa,EAAE,KAAK,CAAC,KAAG,WAAW,CAAC,aAAa,CAsCpJ,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"write.js","sourceRoot":"","sources":["../../src/aws/write.ts"],"names":[],"mappings":"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"}