@studion/infra-code-blocks 0.6.12 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +81 -2
- package/dist/components/database-replica.d.ts +1 -1
- package/dist/components/database-replica.js +1 -1
- package/dist/components/database.d.ts +1 -1
- package/dist/components/database.js +1 -1
- package/dist/components/ecs-service.d.ts +15 -2
- package/dist/components/ecs-service.js +52 -18
- package/dist/components/mongo.d.ts +4 -2
- package/dist/components/mongo.js +8 -2
- package/dist/components/web-server.d.ts +1 -1
- package/dist/constants.js +4 -4
- package/package.json +10 -10
package/README.md
CHANGED
|
@@ -171,6 +171,14 @@ export type WebServerServiceOptions = {
|
|
|
171
171
|
}>;
|
|
172
172
|
size?: pulumi.Input<Size>;
|
|
173
173
|
healthCheckPath?: pulumi.Input<string>;
|
|
174
|
+
persistentStorageConfig?: pulumi.Input<{
|
|
175
|
+
volumes: { name: string }[];
|
|
176
|
+
mountPoints: {
|
|
177
|
+
sourceVolume: string;
|
|
178
|
+
containerPath: string;
|
|
179
|
+
readOnly?: boolean;
|
|
180
|
+
}[];
|
|
181
|
+
}>;
|
|
174
182
|
taskExecutionRoleInlinePolicies?: pulumi.Input<
|
|
175
183
|
pulumi.Input<RoleInlinePolicy>[]
|
|
176
184
|
>;
|
|
@@ -219,6 +227,14 @@ type MongoServiceOptions = {
|
|
|
219
227
|
password?: pulumi.Input<string>;
|
|
220
228
|
port?: pulumi.Input<number>;
|
|
221
229
|
size?: pulumi.Input<Size>;
|
|
230
|
+
persistentStorageConfig?: pulumi.Input<{
|
|
231
|
+
volumes: { name: string }[];
|
|
232
|
+
mountPoints: {
|
|
233
|
+
sourceVolume: string;
|
|
234
|
+
containerPath: string;
|
|
235
|
+
readOnly?: boolean;
|
|
236
|
+
}[];
|
|
237
|
+
}>;
|
|
222
238
|
tags?: pulumi.Input<{
|
|
223
239
|
[key: string]: pulumi.Input<string>;
|
|
224
240
|
}>;
|
|
@@ -233,7 +249,14 @@ type EcsServiceOptions = {
|
|
|
233
249
|
port: pulumi.Input<number>;
|
|
234
250
|
enableServiceAutoDiscovery: pulumi.Input<boolean>;
|
|
235
251
|
lbTargetGroupArn?: aws.lb.TargetGroup['arn'];
|
|
236
|
-
|
|
252
|
+
persistentStorageConfig?: pulumi.Input<{
|
|
253
|
+
volumes: { name: string }[];
|
|
254
|
+
mountPoints: {
|
|
255
|
+
sourceVolume: string;
|
|
256
|
+
containerPath: string;
|
|
257
|
+
readOnly?: boolean;
|
|
258
|
+
}[];
|
|
259
|
+
}>;
|
|
237
260
|
securityGroup?: aws.ec2.SecurityGroup;
|
|
238
261
|
assignPublicIp?: pulumi.Input<boolean>;
|
|
239
262
|
dockerCommand?: pulumi.Input<string[]>;
|
|
@@ -339,6 +362,37 @@ const project = new studion.Project('demo-project', {
|
|
|
339
362
|
});
|
|
340
363
|
```
|
|
341
364
|
|
|
365
|
+
### Persistent Storage Configuration
|
|
366
|
+
|
|
367
|
+
Services that require persistent storage (e.g. `ECS`, `Mongo`) can be configured with multiple EFS volumes and mount points.
|
|
368
|
+
Currently, only one access point is configured, with root directory set to `/data`.
|
|
369
|
+
The configuration consists of two main parts:
|
|
370
|
+
|
|
371
|
+
1. `volumes`: Define the EFS volumes to be created
|
|
372
|
+
2. `mountPoints`: Specify where these volumes should be mounted in the container
|
|
373
|
+
|
|
374
|
+
Example configuration:
|
|
375
|
+
|
|
376
|
+
```ts
|
|
377
|
+
persistentStorageConfig: {
|
|
378
|
+
volumes: [
|
|
379
|
+
{ name: 'data-volume' },
|
|
380
|
+
{ name: 'config-volume' }
|
|
381
|
+
],
|
|
382
|
+
mountPoints: [
|
|
383
|
+
{
|
|
384
|
+
sourceVolume: 'data-volume',
|
|
385
|
+
containerPath: '/data',
|
|
386
|
+
},
|
|
387
|
+
{
|
|
388
|
+
sourceVolume: 'config-volume',
|
|
389
|
+
containerPath: '/config',
|
|
390
|
+
readOnly: true
|
|
391
|
+
}
|
|
392
|
+
]
|
|
393
|
+
}
|
|
394
|
+
```
|
|
395
|
+
|
|
342
396
|
### Database
|
|
343
397
|
|
|
344
398
|
AWS RDS Postgres instance.
|
|
@@ -559,6 +613,14 @@ export type WebServerArgs = {
|
|
|
559
613
|
environment?: aws.ecs.KeyValuePair[];
|
|
560
614
|
secrets?: aws.ecs.Secret[];
|
|
561
615
|
healthCheckPath?: pulumi.Input<string>;
|
|
616
|
+
persistentStorageConfig?: pulumi.Input<{
|
|
617
|
+
volumes: { name: string }[];
|
|
618
|
+
mountPoints: {
|
|
619
|
+
sourceVolume: string;
|
|
620
|
+
containerPath: string;
|
|
621
|
+
readOnly?: boolean;
|
|
622
|
+
}[];
|
|
623
|
+
}>;
|
|
562
624
|
taskExecutionRoleInlinePolicies?: pulumi.Input<
|
|
563
625
|
pulumi.Input<RoleInlinePolicy>[]
|
|
564
626
|
>;
|
|
@@ -655,6 +717,14 @@ export type MongoArgs = {
|
|
|
655
717
|
password?: pulumi.Input<string>;
|
|
656
718
|
port?: pulumi.Input<number>;
|
|
657
719
|
size?: pulumi.Input<Size>;
|
|
720
|
+
persistentStorageConfig?: pulumi.Input<{
|
|
721
|
+
volumes: { name: string }[];
|
|
722
|
+
mountPoints: {
|
|
723
|
+
sourceVolume: string;
|
|
724
|
+
containerPath: string;
|
|
725
|
+
readOnly?: boolean;
|
|
726
|
+
}[];
|
|
727
|
+
}>;
|
|
658
728
|
tags?: pulumi.Input<{
|
|
659
729
|
[key: string]: pulumi.Input<string>;
|
|
660
730
|
}>;
|
|
@@ -665,6 +735,8 @@ If the password is not specified it will be autogenerated.
|
|
|
665
735
|
The Mongo password is stored as a secret inside AWS Secret Manager.
|
|
666
736
|
The secret will be available on the `Mongo` resource as `password.secret`.
|
|
667
737
|
|
|
738
|
+
The Mongo component comes with a default persistent storage configuration that mounts an EFS volume `mongo` to `/data/db`. You can override this by providing your own `persistentStorageConfig`.
|
|
739
|
+
|
|
668
740
|
### Ecs Service
|
|
669
741
|
|
|
670
742
|
AWS ECS Fargate.
|
|
@@ -708,7 +780,14 @@ export type EcsServiceArgs = {
|
|
|
708
780
|
environment?: aws.ecs.KeyValuePair[];
|
|
709
781
|
secrets?: aws.ecs.Secret[];
|
|
710
782
|
enableServiceAutoDiscovery: pulumi.Input<boolean>;
|
|
711
|
-
|
|
783
|
+
persistentStorageConfig?: pulumi.Input<{
|
|
784
|
+
volumes: { name: string }[];
|
|
785
|
+
mountPoints: {
|
|
786
|
+
sourceVolume: string;
|
|
787
|
+
containerPath: string;
|
|
788
|
+
readOnly?: boolean;
|
|
789
|
+
}[];
|
|
790
|
+
}>;
|
|
712
791
|
dockerCommand?: pulumi.Input<string[]>;
|
|
713
792
|
lbTargetGroupArn?: aws.lb.TargetGroup['arn'];
|
|
714
793
|
securityGroup?: aws.ec2.SecurityGroup;
|
|
@@ -11,7 +11,7 @@ const defaults = {
|
|
|
11
11
|
maxAllocatedStorage: 100,
|
|
12
12
|
instanceClass: 'db.t4g.micro',
|
|
13
13
|
enableMonitoring: false,
|
|
14
|
-
engineVersion: '
|
|
14
|
+
engineVersion: '17.2',
|
|
15
15
|
};
|
|
16
16
|
class DatabaseReplica extends pulumi.ComponentResource {
|
|
17
17
|
constructor(name, args, opts = {}) {
|
|
@@ -14,7 +14,7 @@ const defaults = {
|
|
|
14
14
|
instanceClass: 'db.t4g.micro',
|
|
15
15
|
enableMonitoring: false,
|
|
16
16
|
allowMajorVersionUpgrade: false,
|
|
17
|
-
engineVersion: '
|
|
17
|
+
engineVersion: '17.2',
|
|
18
18
|
};
|
|
19
19
|
class Database extends pulumi.ComponentResource {
|
|
20
20
|
constructor(name, args, opts = {}) {
|
|
@@ -13,6 +13,18 @@ export type RoleInlinePolicy = {
|
|
|
13
13
|
*/
|
|
14
14
|
policy?: pulumi.Input<string>;
|
|
15
15
|
};
|
|
16
|
+
export type PersistentStorageMountPoint = {
|
|
17
|
+
sourceVolume: string;
|
|
18
|
+
containerPath: string;
|
|
19
|
+
readOnly?: boolean;
|
|
20
|
+
};
|
|
21
|
+
export type PersistentStorageVolume = {
|
|
22
|
+
name: string;
|
|
23
|
+
};
|
|
24
|
+
export type PersistentStorageConfig = {
|
|
25
|
+
volumes: PersistentStorageVolume[];
|
|
26
|
+
mountPoints: PersistentStorageMountPoint[];
|
|
27
|
+
};
|
|
16
28
|
export type EcsServiceArgs = {
|
|
17
29
|
/**
|
|
18
30
|
* The ECR image used to start a container.
|
|
@@ -70,9 +82,10 @@ export type EcsServiceArgs = {
|
|
|
70
82
|
*/
|
|
71
83
|
enableServiceAutoDiscovery: pulumi.Input<boolean>;
|
|
72
84
|
/**
|
|
73
|
-
*
|
|
85
|
+
* Configuration for multiple EFS volumes and their mount points.
|
|
86
|
+
* Each mount point specifies a container path where the EFS volume will be mounted.
|
|
74
87
|
*/
|
|
75
|
-
|
|
88
|
+
persistentStorageConfig?: pulumi.Input<PersistentStorageConfig>;
|
|
76
89
|
/**
|
|
77
90
|
* Alternate docker CMD instruction.
|
|
78
91
|
*/
|
|
@@ -19,6 +19,18 @@ exports.assumeRolePolicy = {
|
|
|
19
19
|
},
|
|
20
20
|
],
|
|
21
21
|
};
|
|
22
|
+
/**
|
|
23
|
+
* Standard directory permissions:
|
|
24
|
+
* - Owner: read, write, execute (7)
|
|
25
|
+
* - Group: read, execute (5)
|
|
26
|
+
* - Others: read, execute (5)
|
|
27
|
+
*/
|
|
28
|
+
const STANDARD_DIRECTORY_PERMISSIONS = '0755';
|
|
29
|
+
const FIRST_POSIX_NON_ROOT_USER = {
|
|
30
|
+
userId: 1000,
|
|
31
|
+
groupId: 1000,
|
|
32
|
+
permissions: STANDARD_DIRECTORY_PERMISSIONS
|
|
33
|
+
};
|
|
22
34
|
const defaults = {
|
|
23
35
|
desiredCount: 1,
|
|
24
36
|
size: 'small',
|
|
@@ -167,6 +179,22 @@ class EcsService extends pulumi.ComponentResource {
|
|
|
167
179
|
}
|
|
168
180
|
throw Error('Incorrect EcsService size argument');
|
|
169
181
|
});
|
|
182
|
+
const fileSystemId = this.createPersistentStorage(argsWithDefaults).id;
|
|
183
|
+
const accessPoint = new aws.efs.AccessPoint(`${this.name}-efs-ap`, {
|
|
184
|
+
fileSystemId,
|
|
185
|
+
posixUser: {
|
|
186
|
+
uid: FIRST_POSIX_NON_ROOT_USER.userId,
|
|
187
|
+
gid: FIRST_POSIX_NON_ROOT_USER.groupId,
|
|
188
|
+
},
|
|
189
|
+
rootDirectory: {
|
|
190
|
+
path: '/data',
|
|
191
|
+
creationInfo: {
|
|
192
|
+
ownerUid: FIRST_POSIX_NON_ROOT_USER.userId,
|
|
193
|
+
ownerGid: FIRST_POSIX_NON_ROOT_USER.groupId,
|
|
194
|
+
permissions: FIRST_POSIX_NON_ROOT_USER.permissions,
|
|
195
|
+
},
|
|
196
|
+
},
|
|
197
|
+
});
|
|
170
198
|
const taskDefinition = new aws.ecs.TaskDefinition(`${this.name}-task-definition`, Object.assign(Object.assign({ family: `${this.name}-task-definition-${stack}`, networkMode: 'awsvpc', executionRoleArn: taskExecutionRole.arn, taskRoleArn: taskRole.arn, cpu: parsedSize.cpu, memory: parsedSize.memory, requiresCompatibilities: ['FARGATE'], containerDefinitions: pulumi
|
|
171
199
|
.all([
|
|
172
200
|
this.name,
|
|
@@ -174,25 +202,27 @@ class EcsService extends pulumi.ComponentResource {
|
|
|
174
202
|
argsWithDefaults.port,
|
|
175
203
|
argsWithDefaults.environment,
|
|
176
204
|
argsWithDefaults.secrets,
|
|
177
|
-
argsWithDefaults.
|
|
205
|
+
argsWithDefaults.persistentStorageConfig,
|
|
178
206
|
argsWithDefaults.dockerCommand,
|
|
179
207
|
this.logGroup.name,
|
|
180
208
|
exports.awsRegion,
|
|
181
209
|
])
|
|
182
|
-
.apply(([containerName, image, port, environment, secrets,
|
|
210
|
+
.apply(([containerName, image, port, environment, secrets, persistentStorageConfig, command, logGroup, region,]) => {
|
|
183
211
|
return JSON.stringify([
|
|
184
212
|
Object.assign(Object.assign({ readonlyRootFilesystem: false, name: containerName, image, essential: true, portMappings: [
|
|
185
213
|
{
|
|
186
214
|
containerPort: port,
|
|
187
215
|
protocol: 'tcp',
|
|
188
216
|
},
|
|
189
|
-
] }, (
|
|
190
|
-
mountPoints:
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
217
|
+
] }, (persistentStorageConfig && {
|
|
218
|
+
mountPoints: persistentStorageConfig.mountPoints.map(mountPoint => {
|
|
219
|
+
var _a;
|
|
220
|
+
return ({
|
|
221
|
+
containerPath: mountPoint.containerPath,
|
|
222
|
+
sourceVolume: mountPoint.sourceVolume,
|
|
223
|
+
readOnly: (_a = mountPoint.readOnly) !== null && _a !== void 0 ? _a : false,
|
|
224
|
+
});
|
|
225
|
+
}),
|
|
196
226
|
})), { logConfiguration: {
|
|
197
227
|
logDriver: 'awslogs',
|
|
198
228
|
options: {
|
|
@@ -204,16 +234,20 @@ class EcsService extends pulumi.ComponentResource {
|
|
|
204
234
|
environment,
|
|
205
235
|
secrets }),
|
|
206
236
|
]);
|
|
207
|
-
}) }, (argsWithDefaults.
|
|
208
|
-
volumes:
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
237
|
+
}) }, (argsWithDefaults.persistentStorageConfig && {
|
|
238
|
+
volumes: argsWithDefaults.persistentStorageConfig
|
|
239
|
+
.volumes
|
|
240
|
+
.map(volume => ({
|
|
241
|
+
name: volume.name,
|
|
242
|
+
efsVolumeConfiguration: {
|
|
243
|
+
fileSystemId,
|
|
244
|
+
transitEncryption: 'ENABLED',
|
|
245
|
+
authorizationConfig: {
|
|
246
|
+
accessPointId: accessPoint.id,
|
|
247
|
+
iam: 'ENABLED',
|
|
214
248
|
},
|
|
215
|
-
}
|
|
216
|
-
|
|
249
|
+
}
|
|
250
|
+
})),
|
|
217
251
|
})), { tags: Object.assign(Object.assign({}, constants_1.commonTags), argsWithDefaults.tags) }), { parent: this });
|
|
218
252
|
return taskDefinition;
|
|
219
253
|
}
|
|
@@ -21,9 +21,11 @@ export type MongoArgs = Pick<EcsServiceArgs, 'size' | 'clusterId' | 'clusterName
|
|
|
21
21
|
*/
|
|
22
22
|
port?: pulumi.Input<number>;
|
|
23
23
|
/**
|
|
24
|
-
*
|
|
24
|
+
* Configuration for persistent storage using EFS volumes.
|
|
25
|
+
* By default, creates a volume named 'mongo' mounted at '/data/db'.
|
|
26
|
+
* You can override this by providing your own volume and mount point configuration.
|
|
25
27
|
*/
|
|
26
|
-
|
|
28
|
+
persistentStorageConfig?: EcsServiceArgs['persistentStorageConfig'];
|
|
27
29
|
};
|
|
28
30
|
export declare class Mongo extends pulumi.ComponentResource {
|
|
29
31
|
readonly name: string;
|
package/dist/components/mongo.js
CHANGED
|
@@ -21,7 +21,13 @@ class Mongo extends pulumi.ComponentResource {
|
|
|
21
21
|
const image = args.image ||
|
|
22
22
|
'mongo:7.0.3@sha256:238b1636bdd7820c752b91bec8a669f92568eb313ad89a1fc4a92903c1b40489';
|
|
23
23
|
const port = args.port || 27017;
|
|
24
|
-
const
|
|
24
|
+
const persistentStorageConfig = args.persistentStorageConfig || {
|
|
25
|
+
volumes: [{ name: 'mongo' }],
|
|
26
|
+
mountPoints: [{
|
|
27
|
+
sourceVolume: 'mongo',
|
|
28
|
+
containerPath: '/data/db'
|
|
29
|
+
}]
|
|
30
|
+
};
|
|
25
31
|
const { username, password, privateSubnetIds } = args, ecsServiceArgs = __rest(args, ["username", "password", "privateSubnetIds"]);
|
|
26
32
|
this.name = name;
|
|
27
33
|
this.host = pulumi.output(`${name}.${name}`);
|
|
@@ -29,7 +35,7 @@ class Mongo extends pulumi.ComponentResource {
|
|
|
29
35
|
this.port = pulumi.output(port);
|
|
30
36
|
this.password = new password_1.Password(`${this.name}-mongo-password`, { value: password }, { parent: this });
|
|
31
37
|
this.service = new ecs_service_1.EcsService(name, Object.assign(Object.assign({}, ecsServiceArgs), { port,
|
|
32
|
-
image, desiredCount: 1, autoscaling: { enabled: false }, enableServiceAutoDiscovery: true,
|
|
38
|
+
image, desiredCount: 1, autoscaling: { enabled: false }, enableServiceAutoDiscovery: true, persistentStorageConfig, dockerCommand: ['mongod', '--port', port.toString()], assignPublicIp: false, subnetIds: privateSubnetIds, environment: [
|
|
33
39
|
{
|
|
34
40
|
name: 'MONGO_INITDB_ROOT_USERNAME',
|
|
35
41
|
value: username,
|
|
@@ -2,7 +2,7 @@ import * as pulumi from '@pulumi/pulumi';
|
|
|
2
2
|
import * as aws from '@pulumi/aws';
|
|
3
3
|
import { AcmCertificate } from './acm-certificate';
|
|
4
4
|
import { EcsService, EcsServiceArgs } from './ecs-service';
|
|
5
|
-
export type WebServerArgs = Pick<EcsServiceArgs, 'image' | 'port' | 'clusterId' | 'clusterName' | 'vpcId' | 'vpcCidrBlock' | 'desiredCount' | 'autoscaling' | 'size' | 'environment' | 'secrets' | 'taskExecutionRoleInlinePolicies' | 'taskRoleInlinePolicies' | 'tags'> & {
|
|
5
|
+
export type WebServerArgs = Pick<EcsServiceArgs, 'image' | 'port' | 'clusterId' | 'clusterName' | 'vpcId' | 'vpcCidrBlock' | 'desiredCount' | 'autoscaling' | 'size' | 'environment' | 'secrets' | 'persistentStorageConfig' | 'taskExecutionRoleInlinePolicies' | 'taskRoleInlinePolicies' | 'tags'> & {
|
|
6
6
|
publicSubnetIds: pulumi.Input<pulumi.Input<string>[]>;
|
|
7
7
|
/**
|
|
8
8
|
* The domain which will be used to access the service.
|
package/dist/constants.js
CHANGED
|
@@ -6,19 +6,19 @@ const CPU_1_VCPU = 1024;
|
|
|
6
6
|
const MEMORY_1GB = 1024;
|
|
7
7
|
exports.PredefinedSize = {
|
|
8
8
|
small: {
|
|
9
|
-
cpu: CPU_1_VCPU / 4,
|
|
9
|
+
cpu: CPU_1_VCPU / 4, // 0.25 vCPU
|
|
10
10
|
memory: MEMORY_1GB / 2, // 0.5 GB memory
|
|
11
11
|
},
|
|
12
12
|
medium: {
|
|
13
|
-
cpu: CPU_1_VCPU / 2,
|
|
13
|
+
cpu: CPU_1_VCPU / 2, // 0.5 vCPU
|
|
14
14
|
memory: MEMORY_1GB, // 1 GB memory
|
|
15
15
|
},
|
|
16
16
|
large: {
|
|
17
|
-
cpu: CPU_1_VCPU,
|
|
17
|
+
cpu: CPU_1_VCPU, // 1 vCPU
|
|
18
18
|
memory: MEMORY_1GB * 2, // 2 GB memory
|
|
19
19
|
},
|
|
20
20
|
xlarge: {
|
|
21
|
-
cpu: CPU_1_VCPU * 2,
|
|
21
|
+
cpu: CPU_1_VCPU * 2, // 2 vCPU
|
|
22
22
|
memory: MEMORY_1GB * 4, // 4 GB memory
|
|
23
23
|
},
|
|
24
24
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@studion/infra-code-blocks",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Studion common infra components",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"infrastructure",
|
|
@@ -32,18 +32,18 @@
|
|
|
32
32
|
},
|
|
33
33
|
"prettier": "@studion/prettier-config",
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@pulumi/aws": "^
|
|
36
|
-
"@pulumi/awsx": "^
|
|
37
|
-
"@pulumi/pulumi": "^3.
|
|
38
|
-
"@pulumi/random": "^4.
|
|
39
|
-
"@upstash/pulumi": "^0.
|
|
35
|
+
"@pulumi/aws": "^6.66.3",
|
|
36
|
+
"@pulumi/awsx": "^2.21.0",
|
|
37
|
+
"@pulumi/pulumi": "^3.146.0",
|
|
38
|
+
"@pulumi/random": "^4.17.0",
|
|
39
|
+
"@upstash/pulumi": "^0.3.14"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@studion/prettier-config": "^0.1.0",
|
|
43
|
-
"@types/node": "^
|
|
44
|
-
"prettier": "^3.
|
|
45
|
-
"release-it": "^
|
|
46
|
-
"typescript": "^5.
|
|
43
|
+
"@types/node": "^22",
|
|
44
|
+
"prettier": "^3.4.2",
|
|
45
|
+
"release-it": "^18.1.1",
|
|
46
|
+
"typescript": "^5.7.3"
|
|
47
47
|
},
|
|
48
48
|
"publishConfig": {
|
|
49
49
|
"access": "public"
|