@vyriy/services 0.1.9
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/LICENSE +21 -0
- package/README.md +100 -0
- package/cloudfront/actions.d.ts +2 -0
- package/cloudfront/actions.js +40 -0
- package/cloudfront/client.d.ts +2 -0
- package/cloudfront/client.js +2 -0
- package/cloudfront/index.d.ts +3 -0
- package/cloudfront/index.js +2 -0
- package/cloudfront/types.d.ts +1 -0
- package/dynamodb/actions.d.ts +9 -0
- package/dynamodb/actions.js +131 -0
- package/dynamodb/client.d.ts +2 -0
- package/dynamodb/client.js +9 -0
- package/dynamodb/index.d.ts +3 -0
- package/dynamodb/index.js +2 -0
- package/dynamodb/types.d.ts +14 -0
- package/ecs/actions.d.ts +2 -0
- package/ecs/actions.js +50 -0
- package/ecs/client.d.ts +2 -0
- package/ecs/client.js +4 -0
- package/ecs/index.d.ts +3 -0
- package/ecs/index.js +2 -0
- package/ecs/types.d.ts +4 -0
- package/index.d.ts +7 -0
- package/index.js +7 -0
- package/lambda/actions.d.ts +2 -0
- package/lambda/actions.js +23 -0
- package/lambda/client.d.ts +2 -0
- package/lambda/client.js +4 -0
- package/lambda/index.d.ts +3 -0
- package/lambda/index.js +2 -0
- package/lambda/types.d.ts +2 -0
- package/package.json +251 -0
- package/s3/actions.d.ts +4 -0
- package/s3/actions.js +59 -0
- package/s3/client.d.ts +2 -0
- package/s3/client.js +10 -0
- package/s3/index.d.ts +3 -0
- package/s3/index.js +2 -0
- package/s3/types.d.ts +4 -0
- package/sns/actions.d.ts +2 -0
- package/sns/actions.js +8 -0
- package/sns/client.d.ts +2 -0
- package/sns/client.js +2 -0
- package/sns/index.d.ts +3 -0
- package/sns/index.js +2 -0
- package/sns/types.d.ts +2 -0
- package/ssm/actions.d.ts +3 -0
- package/ssm/actions.js +37 -0
- package/ssm/client.d.ts +2 -0
- package/ssm/client.js +2 -0
- package/ssm/index.d.ts +3 -0
- package/ssm/index.js +2 -0
- package/ssm/types.d.ts +2 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Vyriy contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# @vyriy/services
|
|
2
|
+
|
|
3
|
+
Small AWS service SDK for Vyriy projects.
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
This package wraps common AWS SDK operations behind calm, reusable helpers.
|
|
8
|
+
It is not meant to hide AWS. It keeps the AWS command inputs available where
|
|
9
|
+
they are useful, while removing repeated client setup and common boilerplate
|
|
10
|
+
from app, script, service, and deployment code.
|
|
11
|
+
|
|
12
|
+
The package is AWS-first and serverless-oriented. Current helpers cover:
|
|
13
|
+
|
|
14
|
+
- `cloudfront`: create invalidations and optionally wait for completion
|
|
15
|
+
- `dynamodb`: create tables and read/write/query/scan document items
|
|
16
|
+
- `ecs`: start one Fargate task with environment overrides
|
|
17
|
+
- `lambda`: invoke Lambda functions with JSON string payloads
|
|
18
|
+
- `s3`: upload, download, and check object existence
|
|
19
|
+
- `sns`: publish messages to topics
|
|
20
|
+
- `ssm`: read one or many Parameter Store values
|
|
21
|
+
|
|
22
|
+
## Install
|
|
23
|
+
|
|
24
|
+
With npm:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npm install @vyriy/services
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
With Yarn:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
yarn add @vyriy/services
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## LocalStack
|
|
37
|
+
|
|
38
|
+
Some clients are prepared for local AWS-compatible development:
|
|
39
|
+
|
|
40
|
+
- `dynamodb` uses `LOCALSTACK_HOST` and `LOCALSTACK_PORT` as its endpoint when
|
|
41
|
+
`@vyriy/env` reports the local stage.
|
|
42
|
+
- `s3` uses the same LocalStack endpoint in local stage and enables
|
|
43
|
+
`forcePathStyle`.
|
|
44
|
+
- `ecs` uses the configured region in local stage, but does not point to a
|
|
45
|
+
LocalStack endpoint.
|
|
46
|
+
- `cloudfront`, `lambda`, `sns`, and `ssm` currently use their normal AWS SDK
|
|
47
|
+
client configuration.
|
|
48
|
+
|
|
49
|
+
LocalStack defaults come from `@vyriy/env`:
|
|
50
|
+
|
|
51
|
+
- `LOCALSTACK_HOST`: defaults to `localhost`
|
|
52
|
+
- `LOCALSTACK_PORT`: defaults to `4566`
|
|
53
|
+
|
|
54
|
+
## Usage
|
|
55
|
+
|
|
56
|
+
Import from the package root:
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
import * as services from '@vyriy/services';
|
|
60
|
+
|
|
61
|
+
await services.s3.upload('assets-bucket', 'pages/index.html', '<html>...</html>', 'text/html');
|
|
62
|
+
await services.lambda.invoke('my-function', JSON.stringify({ ok: true }));
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Or import a service subpath directly:
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
import { getParameter } from '@vyriy/services/ssm';
|
|
69
|
+
import { upload } from '@vyriy/services/s3';
|
|
70
|
+
|
|
71
|
+
const apiUrl = await getParameter('/app/api-url');
|
|
72
|
+
|
|
73
|
+
await upload('assets-bucket', 'config/api-url.txt', apiUrl, 'text/plain');
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Examples
|
|
77
|
+
|
|
78
|
+
Invalidate CloudFront after publishing static files:
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
import { invalidate } from '@vyriy/services/cloudfront';
|
|
82
|
+
|
|
83
|
+
await invalidate('DISTRIBUTION_ID', ['/index.html', '/assets/*'], true);
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Run a Fargate task:
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
import { runTask } from '@vyriy/services/ecs';
|
|
90
|
+
|
|
91
|
+
await runTask('regenerate-pages', [{ name: 'CONTENT_ID', value: 'home' }]);
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Read application settings from SSM:
|
|
95
|
+
|
|
96
|
+
```ts
|
|
97
|
+
import { getParameters } from '@vyriy/services/ssm';
|
|
98
|
+
|
|
99
|
+
const settings = await getParameters(['/app/api-url', '/app/cdn-url']);
|
|
100
|
+
```
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { CreateInvalidationCommand, GetInvalidationCommand } from '@aws-sdk/client-cloudfront';
|
|
2
|
+
import { createLogger } from '@vyriy/logger';
|
|
3
|
+
import { pause } from '@vyriy/pause';
|
|
4
|
+
import { toError } from '@vyriy/error';
|
|
5
|
+
import { client } from './client.js';
|
|
6
|
+
export const invalidate = async (distribution, paths, shouldWait = false) => {
|
|
7
|
+
try {
|
|
8
|
+
const logger = createLogger();
|
|
9
|
+
logger.info('Distribution:', distribution);
|
|
10
|
+
logger.info('Paths:', paths);
|
|
11
|
+
logger.info('CreateInvalidationCommand');
|
|
12
|
+
const invalidationResponse = await client.send(new CreateInvalidationCommand({
|
|
13
|
+
DistributionId: distribution,
|
|
14
|
+
InvalidationBatch: {
|
|
15
|
+
CallerReference: Date.now().toString(),
|
|
16
|
+
Paths: {
|
|
17
|
+
Quantity: paths.length,
|
|
18
|
+
Items: paths,
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
}));
|
|
22
|
+
const check = async () => {
|
|
23
|
+
const response = await client.send(new GetInvalidationCommand({
|
|
24
|
+
DistributionId: distribution,
|
|
25
|
+
Id: invalidationResponse.Invalidation?.Id,
|
|
26
|
+
}));
|
|
27
|
+
if (response.Invalidation?.Status !== 'Completed') {
|
|
28
|
+
await pause(3000);
|
|
29
|
+
await check();
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
if (shouldWait) {
|
|
33
|
+
await check();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
catch (e) {
|
|
37
|
+
createLogger().error(e);
|
|
38
|
+
throw toError(e);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type Invalidate = (distribution: string, paths: string[], shouldWait?: boolean) => Promise<void>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { CreateItem, CreateTable, DeleteItem, GetAllItems, GetAllItemsWithHandler, GetItem, GetItems, UpdateItem } from './types.js';
|
|
2
|
+
export declare const createTable: CreateTable;
|
|
3
|
+
export declare const createItem: CreateItem;
|
|
4
|
+
export declare const updateItem: UpdateItem;
|
|
5
|
+
export declare const getItem: GetItem;
|
|
6
|
+
export declare const deleteItem: DeleteItem;
|
|
7
|
+
export declare const getItems: GetItems;
|
|
8
|
+
export declare const getAllItems: GetAllItems;
|
|
9
|
+
export declare const getAllItemsWithHandler: GetAllItemsWithHandler;
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { CreateTableCommand } from '@aws-sdk/client-dynamodb';
|
|
2
|
+
import { DeleteCommand, GetCommand, PutCommand, QueryCommand, ScanCommand, UpdateCommand } from '@aws-sdk/lib-dynamodb';
|
|
3
|
+
import { createLogger } from '@vyriy/logger';
|
|
4
|
+
import { toError } from '@vyriy/error';
|
|
5
|
+
import { client } from './client.js';
|
|
6
|
+
export const createTable = async (params) => {
|
|
7
|
+
try {
|
|
8
|
+
createLogger().log('CreateTableCommand:', params);
|
|
9
|
+
await client.send(new CreateTableCommand(params));
|
|
10
|
+
}
|
|
11
|
+
catch (e) {
|
|
12
|
+
throw toError(e);
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
export const createItem = async (TableName, Item, options = {}) => {
|
|
16
|
+
try {
|
|
17
|
+
createLogger().log('PutCommand:', { TableName, Item, ...options });
|
|
18
|
+
await client.send(new PutCommand({ TableName, Item, ...options }));
|
|
19
|
+
}
|
|
20
|
+
catch (e) {
|
|
21
|
+
throw toError(e);
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
export const updateItem = async (TableName, Key, UpdateExpression, ExpressionAttributeValues, options = {}) => {
|
|
25
|
+
try {
|
|
26
|
+
const logger = createLogger();
|
|
27
|
+
const params = {
|
|
28
|
+
TableName,
|
|
29
|
+
Key,
|
|
30
|
+
UpdateExpression,
|
|
31
|
+
ExpressionAttributeValues,
|
|
32
|
+
...options,
|
|
33
|
+
};
|
|
34
|
+
logger.log('UpdateCommand:', params);
|
|
35
|
+
await client.send(new UpdateCommand(params));
|
|
36
|
+
}
|
|
37
|
+
catch (e) {
|
|
38
|
+
throw toError(e);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
export const getItem = async (TableName, Key, options = {}) => {
|
|
42
|
+
try {
|
|
43
|
+
createLogger().log('GetCommand:', { TableName, Key, ...options });
|
|
44
|
+
return await client.send(new GetCommand({ TableName, Key, ...options })).then(({ Item }) => Item);
|
|
45
|
+
}
|
|
46
|
+
catch (e) {
|
|
47
|
+
throw toError(e);
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
export const deleteItem = async (TableName, Key, options = {}) => {
|
|
51
|
+
try {
|
|
52
|
+
createLogger().log('DeleteCommand:', { TableName, Key, ...options });
|
|
53
|
+
await client.send(new DeleteCommand({ TableName, Key, ...options }));
|
|
54
|
+
}
|
|
55
|
+
catch (e) {
|
|
56
|
+
throw toError(e);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
export const getItems = async (TableName, keys, options = {}) => {
|
|
60
|
+
try {
|
|
61
|
+
const logger = createLogger();
|
|
62
|
+
const expressionList = [];
|
|
63
|
+
const ExpressionAttributeNames = {};
|
|
64
|
+
const ExpressionAttributeValues = {};
|
|
65
|
+
Object.keys(keys).forEach((key) => {
|
|
66
|
+
if (keys[key] !== undefined && keys[key] !== '') {
|
|
67
|
+
ExpressionAttributeNames[`#${key}`] = key;
|
|
68
|
+
ExpressionAttributeValues[`:${key}`] = keys[key];
|
|
69
|
+
expressionList.push(`#${key} = :${key}`);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
const queryOptions = {
|
|
73
|
+
ExpressionAttributeNames,
|
|
74
|
+
ExpressionAttributeValues,
|
|
75
|
+
KeyConditionExpression: expressionList.join(' AND '),
|
|
76
|
+
};
|
|
77
|
+
const params = { TableName, ...queryOptions, ...options };
|
|
78
|
+
const items = [];
|
|
79
|
+
const queryUntilDone = async (ExclusiveStartKey) => {
|
|
80
|
+
logger.log('QueryCommand:', { ...params, ExclusiveStartKey });
|
|
81
|
+
const data = await client.send(new QueryCommand({ ...params, ExclusiveStartKey }));
|
|
82
|
+
items.push(...(data.Items || []));
|
|
83
|
+
if (data.LastEvaluatedKey) {
|
|
84
|
+
await queryUntilDone(data.LastEvaluatedKey);
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
await queryUntilDone();
|
|
88
|
+
return items;
|
|
89
|
+
}
|
|
90
|
+
catch (e) {
|
|
91
|
+
throw toError(e);
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
export const getAllItems = async (TableName, options = {}) => {
|
|
95
|
+
try {
|
|
96
|
+
const logger = createLogger();
|
|
97
|
+
const params = { TableName, ...options };
|
|
98
|
+
const items = [];
|
|
99
|
+
const scanUntilDone = async (ExclusiveStartKey) => {
|
|
100
|
+
logger.log('ScanCommand:', { ...params, ExclusiveStartKey });
|
|
101
|
+
const data = await client.send(new ScanCommand({ ...params, ExclusiveStartKey }));
|
|
102
|
+
items.push(...(data.Items || []));
|
|
103
|
+
if (data.LastEvaluatedKey) {
|
|
104
|
+
await scanUntilDone(data.LastEvaluatedKey);
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
await scanUntilDone();
|
|
108
|
+
return items;
|
|
109
|
+
}
|
|
110
|
+
catch (e) {
|
|
111
|
+
throw toError(e);
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
export const getAllItemsWithHandler = async (TableName, handler, options = {}) => {
|
|
115
|
+
try {
|
|
116
|
+
const logger = createLogger();
|
|
117
|
+
const params = { TableName, ...options };
|
|
118
|
+
const scanUntilDone = async (ExclusiveStartKey) => {
|
|
119
|
+
logger.log('ScanCommand:', { ...params, ExclusiveStartKey });
|
|
120
|
+
const data = await client.send(new ScanCommand({ ...params, ExclusiveStartKey }));
|
|
121
|
+
await handler(data.Items || []);
|
|
122
|
+
if (data.LastEvaluatedKey) {
|
|
123
|
+
await scanUntilDone(data.LastEvaluatedKey);
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
await scanUntilDone();
|
|
127
|
+
}
|
|
128
|
+
catch (e) {
|
|
129
|
+
throw toError(e);
|
|
130
|
+
}
|
|
131
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
|
|
2
|
+
import { getLocalstackHost, getLocalstackPort, getRegion, isLocal } from '@vyriy/env';
|
|
3
|
+
const options = isLocal()
|
|
4
|
+
? {
|
|
5
|
+
region: getRegion(),
|
|
6
|
+
endpoint: `http://${getLocalstackHost()}:${getLocalstackPort()}`,
|
|
7
|
+
}
|
|
8
|
+
: {};
|
|
9
|
+
export const client = new DynamoDBClient(options);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { CreateTableCommandInput } from '@aws-sdk/client-dynamodb';
|
|
2
|
+
import type { NativeAttributeValue } from '@aws-sdk/util-dynamodb';
|
|
3
|
+
import type { DeleteCommandInput, GetCommandInput, PutCommandInput, QueryCommandInput, ScanCommandInput, UpdateCommandInput } from '@aws-sdk/lib-dynamodb';
|
|
4
|
+
export type CreateTable = (params: CreateTableCommandInput) => Promise<void>;
|
|
5
|
+
export type Key = Record<string, NativeAttributeValue>;
|
|
6
|
+
export type Item = Record<string, unknown>;
|
|
7
|
+
export type CreateItem = (TableName: string, Item: Item, options?: Omit<PutCommandInput, 'TableName' | 'Item'>) => Promise<void>;
|
|
8
|
+
export type GetItem = (TableName: string, Key: Record<string, string | number>, options?: Omit<GetCommandInput, 'TableName' | 'Key'>) => Promise<Item | undefined>;
|
|
9
|
+
export type DeleteItem = (TableName: string, Key: Record<string, string | number>, options?: Omit<DeleteCommandInput, 'TableName' | 'Key'>) => Promise<void>;
|
|
10
|
+
export type UpdateItem = (TableName: string, Key: Record<string, string | number>, UpdateExpression: string, ExpressionAttributeValues?: Record<string, unknown>, options?: Omit<UpdateCommandInput, 'TableName' | 'Key' | 'UpdateExpression' | 'ExpressionAttributeValues'>) => Promise<void>;
|
|
11
|
+
export type GetItems = (TableName: string, keys: Record<string, unknown>, options?: Omit<QueryCommandInput, 'TableName'>) => Promise<unknown[]>;
|
|
12
|
+
export type GetAllItems = (TableName: string, options?: Omit<ScanCommandInput, 'TableName'>) => Promise<unknown[]>;
|
|
13
|
+
export type Handler = (items: unknown[]) => Promise<void>;
|
|
14
|
+
export type GetAllItemsWithHandler = (TableName: string, handler: Handler, options?: Omit<ScanCommandInput, 'TableName'>) => Promise<void>;
|
package/ecs/actions.d.ts
ADDED
package/ecs/actions.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { RunTaskCommand } from '@aws-sdk/client-ecs';
|
|
2
|
+
import { getEcsClusterName, getEcsTaskDefinition, getVpcSecurityGroup, getVpcSubnets } from '@vyriy/env';
|
|
3
|
+
import { createLogger } from '@vyriy/logger';
|
|
4
|
+
import { client } from './client.js';
|
|
5
|
+
export const runTask = async (task, environment = [], taskDefinition = getEcsTaskDefinition()) => {
|
|
6
|
+
const cluster = getEcsClusterName();
|
|
7
|
+
const subnets = getVpcSubnets();
|
|
8
|
+
const securityGroup = getVpcSecurityGroup();
|
|
9
|
+
if (!cluster) {
|
|
10
|
+
throw new Error('Cluster must be set!');
|
|
11
|
+
}
|
|
12
|
+
if (!taskDefinition) {
|
|
13
|
+
throw new Error('Task definition must be set!');
|
|
14
|
+
}
|
|
15
|
+
if (!subnets) {
|
|
16
|
+
throw new Error('Subnets must be set!');
|
|
17
|
+
}
|
|
18
|
+
if (!securityGroup) {
|
|
19
|
+
throw new Error('SecurityGroup must be set!');
|
|
20
|
+
}
|
|
21
|
+
const params = {
|
|
22
|
+
cluster,
|
|
23
|
+
taskDefinition,
|
|
24
|
+
launchType: 'FARGATE',
|
|
25
|
+
count: 1,
|
|
26
|
+
networkConfiguration: {
|
|
27
|
+
awsvpcConfiguration: {
|
|
28
|
+
assignPublicIp: 'ENABLED',
|
|
29
|
+
subnets: subnets.split(','),
|
|
30
|
+
securityGroups: [securityGroup],
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
overrides: {
|
|
34
|
+
containerOverrides: [
|
|
35
|
+
{
|
|
36
|
+
name: task,
|
|
37
|
+
environment: [
|
|
38
|
+
{
|
|
39
|
+
name: 'TASK',
|
|
40
|
+
value: task,
|
|
41
|
+
},
|
|
42
|
+
...environment,
|
|
43
|
+
],
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
createLogger().info('Params:', params);
|
|
49
|
+
await client.send(new RunTaskCommand(params));
|
|
50
|
+
};
|
package/ecs/client.d.ts
ADDED
package/ecs/client.js
ADDED
package/ecs/index.d.ts
ADDED
package/ecs/index.js
ADDED
package/ecs/types.d.ts
ADDED
package/index.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export * as cloudfront from './cloudfront/index.js';
|
|
2
|
+
export * as dynamodb from './dynamodb/index.js';
|
|
3
|
+
export * as ecs from './ecs/index.js';
|
|
4
|
+
export * as lambda from './lambda/index.js';
|
|
5
|
+
export * as s3 from './s3/index.js';
|
|
6
|
+
export * as sns from './sns/index.js';
|
|
7
|
+
export * as ssm from './ssm/index.js';
|
package/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export * as cloudfront from './cloudfront/index.js';
|
|
2
|
+
export * as dynamodb from './dynamodb/index.js';
|
|
3
|
+
export * as ecs from './ecs/index.js';
|
|
4
|
+
export * as lambda from './lambda/index.js';
|
|
5
|
+
export * as s3 from './s3/index.js';
|
|
6
|
+
export * as sns from './sns/index.js';
|
|
7
|
+
export * as ssm from './ssm/index.js';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { InvokeCommand } from '@aws-sdk/client-lambda';
|
|
2
|
+
import { createLogger } from '@vyriy/logger';
|
|
3
|
+
import { client } from './client.js';
|
|
4
|
+
export const invoke = async (functionName, payload, options = {}) => {
|
|
5
|
+
const logger = createLogger();
|
|
6
|
+
logger.info('functionName:', functionName);
|
|
7
|
+
logger.info('payload:', payload);
|
|
8
|
+
logger.info('options:', options);
|
|
9
|
+
const input = {
|
|
10
|
+
FunctionName: functionName,
|
|
11
|
+
Payload: new TextEncoder().encode(payload),
|
|
12
|
+
...options,
|
|
13
|
+
};
|
|
14
|
+
try {
|
|
15
|
+
const result = await client.send(new InvokeCommand(input));
|
|
16
|
+
logger.info('Result:', result);
|
|
17
|
+
return result;
|
|
18
|
+
}
|
|
19
|
+
catch (e) {
|
|
20
|
+
logger.error(e);
|
|
21
|
+
throw e;
|
|
22
|
+
}
|
|
23
|
+
};
|
package/lambda/client.js
ADDED
package/lambda/index.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@vyriy/services",
|
|
3
|
+
"version": "0.1.9",
|
|
4
|
+
"description": "Shared services package for Vyriy projects",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./index.js",
|
|
7
|
+
"dependencies": {
|
|
8
|
+
"@aws-sdk/client-cloudfront": "^3.1045.0",
|
|
9
|
+
"@aws-sdk/client-dynamodb": "^3.1045.0",
|
|
10
|
+
"@aws-sdk/client-ecs": "^3.1045.0",
|
|
11
|
+
"@aws-sdk/client-lambda": "^3.1045.0",
|
|
12
|
+
"@aws-sdk/client-s3": "^3.1045.0",
|
|
13
|
+
"@aws-sdk/client-sns": "^3.1045.0",
|
|
14
|
+
"@aws-sdk/client-ssm": "^3.1045.0",
|
|
15
|
+
"@aws-sdk/lib-dynamodb": "^3.1045.0",
|
|
16
|
+
"@aws-sdk/util-dynamodb": "^3.996.2",
|
|
17
|
+
"@vyriy/env": "0.1.9",
|
|
18
|
+
"@vyriy/error": "0.1.9",
|
|
19
|
+
"@vyriy/logger": "0.1.9",
|
|
20
|
+
"@vyriy/pause": "0.1.9"
|
|
21
|
+
},
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"types": "./index.d.ts",
|
|
24
|
+
"exports": {
|
|
25
|
+
".": {
|
|
26
|
+
"types": "./index.d.ts",
|
|
27
|
+
"import": "./index.js",
|
|
28
|
+
"default": "./index.js"
|
|
29
|
+
},
|
|
30
|
+
"./cloudfront/actions": {
|
|
31
|
+
"types": "./cloudfront/actions.d.ts",
|
|
32
|
+
"import": "./cloudfront/actions.js",
|
|
33
|
+
"default": "./cloudfront/actions.js"
|
|
34
|
+
},
|
|
35
|
+
"./cloudfront/actions.js": {
|
|
36
|
+
"types": "./cloudfront/actions.d.ts",
|
|
37
|
+
"import": "./cloudfront/actions.js",
|
|
38
|
+
"default": "./cloudfront/actions.js"
|
|
39
|
+
},
|
|
40
|
+
"./cloudfront/client": {
|
|
41
|
+
"types": "./cloudfront/client.d.ts",
|
|
42
|
+
"import": "./cloudfront/client.js",
|
|
43
|
+
"default": "./cloudfront/client.js"
|
|
44
|
+
},
|
|
45
|
+
"./cloudfront/client.js": {
|
|
46
|
+
"types": "./cloudfront/client.d.ts",
|
|
47
|
+
"import": "./cloudfront/client.js",
|
|
48
|
+
"default": "./cloudfront/client.js"
|
|
49
|
+
},
|
|
50
|
+
"./cloudfront/index": {
|
|
51
|
+
"types": "./cloudfront/index.d.ts",
|
|
52
|
+
"import": "./cloudfront/index.js",
|
|
53
|
+
"default": "./cloudfront/index.js"
|
|
54
|
+
},
|
|
55
|
+
"./cloudfront/index.js": {
|
|
56
|
+
"types": "./cloudfront/index.d.ts",
|
|
57
|
+
"import": "./cloudfront/index.js",
|
|
58
|
+
"default": "./cloudfront/index.js"
|
|
59
|
+
},
|
|
60
|
+
"./dynamodb/actions": {
|
|
61
|
+
"types": "./dynamodb/actions.d.ts",
|
|
62
|
+
"import": "./dynamodb/actions.js",
|
|
63
|
+
"default": "./dynamodb/actions.js"
|
|
64
|
+
},
|
|
65
|
+
"./dynamodb/actions.js": {
|
|
66
|
+
"types": "./dynamodb/actions.d.ts",
|
|
67
|
+
"import": "./dynamodb/actions.js",
|
|
68
|
+
"default": "./dynamodb/actions.js"
|
|
69
|
+
},
|
|
70
|
+
"./dynamodb/client": {
|
|
71
|
+
"types": "./dynamodb/client.d.ts",
|
|
72
|
+
"import": "./dynamodb/client.js",
|
|
73
|
+
"default": "./dynamodb/client.js"
|
|
74
|
+
},
|
|
75
|
+
"./dynamodb/client.js": {
|
|
76
|
+
"types": "./dynamodb/client.d.ts",
|
|
77
|
+
"import": "./dynamodb/client.js",
|
|
78
|
+
"default": "./dynamodb/client.js"
|
|
79
|
+
},
|
|
80
|
+
"./dynamodb/index": {
|
|
81
|
+
"types": "./dynamodb/index.d.ts",
|
|
82
|
+
"import": "./dynamodb/index.js",
|
|
83
|
+
"default": "./dynamodb/index.js"
|
|
84
|
+
},
|
|
85
|
+
"./dynamodb/index.js": {
|
|
86
|
+
"types": "./dynamodb/index.d.ts",
|
|
87
|
+
"import": "./dynamodb/index.js",
|
|
88
|
+
"default": "./dynamodb/index.js"
|
|
89
|
+
},
|
|
90
|
+
"./ecs/actions": {
|
|
91
|
+
"types": "./ecs/actions.d.ts",
|
|
92
|
+
"import": "./ecs/actions.js",
|
|
93
|
+
"default": "./ecs/actions.js"
|
|
94
|
+
},
|
|
95
|
+
"./ecs/actions.js": {
|
|
96
|
+
"types": "./ecs/actions.d.ts",
|
|
97
|
+
"import": "./ecs/actions.js",
|
|
98
|
+
"default": "./ecs/actions.js"
|
|
99
|
+
},
|
|
100
|
+
"./ecs/client": {
|
|
101
|
+
"types": "./ecs/client.d.ts",
|
|
102
|
+
"import": "./ecs/client.js",
|
|
103
|
+
"default": "./ecs/client.js"
|
|
104
|
+
},
|
|
105
|
+
"./ecs/client.js": {
|
|
106
|
+
"types": "./ecs/client.d.ts",
|
|
107
|
+
"import": "./ecs/client.js",
|
|
108
|
+
"default": "./ecs/client.js"
|
|
109
|
+
},
|
|
110
|
+
"./ecs/index": {
|
|
111
|
+
"types": "./ecs/index.d.ts",
|
|
112
|
+
"import": "./ecs/index.js",
|
|
113
|
+
"default": "./ecs/index.js"
|
|
114
|
+
},
|
|
115
|
+
"./ecs/index.js": {
|
|
116
|
+
"types": "./ecs/index.d.ts",
|
|
117
|
+
"import": "./ecs/index.js",
|
|
118
|
+
"default": "./ecs/index.js"
|
|
119
|
+
},
|
|
120
|
+
"./index": {
|
|
121
|
+
"types": "./index.d.ts",
|
|
122
|
+
"import": "./index.js",
|
|
123
|
+
"default": "./index.js"
|
|
124
|
+
},
|
|
125
|
+
"./index.js": {
|
|
126
|
+
"types": "./index.d.ts",
|
|
127
|
+
"import": "./index.js",
|
|
128
|
+
"default": "./index.js"
|
|
129
|
+
},
|
|
130
|
+
"./lambda/actions": {
|
|
131
|
+
"types": "./lambda/actions.d.ts",
|
|
132
|
+
"import": "./lambda/actions.js",
|
|
133
|
+
"default": "./lambda/actions.js"
|
|
134
|
+
},
|
|
135
|
+
"./lambda/actions.js": {
|
|
136
|
+
"types": "./lambda/actions.d.ts",
|
|
137
|
+
"import": "./lambda/actions.js",
|
|
138
|
+
"default": "./lambda/actions.js"
|
|
139
|
+
},
|
|
140
|
+
"./lambda/client": {
|
|
141
|
+
"types": "./lambda/client.d.ts",
|
|
142
|
+
"import": "./lambda/client.js",
|
|
143
|
+
"default": "./lambda/client.js"
|
|
144
|
+
},
|
|
145
|
+
"./lambda/client.js": {
|
|
146
|
+
"types": "./lambda/client.d.ts",
|
|
147
|
+
"import": "./lambda/client.js",
|
|
148
|
+
"default": "./lambda/client.js"
|
|
149
|
+
},
|
|
150
|
+
"./lambda/index": {
|
|
151
|
+
"types": "./lambda/index.d.ts",
|
|
152
|
+
"import": "./lambda/index.js",
|
|
153
|
+
"default": "./lambda/index.js"
|
|
154
|
+
},
|
|
155
|
+
"./lambda/index.js": {
|
|
156
|
+
"types": "./lambda/index.d.ts",
|
|
157
|
+
"import": "./lambda/index.js",
|
|
158
|
+
"default": "./lambda/index.js"
|
|
159
|
+
},
|
|
160
|
+
"./s3/actions": {
|
|
161
|
+
"types": "./s3/actions.d.ts",
|
|
162
|
+
"import": "./s3/actions.js",
|
|
163
|
+
"default": "./s3/actions.js"
|
|
164
|
+
},
|
|
165
|
+
"./s3/actions.js": {
|
|
166
|
+
"types": "./s3/actions.d.ts",
|
|
167
|
+
"import": "./s3/actions.js",
|
|
168
|
+
"default": "./s3/actions.js"
|
|
169
|
+
},
|
|
170
|
+
"./s3/client": {
|
|
171
|
+
"types": "./s3/client.d.ts",
|
|
172
|
+
"import": "./s3/client.js",
|
|
173
|
+
"default": "./s3/client.js"
|
|
174
|
+
},
|
|
175
|
+
"./s3/client.js": {
|
|
176
|
+
"types": "./s3/client.d.ts",
|
|
177
|
+
"import": "./s3/client.js",
|
|
178
|
+
"default": "./s3/client.js"
|
|
179
|
+
},
|
|
180
|
+
"./s3/index": {
|
|
181
|
+
"types": "./s3/index.d.ts",
|
|
182
|
+
"import": "./s3/index.js",
|
|
183
|
+
"default": "./s3/index.js"
|
|
184
|
+
},
|
|
185
|
+
"./s3/index.js": {
|
|
186
|
+
"types": "./s3/index.d.ts",
|
|
187
|
+
"import": "./s3/index.js",
|
|
188
|
+
"default": "./s3/index.js"
|
|
189
|
+
},
|
|
190
|
+
"./sns/actions": {
|
|
191
|
+
"types": "./sns/actions.d.ts",
|
|
192
|
+
"import": "./sns/actions.js",
|
|
193
|
+
"default": "./sns/actions.js"
|
|
194
|
+
},
|
|
195
|
+
"./sns/actions.js": {
|
|
196
|
+
"types": "./sns/actions.d.ts",
|
|
197
|
+
"import": "./sns/actions.js",
|
|
198
|
+
"default": "./sns/actions.js"
|
|
199
|
+
},
|
|
200
|
+
"./sns/client": {
|
|
201
|
+
"types": "./sns/client.d.ts",
|
|
202
|
+
"import": "./sns/client.js",
|
|
203
|
+
"default": "./sns/client.js"
|
|
204
|
+
},
|
|
205
|
+
"./sns/client.js": {
|
|
206
|
+
"types": "./sns/client.d.ts",
|
|
207
|
+
"import": "./sns/client.js",
|
|
208
|
+
"default": "./sns/client.js"
|
|
209
|
+
},
|
|
210
|
+
"./sns/index": {
|
|
211
|
+
"types": "./sns/index.d.ts",
|
|
212
|
+
"import": "./sns/index.js",
|
|
213
|
+
"default": "./sns/index.js"
|
|
214
|
+
},
|
|
215
|
+
"./sns/index.js": {
|
|
216
|
+
"types": "./sns/index.d.ts",
|
|
217
|
+
"import": "./sns/index.js",
|
|
218
|
+
"default": "./sns/index.js"
|
|
219
|
+
},
|
|
220
|
+
"./ssm/actions": {
|
|
221
|
+
"types": "./ssm/actions.d.ts",
|
|
222
|
+
"import": "./ssm/actions.js",
|
|
223
|
+
"default": "./ssm/actions.js"
|
|
224
|
+
},
|
|
225
|
+
"./ssm/actions.js": {
|
|
226
|
+
"types": "./ssm/actions.d.ts",
|
|
227
|
+
"import": "./ssm/actions.js",
|
|
228
|
+
"default": "./ssm/actions.js"
|
|
229
|
+
},
|
|
230
|
+
"./ssm/client": {
|
|
231
|
+
"types": "./ssm/client.d.ts",
|
|
232
|
+
"import": "./ssm/client.js",
|
|
233
|
+
"default": "./ssm/client.js"
|
|
234
|
+
},
|
|
235
|
+
"./ssm/client.js": {
|
|
236
|
+
"types": "./ssm/client.d.ts",
|
|
237
|
+
"import": "./ssm/client.js",
|
|
238
|
+
"default": "./ssm/client.js"
|
|
239
|
+
},
|
|
240
|
+
"./ssm/index": {
|
|
241
|
+
"types": "./ssm/index.d.ts",
|
|
242
|
+
"import": "./ssm/index.js",
|
|
243
|
+
"default": "./ssm/index.js"
|
|
244
|
+
},
|
|
245
|
+
"./ssm/index.js": {
|
|
246
|
+
"types": "./ssm/index.d.ts",
|
|
247
|
+
"import": "./ssm/index.js",
|
|
248
|
+
"default": "./ssm/index.js"
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
package/s3/actions.d.ts
ADDED
package/s3/actions.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { GetObjectCommand, HeadObjectCommand, PutObjectCommand } from '@aws-sdk/client-s3';
|
|
2
|
+
import { createLogger } from '@vyriy/logger';
|
|
3
|
+
import { toError } from '@vyriy/error';
|
|
4
|
+
import { client } from './client.js';
|
|
5
|
+
export const download = async (bucketName, path, options = {}) => {
|
|
6
|
+
try {
|
|
7
|
+
const logger = createLogger();
|
|
8
|
+
logger.log('GetObjectCommand:', { Bucket: bucketName, Key: path, ...options });
|
|
9
|
+
const response = await client.send(new GetObjectCommand({ Bucket: bucketName, Key: path, ...options }));
|
|
10
|
+
const str = await response.Body?.transformToString();
|
|
11
|
+
logger.log(str);
|
|
12
|
+
return str;
|
|
13
|
+
}
|
|
14
|
+
catch (e) {
|
|
15
|
+
createLogger().error(e);
|
|
16
|
+
throw toError(e);
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
export const upload = async (bucketName, path, body, mimeType = 'application/json;charset=utf-8', options = {}) => {
|
|
20
|
+
try {
|
|
21
|
+
createLogger().log('PutObjectCommand:', {
|
|
22
|
+
Bucket: bucketName,
|
|
23
|
+
Key: path,
|
|
24
|
+
Body: body,
|
|
25
|
+
ContentType: mimeType,
|
|
26
|
+
...options,
|
|
27
|
+
});
|
|
28
|
+
await client.send(new PutObjectCommand({
|
|
29
|
+
Bucket: bucketName,
|
|
30
|
+
Key: path,
|
|
31
|
+
Body: body,
|
|
32
|
+
ContentType: mimeType,
|
|
33
|
+
...options,
|
|
34
|
+
}));
|
|
35
|
+
}
|
|
36
|
+
catch (e) {
|
|
37
|
+
createLogger().error(e);
|
|
38
|
+
throw toError(e);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
export const exists = async (bucketName, path, options = {}) => {
|
|
42
|
+
try {
|
|
43
|
+
createLogger().log('HeadObjectCommand:', {
|
|
44
|
+
Bucket: bucketName,
|
|
45
|
+
Key: path,
|
|
46
|
+
...options,
|
|
47
|
+
});
|
|
48
|
+
const output = await client.send(new HeadObjectCommand({
|
|
49
|
+
Bucket: bucketName,
|
|
50
|
+
Key: path,
|
|
51
|
+
...options,
|
|
52
|
+
}));
|
|
53
|
+
return output.$metadata.httpStatusCode === 200;
|
|
54
|
+
}
|
|
55
|
+
catch (e) {
|
|
56
|
+
createLogger().error(e);
|
|
57
|
+
throw toError(e);
|
|
58
|
+
}
|
|
59
|
+
};
|
package/s3/client.d.ts
ADDED
package/s3/client.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { S3Client } from '@aws-sdk/client-s3';
|
|
2
|
+
import { getRegion, getLocalstackHost, getLocalstackPort, isLocal } from '@vyriy/env';
|
|
3
|
+
const options = isLocal()
|
|
4
|
+
? {
|
|
5
|
+
region: getRegion(),
|
|
6
|
+
endpoint: `http://${getLocalstackHost()}:${getLocalstackPort()}`,
|
|
7
|
+
forcePathStyle: true,
|
|
8
|
+
}
|
|
9
|
+
: {};
|
|
10
|
+
export const client = new S3Client(options);
|
package/s3/index.d.ts
ADDED
package/s3/index.js
ADDED
package/s3/types.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { GetObjectCommandInput, HeadObjectCommandInput, PutObjectCommandInput } from '@aws-sdk/client-s3';
|
|
2
|
+
export type Download = (bucketName: string, path: string, options?: Omit<GetObjectCommandInput, 'Bucket' | 'Key'>) => Promise<string | undefined>;
|
|
3
|
+
export type Upload = (bucketName: string, path: string, body: string | Buffer, mimeType?: string, options?: Omit<PutObjectCommandInput, 'Bucket' | 'Key' | 'Body' | 'ContentType'>) => Promise<void>;
|
|
4
|
+
export type Exists = (bucketName: string, path: string, options?: Omit<HeadObjectCommandInput, 'Bucket' | 'Key' | 'Body' | 'ContentType'>) => Promise<boolean>;
|
package/sns/actions.d.ts
ADDED
package/sns/actions.js
ADDED
package/sns/client.d.ts
ADDED
package/sns/client.js
ADDED
package/sns/index.d.ts
ADDED
package/sns/index.js
ADDED
package/sns/types.d.ts
ADDED
package/ssm/actions.d.ts
ADDED
package/ssm/actions.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { GetParameterCommand, GetParametersCommand } from '@aws-sdk/client-ssm';
|
|
2
|
+
import { createLogger } from '@vyriy/logger';
|
|
3
|
+
import { toError } from '@vyriy/error';
|
|
4
|
+
import { client } from './client.js';
|
|
5
|
+
export const getParameter = async (parameterName, decrypted = true) => {
|
|
6
|
+
try {
|
|
7
|
+
const logger = createLogger();
|
|
8
|
+
logger.log('GetParameterCommand:', parameterName, decrypted);
|
|
9
|
+
const response = await client.send(new GetParameterCommand({ Name: parameterName, WithDecryption: decrypted }));
|
|
10
|
+
const parameter = response.Parameter?.Value || '';
|
|
11
|
+
logger.log(parameter);
|
|
12
|
+
return parameter;
|
|
13
|
+
}
|
|
14
|
+
catch (e) {
|
|
15
|
+
createLogger().error(e);
|
|
16
|
+
throw toError(e);
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
export const getParameters = async (parameterNames, decrypted = true) => {
|
|
20
|
+
try {
|
|
21
|
+
const logger = createLogger();
|
|
22
|
+
logger.log('GetParametersCommand:', parameterNames, decrypted);
|
|
23
|
+
const response = await client.send(new GetParametersCommand({ Names: parameterNames, WithDecryption: decrypted }));
|
|
24
|
+
const parameters = response.Parameters?.reduce((result, { Name, Value }) => {
|
|
25
|
+
if (Name && Value !== undefined) {
|
|
26
|
+
result[Name] = Value;
|
|
27
|
+
}
|
|
28
|
+
return result;
|
|
29
|
+
}, {}) ?? {};
|
|
30
|
+
logger.log(parameters);
|
|
31
|
+
return parameters;
|
|
32
|
+
}
|
|
33
|
+
catch (e) {
|
|
34
|
+
createLogger().error(e);
|
|
35
|
+
throw toError(e);
|
|
36
|
+
}
|
|
37
|
+
};
|
package/ssm/client.d.ts
ADDED
package/ssm/client.js
ADDED
package/ssm/index.d.ts
ADDED
package/ssm/index.js
ADDED
package/ssm/types.d.ts
ADDED