@mettlecast/domain-cdk-packer 0.2.1 → 0.2.4
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.
|
@@ -2,6 +2,8 @@ import * as cdk from 'aws-cdk-lib';
|
|
|
2
2
|
import * as lambda from 'aws-cdk-lib/aws-lambda';
|
|
3
3
|
import * as nodejs from 'aws-cdk-lib/aws-lambda-nodejs';
|
|
4
4
|
import { Construct } from 'constructs';
|
|
5
|
+
import { createRequire } from 'module';
|
|
6
|
+
const require = createRequire(import.meta.url);
|
|
5
7
|
export class HealthConstruct extends Construct {
|
|
6
8
|
healthFn;
|
|
7
9
|
readyFn;
|
|
@@ -14,6 +14,8 @@ export interface HandlerEntry {
|
|
|
14
14
|
export interface GroupedLambdaProps {
|
|
15
15
|
/** Domain ID this Lambda belongs to. */
|
|
16
16
|
domainId: string;
|
|
17
|
+
/** Absolute path to the domain root directory. Required for dedicated mode. */
|
|
18
|
+
domainRoot?: string;
|
|
17
19
|
/** The primitive type being handled (api, subscriber, etc.). */
|
|
18
20
|
primitiveType: PrimitiveType;
|
|
19
21
|
/** All handler entries for this primitive type within the domain. */
|
|
@@ -36,8 +38,8 @@ export interface GroupedLambdaProps {
|
|
|
36
38
|
/**
|
|
37
39
|
* Creates either a single grouped Lambda (default) or per-handler dedicated Lambdas.
|
|
38
40
|
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
41
|
+
* Dedicated mode uses NodejsFunction (esbuild on-the-fly) with auto-generated
|
|
42
|
+
* adapter wrappers — no pre-compiled dist/domains/ assets needed.
|
|
43
|
+
* Grouped mode retains Code.fromAsset for backward compatibility.
|
|
42
44
|
*/
|
|
43
45
|
export declare function createGroupedLambdas(scope: Construct, props: GroupedLambdaProps): lambda.Function[];
|
|
@@ -1,26 +1,85 @@
|
|
|
1
1
|
import * as lambda from 'aws-cdk-lib/aws-lambda';
|
|
2
|
+
import * as lambdaNode from 'aws-cdk-lib/aws-lambda-nodejs';
|
|
2
3
|
import * as logs from 'aws-cdk-lib/aws-logs';
|
|
3
4
|
import * as cdk from 'aws-cdk-lib';
|
|
5
|
+
import { writeFileSync, mkdirSync } from 'fs';
|
|
6
|
+
import { join } from 'path';
|
|
7
|
+
import { tmpdir } from 'os';
|
|
8
|
+
function camelCase(str) {
|
|
9
|
+
return str.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
|
|
10
|
+
}
|
|
11
|
+
function toPascalCase(str) {
|
|
12
|
+
return str.charAt(0).toUpperCase() + camelCase(str).slice(1);
|
|
13
|
+
}
|
|
14
|
+
function generateDedicatedEntry(domainRoot, entry, primitiveType) {
|
|
15
|
+
const exportName = camelCase(entry.id);
|
|
16
|
+
if (primitiveType === 'schedule') {
|
|
17
|
+
return [
|
|
18
|
+
`import { hydrateCtx } from '@mettlecast/domain-runtime';`,
|
|
19
|
+
`import { ${exportName} } from '${domainRoot}/${entry.handlerFile}';`,
|
|
20
|
+
``,
|
|
21
|
+
`export const handler = async (event: any) => {`,
|
|
22
|
+
` const ctx = await hydrateCtx(event, {`,
|
|
23
|
+
` databaseUrl: process.env.DATABASE_URL,`,
|
|
24
|
+
` eventBusName: process.env.EVENT_BUS_NAME,`,
|
|
25
|
+
` });`,
|
|
26
|
+
` try { await ${exportName}.handler(ctx); } finally { try { await ctx.db.release(); } catch {} }`,
|
|
27
|
+
`};`,
|
|
28
|
+
].join('\n');
|
|
29
|
+
}
|
|
30
|
+
const adapterMap = {
|
|
31
|
+
api: 'createApiLambdaHandler',
|
|
32
|
+
subscriber: 'createSubscriberLambdaHandler',
|
|
33
|
+
job: 'createJobLambdaHandler',
|
|
34
|
+
webhook: 'createWebhookLambdaHandler',
|
|
35
|
+
action: 'createActionLambdaHandler',
|
|
36
|
+
};
|
|
37
|
+
const adapter = adapterMap[primitiveType] ?? 'createApiLambdaHandler';
|
|
38
|
+
return [
|
|
39
|
+
`import { ${adapter} } from '@mettlecast/domain-runtime';`,
|
|
40
|
+
`import { ${exportName} } from '${domainRoot}/${entry.handlerFile}';`,
|
|
41
|
+
'',
|
|
42
|
+
`export const handler = ${adapter}(${exportName});`,
|
|
43
|
+
].join('\n');
|
|
44
|
+
}
|
|
45
|
+
function writeTempEntry(content) {
|
|
46
|
+
const dir = join(tmpdir(), 'tib-domain-entries', `${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
47
|
+
mkdirSync(dir, { recursive: true });
|
|
48
|
+
const filePath = join(dir, 'entry.ts');
|
|
49
|
+
writeFileSync(filePath, content, 'utf8');
|
|
50
|
+
return filePath;
|
|
51
|
+
}
|
|
52
|
+
const adapterCache = new Map();
|
|
4
53
|
/**
|
|
5
54
|
* Creates either a single grouped Lambda (default) or per-handler dedicated Lambdas.
|
|
6
55
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
56
|
+
* Dedicated mode uses NodejsFunction (esbuild on-the-fly) with auto-generated
|
|
57
|
+
* adapter wrappers — no pre-compiled dist/domains/ assets needed.
|
|
58
|
+
* Grouped mode retains Code.fromAsset for backward compatibility.
|
|
10
59
|
*/
|
|
11
60
|
export function createGroupedLambdas(scope, props) {
|
|
12
61
|
const vpcConfig = props.vpc ? { vpc: props.vpc, securityGroups: props.securityGroups } : {};
|
|
13
62
|
const logRetention = toLogRetention(props.logRetentionDays ?? 30);
|
|
14
63
|
const powertoolsLayerArn = `arn:aws:lambda:${cdk.Stack.of(scope).region}:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:26`;
|
|
15
64
|
if (props.dedicated) {
|
|
16
|
-
|
|
65
|
+
if (!props.domainRoot)
|
|
66
|
+
throw new Error('domainRoot is required when dedicated=true');
|
|
67
|
+
const domainRoot = props.domainRoot;
|
|
68
|
+
const fns = props.handlerEntries.map(entry => {
|
|
17
69
|
const powertoolsLayer = lambda.LayerVersion.fromLayerVersionArn(scope, `PowertoolsLayer${props.domainId}-${props.primitiveType}-${entry.id}`, powertoolsLayerArn);
|
|
18
|
-
|
|
70
|
+
const entryContent = generateDedicatedEntry(domainRoot, entry, props.primitiveType);
|
|
71
|
+
const entryPath = writeTempEntry(entryContent);
|
|
72
|
+
return new lambdaNode.NodejsFunction(scope, `${props.domainId}-${props.primitiveType}-${entry.id}`, {
|
|
19
73
|
runtime: lambda.Runtime.NODEJS_22_X,
|
|
20
74
|
architecture: lambda.Architecture.ARM_64,
|
|
21
|
-
|
|
22
|
-
|
|
75
|
+
entry: entryPath,
|
|
76
|
+
handler: 'handler',
|
|
23
77
|
layers: [powertoolsLayer],
|
|
78
|
+
bundling: {
|
|
79
|
+
minify: true,
|
|
80
|
+
sourceMap: true,
|
|
81
|
+
externalModules: ['@aws-sdk/*'],
|
|
82
|
+
},
|
|
24
83
|
environment: {
|
|
25
84
|
...props.environment,
|
|
26
85
|
POWERTOOLS_SERVICE_NAME: `${props.domainId}-${props.primitiveType}`,
|
|
@@ -35,6 +94,7 @@ export function createGroupedLambdas(scope, props) {
|
|
|
35
94
|
...vpcConfig,
|
|
36
95
|
});
|
|
37
96
|
});
|
|
97
|
+
return fns;
|
|
38
98
|
}
|
|
39
99
|
// Single grouped Lambda — all handlers for this primitive type bundled together
|
|
40
100
|
const powertoolsLayer = lambda.LayerVersion.fromLayerVersionArn(scope, `PowertoolsLayer${props.domainId}-${props.primitiveType}`, powertoolsLayerArn);
|