ag-common 0.0.733 → 0.0.735

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.
@@ -7,7 +7,7 @@ const ses_1 = require("./ses");
7
7
  const sqs_1 = require("./sqs");
8
8
  const setAwsRegion = (region) => {
9
9
  (0, dynamo_1.setDynamo)(region);
10
- (0, s3_1.setS3)(region);
10
+ (0, s3_1.setS3)({ region, provider: 's3' });
11
11
  (0, ses_1.setSes)(region);
12
12
  (0, sqs_1.setSqs)(region);
13
13
  };
@@ -0,0 +1,13 @@
1
+ import type { DynamoDBResult } from './types';
2
+ export declare const batchDelete: (params: {
3
+ tableName: string;
4
+ keys: string[];
5
+ pkName: string;
6
+ opt?: {
7
+ /** default 20 */
8
+ batchSize?: number;
9
+ /** option to always retry on 429 until done. default false */
10
+ alwaysRetry?: boolean;
11
+ };
12
+ }) => Promise<DynamoDBResult<void>>;
13
+ export declare const wipeTable: (tableName: string) => Promise<DynamoDBResult<void>>;
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __asyncValues = (this && this.__asyncValues) || function (o) {
12
+ if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
13
+ var m = o[Symbol.asyncIterator], i;
14
+ return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
15
+ function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
16
+ function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
17
+ };
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.wipeTable = exports.batchDelete = void 0;
20
+ const lib_dynamodb_1 = require("@aws-sdk/lib-dynamodb");
21
+ const array_1 = require("../../../common/helpers/array");
22
+ const async_1 = require("../../../common/helpers/async");
23
+ const withRetry_1 = require("../withRetry");
24
+ const _1 = require(".");
25
+ const get_1 = require("./get");
26
+ const batchDelete = (params) => __awaiter(void 0, void 0, void 0, function* () {
27
+ var _a;
28
+ try {
29
+ const { batchSize = 20, alwaysRetry = false } = (_a = params.opt) !== null && _a !== void 0 ? _a : {};
30
+ const chunked = (0, array_1.chunk)(params.keys, batchSize);
31
+ let processed = 0;
32
+ yield (0, async_1.asyncForEach)(chunked, (chunk) => __awaiter(void 0, void 0, void 0, function* () {
33
+ const command = new lib_dynamodb_1.BatchWriteCommand({
34
+ RequestItems: {
35
+ [params.tableName]: chunk.map((key) => ({
36
+ DeleteRequest: { Key: { [params.pkName]: key } },
37
+ })),
38
+ },
39
+ });
40
+ yield (0, withRetry_1.withRetry)(() => _1.dynamoDb.send(command), `batchdelete ${processed}/${params.keys.length}. size=${batchSize}`, {
41
+ maxRetries: alwaysRetry ? null : undefined,
42
+ });
43
+ processed += chunk.length;
44
+ }));
45
+ return { data: undefined };
46
+ }
47
+ catch (e) {
48
+ return { error: e.toString() };
49
+ }
50
+ });
51
+ exports.batchDelete = batchDelete;
52
+ const wipeTable = (tableName) => __awaiter(void 0, void 0, void 0, function* () {
53
+ var _a, e_1, _b, _c;
54
+ try {
55
+ const generator = (0, get_1.scanWithGenerator)(tableName, {
56
+ BATCH_SIZE: 100, // Process in chunks of 100 items
57
+ alwaysRetry: true, // Always retry on 429 since we want to ensure complete deletion
58
+ });
59
+ try {
60
+ // Process each batch of items
61
+ for (var _d = true, generator_1 = __asyncValues(generator), generator_1_1; generator_1_1 = yield generator_1.next(), _a = generator_1_1.done, !_a; _d = true) {
62
+ _c = generator_1_1.value;
63
+ _d = false;
64
+ const batch = _c;
65
+ const pks = batch.map((item) => item.PK);
66
+ if (pks.length > 0) {
67
+ const result = yield (0, exports.batchDelete)({
68
+ tableName,
69
+ keys: pks,
70
+ pkName: 'PK',
71
+ opt: {
72
+ alwaysRetry: true, // Always retry on 429 since we want to ensure complete deletion
73
+ },
74
+ });
75
+ if ('error' in result) {
76
+ return result;
77
+ }
78
+ }
79
+ }
80
+ }
81
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
82
+ finally {
83
+ try {
84
+ if (!_d && !_a && (_b = generator_1.return)) yield _b.call(generator_1);
85
+ }
86
+ finally { if (e_1) throw e_1.error; }
87
+ }
88
+ return { data: undefined };
89
+ }
90
+ catch (e) {
91
+ return { error: e.toString() };
92
+ }
93
+ });
94
+ exports.wipeTable = wipeTable;
@@ -0,0 +1,30 @@
1
+ import type { Key } from '../../types';
2
+ import type { DynamoDBResult } from './types';
3
+ import type { DynamoQueryParams, ScanOptions } from './types';
4
+ export declare const getItemsDynamo: <T>(params: {
5
+ tableName: string;
6
+ items: {
7
+ pkName: string;
8
+ pkValue: string;
9
+ }[];
10
+ }) => Promise<DynamoDBResult<T[]>>;
11
+ export declare const getItemDynamo: <T>(params: {
12
+ tableName: string;
13
+ pkName: string;
14
+ pkValue: string;
15
+ }) => Promise<DynamoDBResult<T>>;
16
+ export declare const queryDynamo: <T>(params: DynamoQueryParams) => Promise<{
17
+ data: T[];
18
+ startKey?: Key;
19
+ } | {
20
+ error: string;
21
+ }>;
22
+ export declare const scan: <T>(tableName: string, options?: ScanOptions) => Promise<DynamoDBResult<T[]>>;
23
+ export declare function queryWithGenerator<T>(params: DynamoQueryParams & {
24
+ /** how many to return in query generator. default 100 */
25
+ BATCH_SIZE?: number;
26
+ }): AsyncGenerator<T[], void, unknown>;
27
+ export declare function scanWithGenerator<T>(tableName: string, options?: ScanOptions & {
28
+ /** how many to return in scan generator. default 100 */
29
+ BATCH_SIZE?: number;
30
+ }): AsyncGenerator<T[], void, unknown>;
@@ -0,0 +1,229 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
12
+ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
13
+ if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
14
+ var g = generator.apply(thisArg, _arguments || []), i, q = [];
15
+ return i = Object.create((typeof AsyncIterator === "function" ? AsyncIterator : Object).prototype), verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;
16
+ function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }
17
+ function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }
18
+ function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
19
+ function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
20
+ function fulfill(value) { resume("next", value); }
21
+ function reject(value) { resume("throw", value); }
22
+ function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
23
+ };
24
+ Object.defineProperty(exports, "__esModule", { value: true });
25
+ exports.scan = exports.queryDynamo = exports.getItemDynamo = exports.getItemsDynamo = void 0;
26
+ exports.queryWithGenerator = queryWithGenerator;
27
+ exports.scanWithGenerator = scanWithGenerator;
28
+ /* eslint-disable no-await-in-loop */
29
+ const lib_dynamodb_1 = require("@aws-sdk/lib-dynamodb");
30
+ const withRetry_1 = require("../withRetry");
31
+ const _1 = require(".");
32
+ const isError = (result) => 'error' in result;
33
+ /**
34
+ * Helper function that builds the query parameters and executes the query
35
+ */
36
+ const executeQuery = (params, startKey) => __awaiter(void 0, void 0, void 0, function* () {
37
+ var _a, _b, _c, _d, _e;
38
+ let kce = `#${params.pkName.toLowerCase()} ${(_a = params.pkOperator) !== null && _a !== void 0 ? _a : '='} :${params.pkName.toLowerCase()}`;
39
+ const ean = {
40
+ [`#${params.pkName.toLowerCase()}`]: params.pkName,
41
+ };
42
+ const eav = {
43
+ [`:${params.pkName.toLowerCase()}`]: params.pkValue,
44
+ };
45
+ if (params.skName && params.skValue !== undefined) {
46
+ const { skName, skValue, skOperator = '=' } = params;
47
+ if (skOperator === 'BETWEEN' && Array.isArray(skValue)) {
48
+ const [start, end] = skValue;
49
+ kce += ` AND #${skName.toLowerCase()} BETWEEN :${skName}1 AND :${skName}2`;
50
+ ean[`#${skName.toLowerCase()}`] = skName;
51
+ eav[`:${skName}1`] = start;
52
+ eav[`:${skName}2`] = end;
53
+ }
54
+ else if (skOperator === 'BEGINS_WITH') {
55
+ kce += ` AND begins_with(#${skName.toLowerCase()}, :${skName.toLowerCase()})`;
56
+ ean[`#${skName.toLowerCase()}`] = skName;
57
+ eav[`:${skName.toLowerCase()}`] = skValue;
58
+ }
59
+ else {
60
+ kce += ` AND #${skName.toLowerCase()} ${skOperator} :${skName.toLowerCase()}`;
61
+ ean[`#${skName.toLowerCase()}`] = skName;
62
+ eav[`:${skName.toLowerCase()}`] = skValue;
63
+ }
64
+ }
65
+ const queryParams = new lib_dynamodb_1.QueryCommand(Object.assign({ TableName: params.tableName, KeyConditionExpression: kce, ExpressionAttributeNames: Object.assign(Object.assign({}, ean), (_b = params.filter) === null || _b === void 0 ? void 0 : _b.attrNames), ExpressionAttributeValues: Object.assign(Object.assign({}, eav), (_c = params.filter) === null || _c === void 0 ? void 0 : _c.attrValues), ScanIndexForward: (_d = params.sortAscending) !== null && _d !== void 0 ? _d : true, Limit: (_e = params.BATCH_SIZE) !== null && _e !== void 0 ? _e : params.limit, IndexName: params.indexName, ExclusiveStartKey: startKey }, (params.filter && Object.assign({ FilterExpression: params.filter.filterExpression }, (params.filter.attrValues && {
66
+ ExpressionAttributeValues: Object.assign(Object.assign({}, eav), params.filter.attrValues),
67
+ })))));
68
+ // eslint-disable-next-line no-return-await
69
+ return yield (0, withRetry_1.withRetry)(() => _1.dynamoDb.send(queryParams), 'queryDynamo');
70
+ });
71
+ /**
72
+ * Helper function that builds the scan parameters and executes the scan
73
+ */
74
+ const executeScan = (tableName, options, exclusiveStartKey) => __awaiter(void 0, void 0, void 0, function* () {
75
+ var _a, _b;
76
+ const projectionAttrs = (_a = options === null || options === void 0 ? void 0 : options.requiredAttributeList) === null || _a === void 0 ? void 0 : _a.reduce((acc, attr, index) => {
77
+ acc[`#proj${index}`] = attr;
78
+ return acc;
79
+ }, {});
80
+ const expressionAttributeNames = Object.assign(Object.assign({}, projectionAttrs), (_b = options === null || options === void 0 ? void 0 : options.filter) === null || _b === void 0 ? void 0 : _b.attrNames);
81
+ const params = new lib_dynamodb_1.ScanCommand(Object.assign(Object.assign(Object.assign(Object.assign({ TableName: tableName, IndexName: options === null || options === void 0 ? void 0 : options.indexName, Limit: options === null || options === void 0 ? void 0 : options.BATCH_SIZE }, ((options === null || options === void 0 ? void 0 : options.filter) && Object.assign({ FilterExpression: options.filter.filterExpression }, (options.filter.attrValues && {
82
+ ExpressionAttributeValues: options.filter.attrValues,
83
+ })))), (Object.keys(expressionAttributeNames).length > 0 && {
84
+ ExpressionAttributeNames: expressionAttributeNames,
85
+ })), ((options === null || options === void 0 ? void 0 : options.requiredAttributeList) && {
86
+ ProjectionExpression: options.requiredAttributeList
87
+ .map((_, index) => `#proj${index}`)
88
+ .join(', '),
89
+ })), { ExclusiveStartKey: exclusiveStartKey }));
90
+ // eslint-disable-next-line no-return-await
91
+ return yield (0, withRetry_1.withRetry)(() => _1.dynamoDb.send(params), `scan. already seen=${exclusiveStartKey ? 'some' : '0'} items`, {
92
+ maxRetries: (options === null || options === void 0 ? void 0 : options.alwaysRetry) ? null : undefined,
93
+ });
94
+ });
95
+ const getItemsDynamo = (params) => __awaiter(void 0, void 0, void 0, function* () {
96
+ var _a, _b;
97
+ try {
98
+ const command = new lib_dynamodb_1.BatchGetCommand({
99
+ RequestItems: {
100
+ [params.tableName]: {
101
+ Keys: params.items.map(({ pkName, pkValue }) => ({
102
+ [pkName]: pkValue,
103
+ })),
104
+ },
105
+ },
106
+ });
107
+ const result = yield (0, withRetry_1.withRetry)(() => _1.dynamoDb.send(command), 'getItemsDynamo');
108
+ return {
109
+ data: (_b = (_a = result.Responses) === null || _a === void 0 ? void 0 : _a[params.tableName]) !== null && _b !== void 0 ? _b : [],
110
+ };
111
+ }
112
+ catch (e) {
113
+ return { error: e.toString() };
114
+ }
115
+ });
116
+ exports.getItemsDynamo = getItemsDynamo;
117
+ const getItemDynamo = (params) => __awaiter(void 0, void 0, void 0, function* () {
118
+ const result = yield (0, exports.getItemsDynamo)({
119
+ tableName: params.tableName,
120
+ items: [{ pkName: params.pkName, pkValue: params.pkValue }],
121
+ });
122
+ if (isError(result)) {
123
+ return result;
124
+ }
125
+ return { data: result.data[0] };
126
+ });
127
+ exports.getItemDynamo = getItemDynamo;
128
+ const queryDynamo = (params) => __awaiter(void 0, void 0, void 0, function* () {
129
+ try {
130
+ const items = [];
131
+ let startKey;
132
+ do {
133
+ const result = yield executeQuery(params, startKey);
134
+ if (result.Items) {
135
+ items.push(...result.Items);
136
+ }
137
+ startKey = result.LastEvaluatedKey;
138
+ if (params.limit && items.length >= params.limit) {
139
+ return {
140
+ data: items.slice(0, params.limit),
141
+ startKey,
142
+ };
143
+ }
144
+ } while (startKey && Object.keys(startKey).length > 0);
145
+ return { data: items };
146
+ }
147
+ catch (e) {
148
+ return { error: e.toString() };
149
+ }
150
+ });
151
+ exports.queryDynamo = queryDynamo;
152
+ const scan = (tableName, options) => __awaiter(void 0, void 0, void 0, function* () {
153
+ try {
154
+ const Items = [];
155
+ let ExclusiveStartKey;
156
+ do {
157
+ const result = yield executeScan(tableName, options, ExclusiveStartKey);
158
+ if (result.Items) {
159
+ Items.push(...result.Items);
160
+ }
161
+ ExclusiveStartKey = result.LastEvaluatedKey;
162
+ } while (ExclusiveStartKey);
163
+ return { data: Items };
164
+ }
165
+ catch (e) {
166
+ return { error: e.toString() };
167
+ }
168
+ });
169
+ exports.scan = scan;
170
+ function queryWithGenerator(params) {
171
+ return __asyncGenerator(this, arguments, function* queryWithGenerator_1() {
172
+ var _a;
173
+ const BATCH_SIZE = (_a = params.BATCH_SIZE) !== null && _a !== void 0 ? _a : 100;
174
+ let items = [];
175
+ let startKey;
176
+ try {
177
+ do {
178
+ const result = yield __await(executeQuery(params, startKey));
179
+ if (result.Items) {
180
+ items.push(...result.Items);
181
+ // Process items in chunks of BATCH_SIZE
182
+ while (items.length >= BATCH_SIZE) {
183
+ const batch = items.slice(0, BATCH_SIZE);
184
+ items = items.slice(BATCH_SIZE);
185
+ yield yield __await(batch);
186
+ }
187
+ }
188
+ startKey = result.LastEvaluatedKey;
189
+ } while (startKey && Object.keys(startKey).length > 0);
190
+ // Yield any remaining items
191
+ if (items.length > 0) {
192
+ yield yield __await(items);
193
+ }
194
+ }
195
+ catch (e) {
196
+ throw new Error(`Query generator error: ${e.toString()}`);
197
+ }
198
+ });
199
+ }
200
+ function scanWithGenerator(tableName, options) {
201
+ return __asyncGenerator(this, arguments, function* scanWithGenerator_1() {
202
+ var _a;
203
+ const BATCH_SIZE = (_a = options === null || options === void 0 ? void 0 : options.BATCH_SIZE) !== null && _a !== void 0 ? _a : 100;
204
+ let items = [];
205
+ let exclusiveStartKey;
206
+ try {
207
+ do {
208
+ const result = yield __await(executeScan(tableName, options, exclusiveStartKey));
209
+ if (result.Items) {
210
+ items.push(...result.Items);
211
+ // Process items in chunks of BATCH_SIZE
212
+ while (items.length >= BATCH_SIZE) {
213
+ const batch = items.slice(0, BATCH_SIZE);
214
+ items = items.slice(BATCH_SIZE);
215
+ yield yield __await(batch);
216
+ }
217
+ }
218
+ exclusiveStartKey = result.LastEvaluatedKey;
219
+ } while (exclusiveStartKey);
220
+ // Yield any remaining items
221
+ if (items.length > 0) {
222
+ yield yield __await(items);
223
+ }
224
+ }
225
+ catch (e) {
226
+ throw new Error(`Scan generator error: ${e.toString()}`);
227
+ }
228
+ });
229
+ }
@@ -0,0 +1,50 @@
1
+ import { DynamoDBDocument } from '@aws-sdk/lib-dynamodb';
2
+ import type { AwsCredentialIdentity } from '@smithy/types';
3
+ import * as getOps from './get';
4
+ export declare let dynamoDb: DynamoDBDocument;
5
+ /**
6
+ * Sets up the DynamoDB client with the specified region and credentials.
7
+ * @param region - AWS region to connect to
8
+ * @param credentials - Optional AWS credentials
9
+ * @returns Configured DynamoDBDocument client
10
+ */
11
+ export declare const setDynamo: (region: string, credentials?: AwsCredentialIdentity) => DynamoDBDocument;
12
+ export declare const getItemDynamo: <T>(params: {
13
+ tableName: string;
14
+ pkName: string;
15
+ pkValue: string;
16
+ }) => Promise<import("./types").DynamoDBResult<T>>, getItemsDynamo: <T>(params: {
17
+ tableName: string;
18
+ items: {
19
+ pkName: string;
20
+ pkValue: string;
21
+ }[];
22
+ }) => Promise<import("./types").DynamoDBResult<T[]>>, queryDynamo: <T>(params: import("./types").DynamoQueryParams) => Promise<{
23
+ data: T[];
24
+ startKey?: import("../..").Key;
25
+ } | {
26
+ error: string;
27
+ }>, queryWithGenerator: typeof getOps.queryWithGenerator, scan: <T>(tableName: string, options?: import("./types").ScanOptions) => Promise<import("./types").DynamoDBResult<T[]>>, scanWithGenerator: typeof getOps.scanWithGenerator;
28
+ export declare const putDynamo: <T extends Record<string, unknown>>(item: T, tableName: string, opt?: {
29
+ pkName?: string;
30
+ }) => Promise<import("./types").DynamoDBResult<void>>, batchWrite: <T extends Record<string, unknown>>(tableName: string, items: T[], opt?: {
31
+ alwaysRetry?: boolean;
32
+ batchSize?: number;
33
+ }) => Promise<import("./types").DynamoDBResult<void>>, getDynamoUpdates: <T extends Record<string, unknown>>(item: T, options?: {
34
+ excludeKeys?: string[];
35
+ }) => {
36
+ UpdateExpression: string;
37
+ ExpressionAttributeNames: Record<string, string>;
38
+ ExpressionAttributeValues: Record<string, unknown>;
39
+ ReturnValues: "UPDATED_NEW";
40
+ };
41
+ export declare const batchDelete: (params: {
42
+ tableName: string;
43
+ keys: string[];
44
+ pkName: string;
45
+ opt?: {
46
+ batchSize?: number;
47
+ alwaysRetry?: boolean;
48
+ };
49
+ }) => Promise<import("./types").DynamoDBResult<void>>, wipeTable: (tableName: string) => Promise<import("./types").DynamoDBResult<void>>;
50
+ export * from './types';
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
36
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.wipeTable = exports.batchDelete = exports.getDynamoUpdates = exports.batchWrite = exports.putDynamo = exports.scanWithGenerator = exports.scan = exports.queryWithGenerator = exports.queryDynamo = exports.getItemsDynamo = exports.getItemDynamo = exports.setDynamo = exports.dynamoDb = void 0;
40
+ const client_dynamodb_1 = require("@aws-sdk/client-dynamodb");
41
+ const lib_dynamodb_1 = require("@aws-sdk/lib-dynamodb");
42
+ const deleteOps = __importStar(require("./delete"));
43
+ const getOps = __importStar(require("./get"));
44
+ const setOps = __importStar(require("./set"));
45
+ /**
46
+ * Sets up the DynamoDB client with the specified region and credentials.
47
+ * @param region - AWS region to connect to
48
+ * @param credentials - Optional AWS credentials
49
+ * @returns Configured DynamoDBDocument client
50
+ */
51
+ const setDynamo = (region, credentials) => {
52
+ const client = new client_dynamodb_1.DynamoDBClient({ region, credentials });
53
+ exports.dynamoDb = lib_dynamodb_1.DynamoDBDocument.from(client, {
54
+ marshallOptions: { removeUndefinedValues: true },
55
+ });
56
+ return exports.dynamoDb;
57
+ };
58
+ exports.setDynamo = setDynamo;
59
+ // Initialize with default region
60
+ exports.dynamoDb = (0, exports.setDynamo)('ap-southeast-2');
61
+ // Export all operations
62
+ exports.getItemDynamo = getOps.getItemDynamo, exports.getItemsDynamo = getOps.getItemsDynamo, exports.queryDynamo = getOps.queryDynamo, exports.queryWithGenerator = getOps.queryWithGenerator, exports.scan = getOps.scan, exports.scanWithGenerator = getOps.scanWithGenerator;
63
+ exports.putDynamo = setOps.putDynamo, exports.batchWrite = setOps.batchWrite, exports.getDynamoUpdates = setOps.getDynamoUpdates;
64
+ exports.batchDelete = deleteOps.batchDelete, exports.wipeTable = deleteOps.wipeTable;
65
+ // Export types
66
+ __exportStar(require("./types"), exports);
@@ -0,0 +1,18 @@
1
+ import type { DynamoDBResult } from './types';
2
+ export declare const putDynamo: <T extends Record<string, unknown>>(item: T, tableName: string, opt?: {
3
+ pkName?: string;
4
+ }) => Promise<DynamoDBResult<void>>;
5
+ export declare const batchWrite: <T extends Record<string, unknown>>(tableName: string, items: T[], opt?: {
6
+ /** option to always retry on 429 until done */
7
+ alwaysRetry?: boolean;
8
+ /** default 20 */
9
+ batchSize?: number;
10
+ }) => Promise<DynamoDBResult<void>>;
11
+ export declare const getDynamoUpdates: <T extends Record<string, unknown>>(item: T, options?: {
12
+ excludeKeys?: string[];
13
+ }) => {
14
+ UpdateExpression: string;
15
+ ExpressionAttributeNames: Record<string, string>;
16
+ ExpressionAttributeValues: Record<string, unknown>;
17
+ ReturnValues: "UPDATED_NEW";
18
+ };
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.getDynamoUpdates = exports.batchWrite = exports.putDynamo = void 0;
13
+ const lib_dynamodb_1 = require("@aws-sdk/lib-dynamodb");
14
+ const array_1 = require("../../../common/helpers/array");
15
+ const async_1 = require("../../../common/helpers/async");
16
+ const withRetry_1 = require("../withRetry");
17
+ const _1 = require(".");
18
+ const putDynamo = (item, tableName, opt) => __awaiter(void 0, void 0, void 0, function* () {
19
+ const params = new lib_dynamodb_1.PutCommand(Object.assign({ TableName: tableName, Item: item }, ((opt === null || opt === void 0 ? void 0 : opt.pkName) && {
20
+ ConditionExpression: `attribute_not_exists(${opt.pkName})`,
21
+ })));
22
+ try {
23
+ yield (0, withRetry_1.withRetry)(() => _1.dynamoDb.send(params), 'putDynamo');
24
+ return { data: undefined };
25
+ }
26
+ catch (e) {
27
+ return { error: e.toString() };
28
+ }
29
+ });
30
+ exports.putDynamo = putDynamo;
31
+ const batchWrite = (tableName, items, opt) => __awaiter(void 0, void 0, void 0, function* () {
32
+ try {
33
+ const { batchSize = 20 } = opt !== null && opt !== void 0 ? opt : {};
34
+ let processed = 0;
35
+ const chunked = (0, array_1.chunk)(items, batchSize);
36
+ yield (0, async_1.asyncForEach)(chunked, (chunk) => __awaiter(void 0, void 0, void 0, function* () {
37
+ const params = new lib_dynamodb_1.BatchWriteCommand({
38
+ RequestItems: {
39
+ [tableName]: chunk.map((Item) => ({ PutRequest: { Item } })),
40
+ },
41
+ });
42
+ yield (0, withRetry_1.withRetry)(() => _1.dynamoDb.send(params), `batchwrite ${processed}/${items.length}. size=${batchSize}`, {
43
+ maxRetries: (opt === null || opt === void 0 ? void 0 : opt.alwaysRetry) ? null : undefined,
44
+ });
45
+ processed += chunk.length;
46
+ }));
47
+ return { data: undefined };
48
+ }
49
+ catch (e) {
50
+ return { error: e.toString() };
51
+ }
52
+ });
53
+ exports.batchWrite = batchWrite;
54
+ const getDynamoUpdates = (item, options) => {
55
+ var _a;
56
+ const excludeKeys = ((_a = options === null || options === void 0 ? void 0 : options.excludeKeys) !== null && _a !== void 0 ? _a : ['PK']).map((k) => k.toLowerCase());
57
+ const validEntries = Object.entries(item).filter(([key, value]) => !excludeKeys.includes(key.toLowerCase()) && value != null);
58
+ const ExpressionAttributeNames = {};
59
+ const ExpressionAttributeValues = {};
60
+ const UpdateExpression = validEntries.reduce((expr, [key, value], index) => {
61
+ ExpressionAttributeNames[`#${key}`] = key;
62
+ ExpressionAttributeValues[`:${key}`] = value;
63
+ return `${expr}${index > 0 ? ', ' : ''}#${key} = :${key}`;
64
+ }, 'SET ');
65
+ return {
66
+ UpdateExpression,
67
+ ExpressionAttributeNames,
68
+ ExpressionAttributeValues,
69
+ ReturnValues: 'UPDATED_NEW',
70
+ };
71
+ };
72
+ exports.getDynamoUpdates = getDynamoUpdates;
@@ -0,0 +1,43 @@
1
+ import type { Key } from '../../types';
2
+ export type DynamoDBError = {
3
+ error: string;
4
+ };
5
+ export type DynamoDBSuccess<T> = {
6
+ data: T;
7
+ };
8
+ export type DynamoDBResult<T> = DynamoDBSuccess<T> | DynamoDBError;
9
+ export interface DynamoFilter {
10
+ filterExpression: string;
11
+ attrNames: Record<string, string>;
12
+ attrValues?: Record<string, unknown>;
13
+ }
14
+ export interface ScanOptions {
15
+ /** eg
16
+ * filter: {
17
+ filterExpression: '#feedIcon = :empty',
18
+ attrNames: { '#feedIcon': 'feedIcon' },
19
+ attrValues: {
20
+ ':empty': '',
21
+ },
22
+ },
23
+ */
24
+ filter?: DynamoFilter;
25
+ requiredAttributeList?: string[];
26
+ indexName?: string;
27
+ alwaysRetry?: boolean;
28
+ }
29
+ export interface DynamoQueryParams {
30
+ tableName: string;
31
+ pkName: string;
32
+ pkValue: string | number;
33
+ pkOperator?: '=' | '<' | '>' | '<=' | '>=';
34
+ skName?: string;
35
+ skValue?: string | number | [string | number, string | number];
36
+ skOperator?: '=' | '<' | '>' | '<=' | '>=' | 'BETWEEN' | 'BEGINS_WITH';
37
+ indexName?: string;
38
+ limit?: number;
39
+ startKey?: Key;
40
+ filter?: DynamoFilter;
41
+ sortAscending?: boolean;
42
+ }
43
+ export declare const isError: <T>(result: DynamoDBResult<T>) => result is DynamoDBError;
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isError = void 0;
4
+ const isError = (result) => 'error' in result;
5
+ exports.isError = isError;
@@ -1,7 +1,15 @@
1
1
  import { S3Client } from '@aws-sdk/client-s3';
2
2
  import type { StreamingBlobPayloadOutputTypes } from '@smithy/types';
3
3
  import type { Buffer } from 'buffer';
4
- export declare const setS3: (region: string) => S3Client;
4
+ export type StorageProvider = 's3' | 'r2';
5
+ export interface StorageConfig {
6
+ provider: StorageProvider;
7
+ region: string;
8
+ endpoint?: string;
9
+ accountId?: string;
10
+ }
11
+ export declare const createStorageClient: (config: StorageConfig) => S3Client;
12
+ export declare const setS3: (config: StorageConfig) => S3Client;
5
13
  export declare const s3: S3Client;
6
14
  export declare const getS3Object: ({ fileurl: { Bucket, Key }, }: {
7
15
  fileurl: {