puls-dev 0.1.0 → 0.1.8

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 (50) hide show
  1. package/README.md +10 -8
  2. package/dist/core/checker.d.ts +1 -1
  3. package/dist/core/checker.js +88 -56
  4. package/dist/core/config.test.d.ts +1 -0
  5. package/dist/core/config.test.js +21 -0
  6. package/dist/core/decorators.js +8 -2
  7. package/dist/core/output.test.d.ts +1 -0
  8. package/dist/core/output.test.js +18 -0
  9. package/dist/core/resource.js +2 -2
  10. package/dist/core/stack.d.ts +1 -1
  11. package/dist/core/stack.js +2 -2
  12. package/dist/providers/aws/acm.d.ts +1 -1
  13. package/dist/providers/aws/acm.js +27 -23
  14. package/dist/providers/aws/api.d.ts +14 -14
  15. package/dist/providers/aws/api.js +21 -21
  16. package/dist/providers/aws/apigateway.d.ts +2 -2
  17. package/dist/providers/aws/apigateway.js +33 -29
  18. package/dist/providers/aws/cloudfront.d.ts +3 -3
  19. package/dist/providers/aws/cloudfront.js +49 -34
  20. package/dist/providers/aws/fargate.d.ts +2 -2
  21. package/dist/providers/aws/fargate.js +99 -52
  22. package/dist/providers/aws/lambda.d.ts +2 -2
  23. package/dist/providers/aws/lambda.js +63 -32
  24. package/dist/providers/aws/rds.d.ts +1 -1
  25. package/dist/providers/aws/rds.js +77 -39
  26. package/dist/providers/aws/route53.d.ts +5 -5
  27. package/dist/providers/aws/route53.js +42 -35
  28. package/dist/providers/aws/s3.d.ts +2 -2
  29. package/dist/providers/aws/s3.js +40 -33
  30. package/dist/providers/aws/secrets.js +15 -7
  31. package/dist/providers/aws/sqs.d.ts +1 -1
  32. package/dist/providers/aws/sqs.js +47 -23
  33. package/dist/providers/do/domain.d.ts +4 -4
  34. package/dist/providers/do/domain.js +15 -11
  35. package/dist/providers/firebase/auth.d.ts +1 -1
  36. package/dist/providers/firebase/auth.js +65 -33
  37. package/dist/providers/firebase/firestore.d.ts +2 -2
  38. package/dist/providers/firebase/firestore.js +45 -28
  39. package/dist/providers/firebase/functions.d.ts +1 -1
  40. package/dist/providers/firebase/functions.js +75 -42
  41. package/dist/providers/firebase/hosting.d.ts +1 -1
  42. package/dist/providers/firebase/hosting.js +92 -52
  43. package/dist/providers/firebase/remoteconfig.d.ts +1 -1
  44. package/dist/providers/firebase/remoteconfig.js +42 -33
  45. package/dist/providers/firebase/storage.d.ts +1 -1
  46. package/dist/providers/firebase/storage.js +38 -24
  47. package/dist/providers/proxmox/vm.d.ts +1 -1
  48. package/dist/providers/proxmox/vm.js +43 -24
  49. package/dist/types/aws.js +1 -1
  50. package/package.json +3 -2
