@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.
Files changed (54) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +100 -0
  3. package/cloudfront/actions.d.ts +2 -0
  4. package/cloudfront/actions.js +40 -0
  5. package/cloudfront/client.d.ts +2 -0
  6. package/cloudfront/client.js +2 -0
  7. package/cloudfront/index.d.ts +3 -0
  8. package/cloudfront/index.js +2 -0
  9. package/cloudfront/types.d.ts +1 -0
  10. package/dynamodb/actions.d.ts +9 -0
  11. package/dynamodb/actions.js +131 -0
  12. package/dynamodb/client.d.ts +2 -0
  13. package/dynamodb/client.js +9 -0
  14. package/dynamodb/index.d.ts +3 -0
  15. package/dynamodb/index.js +2 -0
  16. package/dynamodb/types.d.ts +14 -0
  17. package/ecs/actions.d.ts +2 -0
  18. package/ecs/actions.js +50 -0
  19. package/ecs/client.d.ts +2 -0
  20. package/ecs/client.js +4 -0
  21. package/ecs/index.d.ts +3 -0
  22. package/ecs/index.js +2 -0
  23. package/ecs/types.d.ts +4 -0
  24. package/index.d.ts +7 -0
  25. package/index.js +7 -0
  26. package/lambda/actions.d.ts +2 -0
  27. package/lambda/actions.js +23 -0
  28. package/lambda/client.d.ts +2 -0
  29. package/lambda/client.js +4 -0
  30. package/lambda/index.d.ts +3 -0
  31. package/lambda/index.js +2 -0
  32. package/lambda/types.d.ts +2 -0
  33. package/package.json +251 -0
  34. package/s3/actions.d.ts +4 -0
  35. package/s3/actions.js +59 -0
  36. package/s3/client.d.ts +2 -0
  37. package/s3/client.js +10 -0
  38. package/s3/index.d.ts +3 -0
  39. package/s3/index.js +2 -0
  40. package/s3/types.d.ts +4 -0
  41. package/sns/actions.d.ts +2 -0
  42. package/sns/actions.js +8 -0
  43. package/sns/client.d.ts +2 -0
  44. package/sns/client.js +2 -0
  45. package/sns/index.d.ts +3 -0
  46. package/sns/index.js +2 -0
  47. package/sns/types.d.ts +2 -0
  48. package/ssm/actions.d.ts +3 -0
  49. package/ssm/actions.js +37 -0
  50. package/ssm/client.d.ts +2 -0
  51. package/ssm/client.js +2 -0
  52. package/ssm/index.d.ts +3 -0
  53. package/ssm/index.js +2 -0
  54. 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,2 @@