@@ -1,14 +1,20 @@
1
- import { DescribeClustersCommand, CreateClusterCommand, DescribeServicesCommand, CreateServiceCommand, UpdateServiceCommand, DeleteServiceCommand, RegisterTaskDefinitionCommand, NetworkMode, LaunchType, SchedulingStrategy, } from '@aws-sdk/client-ecs';
2
- import { DescribeVpcsCommand, DescribeSubnetsCommand, DescribeSecurityGroupsCommand, CreateSecurityGroupCommand, AuthorizeSecurityGroupIngressCommand, } from '@aws-sdk/client-ec2';
3
- import { GetRoleCommand, CreateRoleCommand, AttachRolePolicyCommand, } from '@aws-sdk/client-iam';
4
- import { DescribeLogGroupsCommand, CreateLogGroupCommand, } from '@aws-sdk/client-cloudwatch-logs';
5
- import { BaseBuilder } from '../../core/resource.js';
6
- import { getECSClient, getEC2Client, getIAMClient, getCWLogsClient } from './api.js';
7
- import { resolveEnvVars } from './secrets.js';
8
- import { Config } from '../../core/config.js';
1
+ import { DescribeClustersCommand, CreateClusterCommand, DescribeServicesCommand, CreateServiceCommand, UpdateServiceCommand, DeleteServiceCommand, RegisterTaskDefinitionCommand, NetworkMode, LaunchType, SchedulingStrategy, } from "@aws-sdk/client-ecs";
2
+ import { DescribeVpcsCommand, DescribeSubnetsCommand, DescribeSecurityGroupsCommand, CreateSecurityGroupCommand, AuthorizeSecurityGroupIngressCommand, } from "@aws-sdk/client-ec2";
3
+ import { GetRoleCommand, CreateRoleCommand, AttachRolePolicyCommand, } from "@aws-sdk/client-iam";
4
+ import { DescribeLogGroupsCommand, CreateLogGroupCommand, } from "@aws-sdk/client-cloudwatch-logs";
5
+ import { BaseBuilder } from "../../core/resource.js";
6
+ import { getECSClient, getEC2Client, getIAMClient, getCWLogsClient, } from "./api.js";
7
+ import { resolveEnvVars } from "./secrets.js";
8
+ import { Config } from "../../core/config.js";
9
9
  const ECS_ASSUME_ROLE_POLICY = JSON.stringify({
10
- Version: '2012-10-17',
11
- Statement: [{ Effect: 'Allow', Principal: { Service: 'ecs-tasks.amazonaws.com' }, Action: 'sts:AssumeRole' }],
10
+ Version: "2012-10-17",
11
+ Statement: [
12
+ {
13
+ Effect: "Allow",
14
+ Principal: { Service: "ecs-tasks.amazonaws.com" },
15
+ Action: "sts:AssumeRole",
16
+ },
17
+ ],
12
18
  });