1
+ import type { Invalidate } from './types.js';
2
+ export declare const invalidate: Invalidate;
@@ -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,2 @@
1
+ import { CloudFrontClient } from '@aws-sdk/client-cloudfront';
2
+ export declare const client: CloudFrontClient;
@@ -0,0 +1,2 @@
1
+ import { CloudFrontClient } from '@aws-sdk/client-cloudfront';
2
+ export const client = new CloudFrontClient({});
@@ -0,0 +1,3 @@
1
+ export * from './actions.js';
2
+ export * from './client.js';
3
+ export type * from './types.js';
@@ -0,0 +1,2 @@
1
+ export * from './actions.js';
2
+ export * from './client.js';
@@ -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,2 @@
1
+ import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
2
+ export declare const client: DynamoDBClient;
@@ -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,3 @@
1
+ export * from './actions.js';
2
+ export * from './client.js';
3
+ export type * from './types.js';
@@ -0,0 +1,2 @@
1
+ export * from './actions.js';
2
+ export * from './client.js';
@@ -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>;
@@ -0,0 +1,2 @@
1
+ import type { RunTask } from './types.js';
2
+ export declare const runTask: RunTask;
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
+ };
@@ -0,0 +1,2 @@
1
+ import { ECSClient } from '@aws-sdk/client-ecs';
2
+ export declare const client: ECSClient;
package/ecs/client.js ADDED
@@ -0,0 +1,4 @@
1
+ import { ECSClient } from '@aws-sdk/client-ecs';
2
+ import { getRegion, isLocal } from '@vyriy/env';
3
+ const options = isLocal() ? { region: getRegion() } : {};
4
+ export const client = new ECSClient(options);
package/ecs/index.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ export * from './actions.js';
2
+ export * from './client.js';
3
+ export type * from './types.js';
package/ecs/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export * from './actions.js';
2
+ export * from './client.js';
package/ecs/types.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ export type RunTask = (task: string, environment?: {
2
+ name: string;
3
+ value: string;
4
+ }[], taskDefinition?: string) => Promise<void>;
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,2 @@
1
+ import type { Invoke } from './types.js';
2
+ export declare const invoke: Invoke;
@@ -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
+ };
@@ -0,0 +1,2 @@
1
+ import { LambdaClient } from '@aws-sdk/client-lambda';
2
+ export declare const client: LambdaClient;
@@ -0,0 +1,4 @@
1
+ import { LambdaClient } from '@aws-sdk/client-lambda';
2
+ import { getRegion } from '@vyriy/env';
3
+ const options = { region: getRegion() };
4
+ export const client = new LambdaClient(options);
@@ -0,0 +1,3 @@
1
+ export * from './actions.js';
2
+ export * from './client.js';
3
+ export type * from './types.js';
@@ -0,0 +1,2 @@
1
+ export * from './actions.js';
2
+ export * from './client.js';
@@ -0,0 +1,2 @@
1
+ import type { InvokeCommandInput, InvokeCommandOutput } from '@aws-sdk/client-lambda';
2
+ export type Invoke = (functionName: string, payload: string, options?: Omit<InvokeCommandInput, 'FunctionName' | 'Payload'>) => Promise<InvokeCommandOutput>;
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
+ }
@@ -0,0 +1,4 @@
1
+ import type { Download, Exists, Upload } from './types.js';
2
+ export declare const download: Download;
3
+ export declare const upload: Upload;
4
+ export declare const exists: Exists;
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
@@ -0,0 +1,2 @@
1
+ import { S3Client } from '@aws-sdk/client-s3';
2
+ export declare const client: S3Client;
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
@@ -0,0 +1,3 @@
1
+ export * from './actions.js';
2
+ export * from './client.js';
3
+ export type * from './types.js';
package/s3/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export * from './actions.js';
2
+ export * from './client.js';
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>;
@@ -0,0 +1,2 @@
1
+ import type { Publish } from './types.js';
2
+ export declare const publish: Publish;
package/sns/actions.js ADDED
@@ -0,0 +1,8 @@
1
+ import { client } from './client.js';
2
+ export const publish = async (topicArn, message, options = {}) => {
3
+ await client.publish({
4
+ TopicArn: topicArn,
5
+ Message: message,
6
+ ...options,
7
+ });
8
+ };
@@ -0,0 +1,2 @@
1
+ import { SNS } from '@aws-sdk/client-sns';
2
+ export declare const client: SNS;
package/sns/client.js ADDED
@@ -0,0 +1,2 @@
1
+ import { SNS } from '@aws-sdk/client-sns';
2
+ export const client = new SNS({});
package/sns/index.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ export * from './actions.js';
2
+ export * from './client.js';
3
+ export type * from './types.js';
package/sns/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export * from './actions.js';
2
+ export * from './client.js';
package/sns/types.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ import type { PublishCommandInput } from '@aws-sdk/client-sns';
2
+ export type Publish = (topicArn: string, message: string, options?: Omit<PublishCommandInput, 'TopicArn' | 'Message'>) => Promise<void>;
@@ -0,0 +1,3 @@
1
+ import type { GetParameter, GetParameters } from './types.js';
2
+ export declare const getParameter: GetParameter;
3
+ export declare const getParameters: GetParameters;
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
+ };
@@ -0,0 +1,2 @@
1
+ import { SSMClient } from '@aws-sdk/client-ssm';
2
+ export declare const client: SSMClient;
package/ssm/client.js ADDED
@@ -0,0 +1,2 @@
1
+ import { SSMClient } from '@aws-sdk/client-ssm';
2
+ export const client = new SSMClient({});
package/ssm/index.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ export * from './actions.js';
2
+ export * from './client.js';
3
+ export type * from './types.js';
package/ssm/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export * from './actions.js';
2
+ export * from './client.js';
package/ssm/types.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export type GetParameter = (parameterName: string, decrypted?: boolean) => Promise<string>;
2
+ export type GetParameters = (parameterNames: string[], decrypted?: boolean) => Promise<Record<string, string>>;