13
19
  export class FargateBuilder extends BaseBuilder {
14
20
  _image;
@@ -17,7 +23,7 @@ export class FargateBuilder extends BaseBuilder {
17
23
  _port;
18
24
  _replicas = 1;
19
25
  _env = {};
20
- _clusterName = 'puls';
26
+ _clusterName = "puls";
21
27
  _subnetIds;
22
28
  _securityGroupIds;
23
29
  resolvedArn = null;
@@ -25,33 +31,61 @@ export class FargateBuilder extends BaseBuilder {
25
31
  super(name);
26
32
  this.discoveryPromise = this.discoverService(name);
27
33
  }
28
- image(img) { this._image = img; return this; }
29
- cpu(units) { this._cpu = units; return this; }
30
- memory(mb) { this._memory = mb; return this; }
31
- port(p) { this._port = p; return this; }
32
- replicas(n) { this._replicas = n; return this; }
33
- cluster(name) { this._clusterName = name; return this; }
34
- subnets(ids) { this._subnetIds = ids; return this; }
35
- securityGroups(ids) { this._securityGroupIds = ids; return this; }
36
- env(vars) { this._env = { ...this._env, ...vars }; return this; }
34
+ image(img) {
35
+ this._image = img;
36
+ return this;
37
+ }
38
+ cpu(units) {
39
+ this._cpu = units;
40
+ return this;
41
+ }
42
+ memory(mb) {
43
+ this._memory = mb;
44
+ return this;
45
+ }
46
+ port(p) {
47
+ this._port = p;
48
+ return this;
49
+ }
50
+ replicas(n) {
51
+ this._replicas = n;
52
+ return this;
53
+ }
54
+ cluster(name) {
55
+ this._clusterName = name;
56
+ return this;
57
+ }
58
+ subnets(ids) {
59
+ this._subnetIds = ids;
60
+ return this;
61
+ }
62
+ securityGroups(ids) {
63
+ this._securityGroupIds = ids;
64
+ return this;
65
+ }
66
+ env(vars) {
67
+ this._env = { ...this._env, ...vars };
68
+ return this;
69
+ }
37
70
  async discoverService(name) {
38
71
  try {
39
72
  const ecs = getECSClient();
40
73
  const clusterDesc = await ecs.send(new DescribeClustersCommand({ clusters: [this._clusterName] }));
41
- const cluster = clusterDesc.clusters?.find(c => c.status === 'ACTIVE');
74
+ const cluster = clusterDesc.clusters?.find((c) => c.status === "ACTIVE");
42
75
  if (!cluster)
43
76
  return null;
44
77
  const result = await ecs.send(new DescribeServicesCommand({
45
78
  cluster: this._clusterName,
46
79
  services: [name],
47
80
  }));
48
- const svc = result.services?.find(s => s.status !== 'INACTIVE');
81
+ const svc = result.services?.find((s) => s.status !== "INACTIVE");
49
82
  if (svc)
50
83
  this.resolvedArn = svc.serviceArn ?? null;
51
84
  return svc ?? null;
52
85
  }
53
86
  catch (e) {
54
- if (e.name === 'ClusterNotFoundException' || e.name === 'CredentialsProviderError')
87
+ if (e.name === "ClusterNotFoundException" ||
88
+ e.name === "CredentialsProviderError")
55
89
  return null;
56
90
  throw e;
57
91
  }
@@ -59,7 +93,7 @@ export class FargateBuilder extends BaseBuilder {
59
93
  async ensureCluster() {
60
94
  const ecs = getECSClient();
61
95
  const desc = await ecs.send(new DescribeClustersCommand({ clusters: [this._clusterName] }));
62
- const existing = desc.clusters?.find(c => c.status === 'ACTIVE');
96
+ const existing = desc.clusters?.find((c) => c.status === "ACTIVE");
63
97
  if (existing)
64
98
  return existing.clusterArn;
65
99
  const created = await ecs.send(new CreateClusterCommand({ clusterName: this._clusterName }));
@@ -74,7 +108,7 @@ export class FargateBuilder extends BaseBuilder {
74
108
  return existing.Role.Arn;
75
109
  }
76
110
  catch (e) {
77
- if (e.name !== 'NoSuchEntityException')
111
+ if (e.name !== "NoSuchEntityException")
78
112
  throw e;
79
113
  }
80
114
  const created = await iam.send(new CreateRoleCommand({
@@ -84,7 +118,7 @@ export class FargateBuilder extends BaseBuilder {
84
118
  }));
85
119
  await iam.send(new AttachRolePolicyCommand({
86
120
  RoleName: roleName,
87
- PolicyArn: 'arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy',
121
+ PolicyArn: "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy",
88
122
  }));
89
123
  console.log(` ✅ Created execution role: ${roleName}`);
90
124
  return created.Role.Arn;
@@ -93,7 +127,7 @@ export class FargateBuilder extends BaseBuilder {
93
127
  const logGroupName = `/puls/${this.name}`;
94
128
  const cw = getCWLogsClient();
95
129
  const existing = await cw.send(new DescribeLogGroupsCommand({ logGroupNamePrefix: logGroupName }));
96
- if (existing.logGroups?.some(g => g.logGroupName === logGroupName))
130
+ if (existing.logGroups?.some((g) => g.logGroupName === logGroupName))
97
131
  return logGroupName;
98
132
  await cw.send(new CreateLogGroupCommand({ logGroupName }));
99
133
  console.log(` ✅ Created log group: ${logGroupName}`);
@@ -102,15 +136,17 @@ export class FargateBuilder extends BaseBuilder {
102
136
  async discoverDefaultVpc() {
103
137
  const ec2 = getEC2Client();
104
138
  const vpcs = await ec2.send(new DescribeVpcsCommand({
105
- Filters: [{ Name: 'isDefault', Values: ['true'] }],
139
+ Filters: [{ Name: "isDefault", Values: ["true"] }],
106
140
  }));
107
141
  const vpcId = vpcs.Vpcs?.[0]?.VpcId;
108
142
  if (!vpcId)
109
143
  throw new Error(`[Fargate:${this.name}] No default VPC found. Use .subnets(ids[]) to specify subnets.`);
110
144
  const subnets = await ec2.send(new DescribeSubnetsCommand({
111
- Filters: [{ Name: 'vpc-id', Values: [vpcId] }],
145
+ Filters: [{ Name: "vpc-id", Values: [vpcId] }],
112
146
  }));
113
- const subnetIds = (subnets.Subnets ?? []).map(s => s.SubnetId).filter(Boolean);
147
+ const subnetIds = (subnets.Subnets ?? [])
148
+ .map((s) => s.SubnetId)
149
+ .filter(Boolean);
114
150
  return { vpcId, subnetIds };
115
151
  }
116
152
  async ensureSecurityGroup(vpcId) {
@@ -118,8 +154,8 @@ export class FargateBuilder extends BaseBuilder {
118
154
  const sgName = `puls-${this.name}-sg`;
119
155
  const existing = await ec2.send(new DescribeSecurityGroupsCommand({
120
156
  Filters: [
121
- { Name: 'group-name', Values: [sgName] },
122
- { Name: 'vpc-id', Values: [vpcId] },
157
+ { Name: "group-name", Values: [sgName] },
158
+ { Name: "vpc-id", Values: [vpcId] },
123
159
  ],
124
160
  }));
125
161
  if (existing.SecurityGroups?.length)
@@ -133,13 +169,15 @@ export class FargateBuilder extends BaseBuilder {
133
169
  if (this._port) {
134
170
  await ec2.send(new AuthorizeSecurityGroupIngressCommand({
135
171
  GroupId: sgId,
136
- IpPermissions: [{
137
- IpProtocol: 'tcp',
172
+ IpPermissions: [
173
+ {
174
+ IpProtocol: "tcp",
138
175
  FromPort: this._port,
139
176
  ToPort: this._port,
140
- IpRanges: [{ CidrIp: '0.0.0.0/0' }],
141
- Ipv6Ranges: [{ CidrIpv6: '::/0' }],
142
- }],
177
+ IpRanges: [{ CidrIp: "0.0.0.0/0" }],
178
+ Ipv6Ranges: [{ CidrIpv6: "::/0" }],
179
+ },
180
+ ],
143
181
  }));
144
182
  }
145
183
  console.log(` ✅ Created security group: ${sgName} (${sgId})`);
@@ -147,10 +185,13 @@ export class FargateBuilder extends BaseBuilder {
147
185
  }
148
186
  async resolveNetworking() {
149
187
  if (this._subnetIds && this._securityGroupIds) {
150
- return { subnetIds: this._subnetIds, securityGroupIds: this._securityGroupIds };
188
+ return {
189
+ subnetIds: this._subnetIds,
190
+ securityGroupIds: this._securityGroupIds,
191
+ };
151
192
  }
152
193
  const { vpcId, subnetIds } = await this.discoverDefaultVpc();
153
- const sgId = this._securityGroupIds?.[0] ?? await this.ensureSecurityGroup(vpcId);
194
+ const sgId = this._securityGroupIds?.[0] ?? (await this.ensureSecurityGroup(vpcId));
154
195
  return {
155
196
  subnetIds: this._subnetIds ?? subnetIds,
156
197
  securityGroupIds: [sgId],
@@ -159,19 +200,19 @@ export class FargateBuilder extends BaseBuilder {
159
200
  async deploy() {
160
201
  const dryRun = this.isDryRunActive();
161
202
  const existing = await this.discoveryPromise;
162
- const region = Config.get().providers.aws?.region ?? 'us-east-1';
203
+ const region = Config.get().providers.aws?.region ?? "us-east-1";
163
204
  console.log(`\n⚡ Finalizing Fargate Service "${this.name}"...`);
164
205
  if (!this._image)
165
206
  throw new Error(`[Fargate:${this.name}] .image("...") is required`);
166
207
  if (dryRun) {
167
- console.log(` 📝 [PLAN] ${existing ? 'Update' : 'Create'} Fargate service "${this.name}"`);
208
+ console.log(` 📝 [PLAN] ${existing ? "Update" : "Create"} Fargate service "${this.name}"`);
168
209
  console.log(` └─ Cluster: ${this._clusterName}`);
169
210
  console.log(` └─ Image: ${this._image}`);
170
211
  console.log(` └─ CPU: ${this._cpu} | Memory: ${this._memory}MB | Replicas: ${this._replicas}`);
171
212
  if (this._port)
172
213
  console.log(` └─ Port: ${this._port}`);
173
214
  if (Object.keys(this._env).length)
174
- console.log(` └─ Env vars: ${Object.keys(this._env).join(', ')}`);
215
+ console.log(` └─ Env vars: ${Object.keys(this._env).join(", ")}`);
175
216
  this.resolvedArn = `arn:aws:ecs:${region}:000000000000:service/${this._clusterName}/DRYRUN`;
176
217
  return { name: this.name, arn: this.resolvedArn };
177
218
  }
@@ -187,16 +228,18 @@ export class FargateBuilder extends BaseBuilder {
187
228
  image: this._image,
188
229
  essential: true,
189
230
  logConfiguration: {
190
- logDriver: 'awslogs',
231
+ logDriver: "awslogs",
191
232
  options: {
192
- 'awslogs-group': logGroupName,
193
- 'awslogs-region': region,
194
- 'awslogs-stream-prefix': this.name,
233
+ "awslogs-group": logGroupName,
234
+ "awslogs-region": region,
235
+ "awslogs-stream-prefix": this.name,
195
236
  },
196
237
  },
197
238
  };
198
239
  if (this._port)
199
- containerDef.portMappings = [{ containerPort: this._port, protocol: 'tcp' }];
240
+ containerDef.portMappings = [
241
+ { containerPort: this._port, protocol: "tcp" },
242
+ ];
200
243
  if (Object.keys(this._env).length) {
201
244
  const resolvedEnv = await resolveEnvVars(this._env);
202
245
  containerDef.environment = Object.entries(resolvedEnv).map(([name, value]) => ({ name, value }));
@@ -204,7 +247,7 @@ export class FargateBuilder extends BaseBuilder {
204
247
  const taskDef = await getECSClient().send(new RegisterTaskDefinitionCommand({
205
248
  family: this.name,
206
249
  networkMode: NetworkMode.AWSVPC,
207
- requiresCompatibilities: ['FARGATE'],
250
+ requiresCompatibilities: ["FARGATE"],
208
251
  cpu: String(this._cpu),
209
252
  memory: String(this._memory),
210
253
  executionRoleArn,
@@ -216,7 +259,7 @@ export class FargateBuilder extends BaseBuilder {
216
259
  awsvpcConfiguration: {
217
260
  subnets: networking.subnetIds,
218
261
  securityGroups: networking.securityGroupIds,
219
- assignPublicIp: 'ENABLED',
262
+ assignPublicIp: "ENABLED",
220
263
  },
221
264
  };
222
265
  const ecs = getECSClient();
@@ -245,14 +288,18 @@ export class FargateBuilder extends BaseBuilder {
245
288
  console.log(`🚀 Created Fargate service "${this.name}" (arn=${this.resolvedArn})`);
246
289
  }
247
290
  await this.deploySidecars();
248
- return { name: this.name, arn: this.resolvedArn, cluster: this._clusterName };
291
+ return {
292
+ name: this.name,
293
+ arn: this.resolvedArn,
294
+ cluster: this._clusterName,
295
+ };
249
296
  }
250
297
  async destroy() {
251
298
  const dryRun = this.isDryRunActive();
252
299
  const existing = await this.discoveryPromise;
253
300
  console.log(`\n🗑️ Destroying Fargate Service "${this.name}"...`);
254
301
  if (!existing) {
255
- console.log(` ✅ Service "${this.name}" does not exist nothing to do`);
302
+ console.log(` ✅ Service "${this.name}" does not exist - nothing to do`);
256
303
  return { destroyed: this.name };
257
304
  }
258
305
  if (dryRun) {
@@ -260,7 +307,7 @@ export class FargateBuilder extends BaseBuilder {
260
307
  return { destroyed: this.name };
261
308
  }
262
309
  const ecs = getECSClient();
263
- // Drain before delete required by ECS
310
+ // Drain before delete - required by ECS
264
311
  await ecs.send(new UpdateServiceCommand({
265
312
  cluster: this._clusterName,
266
313
  service: this.name,
@@ -1,5 +1,5 @@
1
- import { BaseBuilder } from '../../core/resource.js';
2
- import { SecretsBuilder } from './secrets.js';
1
+ import { BaseBuilder } from "../../core/resource.js";
2
+ import { SecretsBuilder } from "./secrets.js";
3
3
  export declare class LambdaBuilder extends BaseBuilder {
4
4
  private _runtime;
5
5
  private _handler;
@@ -1,19 +1,25 @@
1
- import { readFileSync, unlinkSync } from 'node:fs';
2
- import { execSync } from 'node:child_process';
3
- import { tmpdir } from 'node:os';
4
- import { join, extname } from 'node:path';
5
- import { GetFunctionCommand, CreateFunctionCommand, UpdateFunctionCodeCommand, UpdateFunctionConfigurationCommand, DeleteFunctionCommand, } from '@aws-sdk/client-lambda';
6
- import { GetRoleCommand, CreateRoleCommand, AttachRolePolicyCommand, } from '@aws-sdk/client-iam';
7
- import { BaseBuilder } from '../../core/resource.js';
8
- import { getLambdaClient, getIAMClient } from './api.js';
9
- import { resolveEnvVars } from './secrets.js';
1
+ import { readFileSync, unlinkSync } from "node:fs";
2
+ import { execSync } from "node:child_process";
3
+ import { tmpdir } from "node:os";
4
+ import { join, extname } from "node:path";
5
+ import { GetFunctionCommand, CreateFunctionCommand, UpdateFunctionCodeCommand, UpdateFunctionConfigurationCommand, DeleteFunctionCommand, } from "@aws-sdk/client-lambda";
6
+ import { GetRoleCommand, CreateRoleCommand, AttachRolePolicyCommand, } from "@aws-sdk/client-iam";
7
+ import { BaseBuilder } from "../../core/resource.js";
8
+ import { getLambdaClient, getIAMClient } from "./api.js";
9
+ import { resolveEnvVars } from "./secrets.js";
10
10
  const ASSUME_ROLE_POLICY = JSON.stringify({
11
- Version: '2012-10-17',
12
- Statement: [{ Effect: 'Allow', Principal: { Service: 'lambda.amazonaws.com' }, Action: 'sts:AssumeRole' }],
11
+ Version: "2012-10-17",
12
+ Statement: [
13
+ {
14
+ Effect: "Allow",
15
+ Principal: { Service: "lambda.amazonaws.com" },
16
+ Action: "sts:AssumeRole",
17
+ },
18
+ ],
13
19
  });
14
20
  export class LambdaBuilder extends BaseBuilder {
15
- _runtime = 'nodejs20.x';
16
- _handler = 'index.handler';
21
+ _runtime = "nodejs20.x";
22
+ _handler = "index.handler";
17
23
  _memory = 128;
18
24
  _timeout = 30;
19
25
  _codePath;
@@ -31,20 +37,41 @@ export class LambdaBuilder extends BaseBuilder {
31
37
  return result.Configuration ?? null;
32
38
  }
33
39
  catch (e) {
34
- if (e.name === 'ResourceNotFoundException')
40
+ if (e.name === "ResourceNotFoundException")
35
41
  return null;
36
- if (e.name === 'CredentialsProviderError')
42
+ if (e.name === "CredentialsProviderError")
37
43
  return null;
38
44
  throw e;
39
45
  }
40
46
  }
41
- code(pathOrZip) { this._codePath = pathOrZip; return this; }
42
- runtime(r) { this._runtime = r; return this; }
43
- handler(h) { this._handler = h; return this; }
44
- memory(mb) { this._memory = mb; return this; }
45
- timeout(seconds) { this._timeout = seconds; return this; }
46
- role(arn) { this._roleArn = arn; return this; }
47
- env(vars) { this._env = { ...this._env, ...vars }; return this; }
47
+ code(pathOrZip) {
48
+ this._codePath = pathOrZip;
49
+ return this;
50
+ }
51
+ runtime(r) {
52
+ this._runtime = r;
53
+ return this;
54
+ }
55
+ handler(h) {
56
+ this._handler = h;
57
+ return this;
58
+ }
59
+ memory(mb) {
60
+ this._memory = mb;
61
+ return this;
62
+ }
63
+ timeout(seconds) {
64
+ this._timeout = seconds;
65
+ return this;
66
+ }
67
+ role(arn) {
68
+ this._roleArn = arn;
69
+ return this;
70
+ }
71
+ env(vars) {
72
+ this._env = { ...this._env, ...vars };
73
+ return this;
74
+ }
48
75
  async ensureRole() {
49
76
  if (this._roleArn)
50
77
  return this._roleArn;
@@ -55,7 +82,7 @@ export class LambdaBuilder extends BaseBuilder {
55
82
  return existing.Role.Arn;
56
83
  }
57
84
  catch (e) {
58
- if (e.name !== 'NoSuchEntityException')
85
+ if (e.name !== "NoSuchEntityException")
59
86
  throw e;
60
87
  }
61
88
  const created = await iam.send(new CreateRoleCommand({
@@ -65,21 +92,23 @@ export class LambdaBuilder extends BaseBuilder {
65
92
  }));
66
93
  await iam.send(new AttachRolePolicyCommand({
67
94
  RoleName: roleName,
68
- PolicyArn: 'arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole',
95
+ PolicyArn: "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole",
69
96
  }));
70
97
  console.log(` ✅ Created execution role: ${roleName}`);
71
- // IAM propagation Lambda rejects a brand-new role for ~10s
72
- await new Promise(r => setTimeout(r, 10_000));
98
+ // IAM propagation - Lambda rejects a brand-new role for ~10s
99
+ await new Promise((r) => setTimeout(r, 10_000));
73
100
  return created.Role.Arn;
74
101
  }
75
102
  buildZip() {
76
103
  if (!this._codePath)
77
104
  throw new Error(`[Lambda:${this.name}] .code(path) is required`);
78
- if (extname(this._codePath) === '.zip') {
105
+ if (extname(this._codePath) === ".zip") {
79
106
  return readFileSync(this._codePath);
80
107
  }
81
108
  const outPath = join(tmpdir(), `puls-lambda-${this.name}-${Date.now()}.zip`);
82
- execSync(`cd "${this._codePath}" && zip -r "${outPath}" .`, { stdio: 'pipe' });
109
+ execSync(`cd "${this._codePath}" && zip -r "${outPath}" .`, {
110
+ stdio: "pipe",
111
+ });
83
112
  const buf = readFileSync(outPath);
84
113
  unlinkSync(outPath);
85
114
  return buf;
@@ -90,13 +119,13 @@ export class LambdaBuilder extends BaseBuilder {
90
119
  const lambda = getLambdaClient();
91
120
  console.log(`\n⚡ Finalizing Lambda Function "${this.name}"...`);
92
121
  if (dryRun) {
93
- console.log(` 📝 [PLAN] ${existing ? 'Update' : 'Create'} function "${this.name}"`);
122
+ console.log(` 📝 [PLAN] ${existing ? "Update" : "Create"} function "${this.name}"`);
94
123
  console.log(` └─ Runtime: ${this._runtime} | Handler: ${this._handler}`);
95
124
  console.log(` └─ Memory: ${this._memory}MB | Timeout: ${this._timeout}s`);
96
125
  if (this._codePath)
97
126
  console.log(` └─ Code: ${this._codePath}`);
98
127
  if (Object.keys(this._env).length)
99
- console.log(` └─ Env vars: ${Object.keys(this._env).join(', ')}`);
128
+ console.log(` └─ Env vars: ${Object.keys(this._env).join(", ")}`);
100
129
  this.resolvedArn = `arn:aws:lambda:DRYRUN:000000000000:function:${this.name}`;
101
130
  return { name: this.name, arn: this.resolvedArn };
102
131
  }
@@ -111,7 +140,9 @@ export class LambdaBuilder extends BaseBuilder {
111
140
  MemorySize: this._memory,
112
141
  Timeout: this._timeout,
113
142
  Role: roleArn,
114
- Environment: Object.keys(resolvedEnv).length ? { Variables: resolvedEnv } : undefined,
143
+ Environment: Object.keys(resolvedEnv).length
144
+ ? { Variables: resolvedEnv }
145
+ : undefined,
115
146
  };
116
147
  if (existing) {
117
148
  this.resolvedArn = existing.FunctionArn;
@@ -145,7 +176,7 @@ export class LambdaBuilder extends BaseBuilder {
145
176
  const existing = await this.discoveryPromise;
146
177
  console.log(`\n🗑️ Destroying Lambda Function "${this.name}"...`);
147
178
  if (!existing) {
148
- console.log(` ✅ Function "${this.name}" does not exist nothing to do`);
179
+ console.log(` ✅ Function "${this.name}" does not exist - nothing to do`);
149
180
  return { destroyed: this.name };
150
181
  }
151
182
  if (dryRun) {
@@ -1,4 +1,4 @@
1
- import { BaseBuilder } from '../../core/resource.js';
1
+ import { BaseBuilder } from "../../core/resource.js";
2
2
  export declare class RDSBuilder extends BaseBuilder {
3
3
  private _engine;
4
4
  private _engineVersion;