@moicky/dynamodb 1.3.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/lib/client.d.ts +2 -50
- package/dist/lib/client.js +13 -89
- package/dist/lib/defaultArguments.d.ts +19 -0
- package/dist/lib/defaultArguments.js +17 -0
- package/dist/lib/fixes.d.ts +23 -0
- package/dist/lib/fixes.js +38 -0
- package/dist/lib/helpers.js +5 -5
- package/dist/lib/index.d.ts +5 -0
- package/dist/lib/index.js +21 -0
- package/dist/lib/schemas.d.ts +13 -0
- package/dist/lib/schemas.js +63 -0
- package/dist/operations/delete.js +10 -11
- package/dist/operations/get.js +18 -20
- package/dist/operations/misc.js +13 -6
- package/dist/operations/put.js +11 -13
- package/dist/operations/query.js +15 -16
- package/dist/operations/update.js +15 -17
- package/package.json +1 -1
- package/readme.md +58 -23
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from "./lib
|
|
1
|
+
export * from "./lib";
|
|
2
2
|
export * from "./operations";
|
package/dist/index.js
CHANGED
|
@@ -14,5 +14,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./lib
|
|
17
|
+
__exportStar(require("./lib"), exports);
|
|
18
18
|
__exportStar(require("./operations"), exports);
|
package/dist/lib/client.d.ts
CHANGED
|
@@ -1,51 +1,3 @@
|
|
|
1
1
|
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
deleteItem?: Parameters<typeof deleteItem>[1];
|
|
5
|
-
deleteItems?: Parameters<typeof deleteItems>[1];
|
|
6
|
-
getItem?: Parameters<typeof getItem>[1];
|
|
7
|
-
getItems?: Parameters<typeof getItems>[1];
|
|
8
|
-
getAllItems?: Parameters<typeof getAllItems>[0];
|
|
9
|
-
putItem?: Parameters<typeof putItem>[1];
|
|
10
|
-
putItems?: Parameters<typeof putItems>[1];
|
|
11
|
-
query?: Parameters<typeof query>[2];
|
|
12
|
-
queryItems?: Parameters<typeof queryItems>[2];
|
|
13
|
-
queryAllItems?: Parameters<typeof queryAllItems>[2];
|
|
14
|
-
updateItem?: Parameters<typeof updateItem>[2];
|
|
15
|
-
removeAttributes?: Parameters<typeof removeAttributes>[2];
|
|
16
|
-
}
|
|
17
|
-
type Operation = keyof OperationArguments;
|
|
18
|
-
declare interface KeySchema {
|
|
19
|
-
hash: string;
|
|
20
|
-
range?: string;
|
|
21
|
-
}
|
|
22
|
-
declare interface KeySchemaCollection {
|
|
23
|
-
[tableName: string]: KeySchema;
|
|
24
|
-
}
|
|
25
|
-
declare class DynamoDBConfig {
|
|
26
|
-
#private;
|
|
27
|
-
client: DynamoDBClient;
|
|
28
|
-
tablesSchema: KeySchemaCollection;
|
|
29
|
-
constructor({ region }?: {
|
|
30
|
-
region?: string;
|
|
31
|
-
});
|
|
32
|
-
initSchema(schema: KeySchemaCollection): KeySchemaCollection;
|
|
33
|
-
getDefaultTable(): string;
|
|
34
|
-
getTableSchema(tableName?: string): KeySchema;
|
|
35
|
-
getDefaultTableSchema(): KeySchema;
|
|
36
|
-
validateSchema(schema: KeySchemaCollection): boolean;
|
|
37
|
-
initDefaults(newDefaults: OperationArguments): void;
|
|
38
|
-
withDefaults<T extends Operation>(args: OperationArguments[T], operation: T): OperationArguments[T];
|
|
39
|
-
destroy(): void;
|
|
40
|
-
}
|
|
41
|
-
declare const config: DynamoDBConfig;
|
|
42
|
-
export declare const client: DynamoDBClient;
|
|
43
|
-
export declare const initSchema: (schema: KeySchemaCollection) => KeySchemaCollection;
|
|
44
|
-
export declare const getDefaultTable: () => string;
|
|
45
|
-
export declare const getDefaultTableSchema: () => KeySchema;
|
|
46
|
-
export declare const validateSchema: (schema: KeySchemaCollection) => boolean;
|
|
47
|
-
export declare const getTableSchema: (tableName?: string) => KeySchema;
|
|
48
|
-
export declare const initDefaults: (newDefaults: OperationArguments) => void;
|
|
49
|
-
export declare const withDefaults: <T extends keyof OperationArguments>(args: OperationArguments[T], operation: T) => OperationArguments[T];
|
|
50
|
-
export declare const destroy: () => void;
|
|
51
|
-
export default config;
|
|
2
|
+
export declare const initClient: (newClient: DynamoDBClient) => void;
|
|
3
|
+
export declare const getClient: () => DynamoDBClient;
|
package/dist/lib/client.js
CHANGED
|
@@ -1,94 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.getClient = exports.initClient = void 0;
|
|
4
4
|
const client_dynamodb_1 = require("@aws-sdk/client-dynamodb");
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
region: region || process.env.AWS_REGION || "eu-central-1",
|
|
13
|
-
});
|
|
14
|
-
const defaultTable = process.env.DYNAMODB_TABLE;
|
|
15
|
-
if (defaultTable) {
|
|
16
|
-
this.initSchema({
|
|
17
|
-
[defaultTable]: {
|
|
18
|
-
hash: "PK",
|
|
19
|
-
range: "SK",
|
|
20
|
-
},
|
|
21
|
-
});
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
initSchema(schema) {
|
|
25
|
-
if (!this.validateSchema(schema)) {
|
|
26
|
-
throw new Error("Invalid schema");
|
|
27
|
-
}
|
|
28
|
-
this.tablesSchema = Object.keys(schema).reduce((acc, table) => {
|
|
29
|
-
const { hash, range } = schema[table];
|
|
30
|
-
acc[table] = {
|
|
31
|
-
hash: hash + "",
|
|
32
|
-
...(range && { range: range + "" }),
|
|
33
|
-
};
|
|
34
|
-
return acc;
|
|
35
|
-
}, {});
|
|
36
|
-
this.#initialized = true;
|
|
37
|
-
return this.tablesSchema;
|
|
38
|
-
}
|
|
39
|
-
getDefaultTable() {
|
|
40
|
-
if (!this.#initialized) {
|
|
41
|
-
throw new Error("Schema not initialized");
|
|
42
|
-
}
|
|
43
|
-
return Object.keys(this.tablesSchema)[0];
|
|
44
|
-
}
|
|
45
|
-
getTableSchema(tableName) {
|
|
46
|
-
if (!this.#initialized) {
|
|
47
|
-
throw new Error("Schema not initialized");
|
|
48
|
-
}
|
|
49
|
-
const table = tableName || this.getDefaultTable();
|
|
50
|
-
return this.tablesSchema[table] || this.getDefaultTableSchema();
|
|
51
|
-
}
|
|
52
|
-
getDefaultTableSchema() {
|
|
53
|
-
return { hash: "PK", range: "SK" };
|
|
54
|
-
}
|
|
55
|
-
validateSchema(schema) {
|
|
56
|
-
const tables = Object.keys(schema);
|
|
57
|
-
if (tables.length === 0) {
|
|
58
|
-
throw new Error("No tables provided");
|
|
59
|
-
}
|
|
60
|
-
tables.forEach((table) => {
|
|
61
|
-
const { hash } = schema[table];
|
|
62
|
-
if (!hash) {
|
|
63
|
-
throw new Error(`No hash key provided for table ${table}`);
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
return true;
|
|
67
|
-
}
|
|
68
|
-
initDefaults(newDefaults) {
|
|
69
|
-
this.#defaults = { ...newDefaults };
|
|
70
|
-
}
|
|
71
|
-
withDefaults(args, operation) {
|
|
72
|
-
return {
|
|
73
|
-
...this.#defaults[operation],
|
|
74
|
-
...args,
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
destroy() {
|
|
78
|
-
this.client.destroy();
|
|
79
|
-
}
|
|
5
|
+
const schemas_1 = require("./schemas");
|
|
6
|
+
let client = new client_dynamodb_1.DynamoDBClient({
|
|
7
|
+
region: process.env.AWS_REGION || "eu-central-1",
|
|
8
|
+
});
|
|
9
|
+
const defaultTable = process.env.DYNAMODB_TABLE;
|
|
10
|
+
if (defaultTable) {
|
|
11
|
+
(0, schemas_1.initSchema)({ [defaultTable]: (0, schemas_1.getDefaultTableSchema)() });
|
|
80
12
|
}
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
return fn.bind(config);
|
|
13
|
+
const initClient = (newClient) => {
|
|
14
|
+
client = newClient;
|
|
84
15
|
};
|
|
85
|
-
exports.
|
|
86
|
-
|
|
87
|
-
exports.
|
|
88
|
-
exports.getDefaultTableSchema = bind(config.getDefaultTableSchema);
|
|
89
|
-
exports.validateSchema = bind(config.validateSchema);
|
|
90
|
-
exports.getTableSchema = bind(config.getTableSchema);
|
|
91
|
-
exports.initDefaults = bind(config.initDefaults);
|
|
92
|
-
exports.withDefaults = bind(config.withDefaults);
|
|
93
|
-
exports.destroy = bind(config.destroy);
|
|
94
|
-
exports.default = config;
|
|
16
|
+
exports.initClient = initClient;
|
|
17
|
+
const getClient = () => client;
|
|
18
|
+
exports.getClient = getClient;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { deleteItem, deleteItems, getAllItems, getItem, getItems, itemExists, putItem, putItems, query, queryAllItems, queryItems, removeAttributes, updateItem } from "../operations";
|
|
2
|
+
export interface OperationArguments {
|
|
3
|
+
deleteItem?: Parameters<typeof deleteItem>[1];
|
|
4
|
+
deleteItems?: Parameters<typeof deleteItems>[1];
|
|
5
|
+
getItem?: Parameters<typeof getItem>[1];
|
|
6
|
+
getItems?: Parameters<typeof getItems>[1];
|
|
7
|
+
getAllItems?: Parameters<typeof getAllItems>[0];
|
|
8
|
+
itemExists?: Parameters<typeof itemExists>[1];
|
|
9
|
+
putItem?: Parameters<typeof putItem>[1];
|
|
10
|
+
putItems?: Parameters<typeof putItems>[1];
|
|
11
|
+
query?: Parameters<typeof query>[2];
|
|
12
|
+
queryItems?: Parameters<typeof queryItems>[2];
|
|
13
|
+
queryAllItems?: Parameters<typeof queryAllItems>[2];
|
|
14
|
+
updateItem?: Parameters<typeof updateItem>[2];
|
|
15
|
+
removeAttributes?: Parameters<typeof removeAttributes>[2];
|
|
16
|
+
}
|
|
17
|
+
export declare const initDefaultArguments: (args: OperationArguments) => void;
|
|
18
|
+
export declare const getDefaultArguments: () => OperationArguments;
|
|
19
|
+
export declare const withDefaults: <T extends keyof OperationArguments>(args: Partial<OperationArguments[T]>, operation: T) => OperationArguments[T];
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.withDefaults = exports.getDefaultArguments = exports.initDefaultArguments = void 0;
|
|
4
|
+
let defaultArguments = {};
|
|
5
|
+
const initDefaultArguments = (args) => {
|
|
6
|
+
defaultArguments = args;
|
|
7
|
+
};
|
|
8
|
+
exports.initDefaultArguments = initDefaultArguments;
|
|
9
|
+
const getDefaultArguments = () => defaultArguments;
|
|
10
|
+
exports.getDefaultArguments = getDefaultArguments;
|
|
11
|
+
const withDefaults = (args, operation) => {
|
|
12
|
+
return {
|
|
13
|
+
...defaultArguments[operation],
|
|
14
|
+
...args,
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
exports.withDefaults = withDefaults;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { QueryCommandInput, ScanCommandInput } from "@aws-sdk/client-dynamodb";
|
|
2
|
+
import { marshall, marshallOptions, unmarshall, unmarshallOptions } from "@aws-sdk/util-dynamodb";
|
|
3
|
+
export declare interface DynamoDBFixes {
|
|
4
|
+
disableConsistantReadWhenUsingIndexes?: {
|
|
5
|
+
enabled: boolean;
|
|
6
|
+
stillUseOnLocalIndexes?: string[];
|
|
7
|
+
};
|
|
8
|
+
marshallOptions?: marshallOptions;
|
|
9
|
+
unmarshallOptions?: unmarshallOptions;
|
|
10
|
+
}
|
|
11
|
+
export declare const initFixes: (fixesConfig: DynamoDBFixes) => void;
|
|
12
|
+
export declare const getFixes: () => DynamoDBFixes;
|
|
13
|
+
export declare const withFixes: (args: Partial<QueryCommandInput> | Partial<ScanCommandInput>) => Partial<QueryCommandInput> | Partial<ScanCommandInput>;
|
|
14
|
+
export declare const getDefaultFixes: () => {
|
|
15
|
+
disableConsistantReadWhenQueryingIndexes: {
|
|
16
|
+
enabled: boolean;
|
|
17
|
+
};
|
|
18
|
+
marshallOptions: {
|
|
19
|
+
removeUndefinedValues: boolean;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
export declare const marshallWithOptions: (input: Parameters<typeof marshall>[0]) => Record<string, import("@aws-sdk/client-dynamodb").AttributeValue>;
|
|
23
|
+
export declare const unmarshallWithOptions: (input: Parameters<typeof unmarshall>[0]) => Record<string, any>;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.unmarshallWithOptions = exports.marshallWithOptions = exports.getDefaultFixes = exports.withFixes = exports.getFixes = exports.initFixes = void 0;
|
|
4
|
+
const util_dynamodb_1 = require("@aws-sdk/util-dynamodb");
|
|
5
|
+
const defaults = {
|
|
6
|
+
disableConsistantReadWhenQueryingIndexes: {
|
|
7
|
+
enabled: true,
|
|
8
|
+
},
|
|
9
|
+
marshallOptions: {
|
|
10
|
+
removeUndefinedValues: true,
|
|
11
|
+
},
|
|
12
|
+
};
|
|
13
|
+
let fixes = defaults;
|
|
14
|
+
const initFixes = (fixesConfig) => {
|
|
15
|
+
fixes = fixesConfig;
|
|
16
|
+
};
|
|
17
|
+
exports.initFixes = initFixes;
|
|
18
|
+
const getFixes = () => fixes;
|
|
19
|
+
exports.getFixes = getFixes;
|
|
20
|
+
const handleIndex = (args) => {
|
|
21
|
+
if (fixes?.disableConsistantReadWhenUsingIndexes?.enabled &&
|
|
22
|
+
args?.IndexName &&
|
|
23
|
+
args?.ConsistentRead &&
|
|
24
|
+
!fixes?.disableConsistantReadWhenUsingIndexes?.stillUseOnLocalIndexes?.includes(args?.IndexName)) {
|
|
25
|
+
args.ConsistentRead = false;
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
const withFixes = (args) => {
|
|
29
|
+
handleIndex(args);
|
|
30
|
+
return args;
|
|
31
|
+
};
|
|
32
|
+
exports.withFixes = withFixes;
|
|
33
|
+
const getDefaultFixes = () => defaults;
|
|
34
|
+
exports.getDefaultFixes = getDefaultFixes;
|
|
35
|
+
const marshallWithOptions = (input) => (0, util_dynamodb_1.marshall)(input, fixes.marshallOptions);
|
|
36
|
+
exports.marshallWithOptions = marshallWithOptions;
|
|
37
|
+
const unmarshallWithOptions = (input) => (0, util_dynamodb_1.unmarshall)(input, fixes.unmarshallOptions);
|
|
38
|
+
exports.unmarshallWithOptions = unmarshallWithOptions;
|
package/dist/lib/helpers.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getAttributesFromExpression = exports.getAttributeNames = exports.getAttributeValues = exports.splitEvery = exports.stripKey = void 0;
|
|
4
|
-
const
|
|
5
|
-
const
|
|
4
|
+
const fixes_1 = require("./fixes");
|
|
5
|
+
const schemas_1 = require("./schemas");
|
|
6
6
|
// Since dynamo only accepts key atrtributes which are described in table schema
|
|
7
7
|
// we remove any other attributes from the item if they are present and passed as
|
|
8
8
|
// key parameter to any of the functions below (getItem, updateItem, deleteItem...)
|
|
9
9
|
function stripKey(key, args) {
|
|
10
|
-
const { hash, range } = (0,
|
|
11
|
-
return (0,
|
|
10
|
+
const { hash, range } = (0, schemas_1.getTableSchema)(args?.TableName);
|
|
11
|
+
return (0, fixes_1.marshallWithOptions)({
|
|
12
12
|
[hash]: key[hash],
|
|
13
13
|
...(range && { [range]: key[range] }),
|
|
14
14
|
});
|
|
@@ -23,7 +23,7 @@ function splitEvery(items, limit = 25) {
|
|
|
23
23
|
}
|
|
24
24
|
exports.splitEvery = splitEvery;
|
|
25
25
|
function getAttributeValues(key, attributesToGet) {
|
|
26
|
-
return (0,
|
|
26
|
+
return (0, fixes_1.marshallWithOptions)((attributesToGet || Object.keys(key)).reduce((acc, keyName) => {
|
|
27
27
|
acc[`:${keyName}`] = key[keyName];
|
|
28
28
|
return acc;
|
|
29
29
|
}, {}));
|
|
@@ -0,0 +1,21 @@
|
|
|
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./client"), exports);
|
|
18
|
+
__exportStar(require("./defaultArguments"), exports);
|
|
19
|
+
__exportStar(require("./fixes"), exports);
|
|
20
|
+
__exportStar(require("./helpers"), exports);
|
|
21
|
+
__exportStar(require("./schemas"), exports);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare interface KeySchema {
|
|
2
|
+
hash: string;
|
|
3
|
+
range?: string;
|
|
4
|
+
}
|
|
5
|
+
export declare interface KeySchemaCollection {
|
|
6
|
+
[tableName: string]: KeySchema;
|
|
7
|
+
}
|
|
8
|
+
export declare const initSchema: (schema: KeySchemaCollection) => KeySchemaCollection;
|
|
9
|
+
export declare const validateSchema: (schema: KeySchemaCollection) => boolean;
|
|
10
|
+
export declare const getDefaultTable: () => string;
|
|
11
|
+
export declare const getTableSchema: (tableName?: string) => KeySchema;
|
|
12
|
+
export declare const getDefaultTableSchema: () => KeySchema;
|
|
13
|
+
export declare const isInitialized: () => boolean;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isInitialized = exports.getDefaultTableSchema = exports.getTableSchema = exports.getDefaultTable = exports.validateSchema = exports.initSchema = void 0;
|
|
4
|
+
let initialized = false;
|
|
5
|
+
let tablesSchema = {};
|
|
6
|
+
const initSchema = (schema) => {
|
|
7
|
+
if (!(0, exports.validateSchema)(schema)) {
|
|
8
|
+
throw new Error("[@moicky/dynamodb]: Invalid schema");
|
|
9
|
+
}
|
|
10
|
+
tablesSchema = Object.keys(schema).reduce((acc, table) => {
|
|
11
|
+
const { hash, range } = schema[table];
|
|
12
|
+
acc[table] = {
|
|
13
|
+
hash: hash + "",
|
|
14
|
+
...(range && { range: range + "" }),
|
|
15
|
+
};
|
|
16
|
+
return acc;
|
|
17
|
+
}, {});
|
|
18
|
+
initialized = true;
|
|
19
|
+
return tablesSchema;
|
|
20
|
+
};
|
|
21
|
+
exports.initSchema = initSchema;
|
|
22
|
+
const validateSchema = (schema) => {
|
|
23
|
+
const tables = Object.keys(schema);
|
|
24
|
+
if (tables.length === 0) {
|
|
25
|
+
throw new Error("[@moicky/dynamodb]: No tables provided");
|
|
26
|
+
}
|
|
27
|
+
tables.forEach((table) => {
|
|
28
|
+
const { hash } = schema[table];
|
|
29
|
+
if (!hash) {
|
|
30
|
+
throw new Error(`No hash key provided for table ${table}`);
|
|
31
|
+
}
|
|
32
|
+
if (typeof hash !== "string") {
|
|
33
|
+
throw new Error(`Invalid hash key provided for table ${table}`);
|
|
34
|
+
}
|
|
35
|
+
const { range } = schema[table];
|
|
36
|
+
if (range && typeof range !== "string") {
|
|
37
|
+
throw new Error(`Invalid range key provided for table ${table}`);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
return true;
|
|
41
|
+
};
|
|
42
|
+
exports.validateSchema = validateSchema;
|
|
43
|
+
const getDefaultTable = () => {
|
|
44
|
+
if (!initialized) {
|
|
45
|
+
throw new Error("[@moicky/dynamodb]: Schema not initialized");
|
|
46
|
+
}
|
|
47
|
+
return Object.keys(tablesSchema)[0];
|
|
48
|
+
};
|
|
49
|
+
exports.getDefaultTable = getDefaultTable;
|
|
50
|
+
const getTableSchema = (tableName) => {
|
|
51
|
+
if (!initialized) {
|
|
52
|
+
throw new Error("[@moicky/dynamodb]: Schema not initialized");
|
|
53
|
+
}
|
|
54
|
+
const table = tableName || (0, exports.getDefaultTable)();
|
|
55
|
+
return tablesSchema[table] || (0, exports.getDefaultTableSchema)();
|
|
56
|
+
};
|
|
57
|
+
exports.getTableSchema = getTableSchema;
|
|
58
|
+
const getDefaultTableSchema = () => {
|
|
59
|
+
return { hash: "PK", range: "SK" };
|
|
60
|
+
};
|
|
61
|
+
exports.getDefaultTableSchema = getDefaultTableSchema;
|
|
62
|
+
const isInitialized = () => initialized;
|
|
63
|
+
exports.isInitialized = isInitialized;
|
|
@@ -2,20 +2,19 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.deleteItems = exports.deleteItem = void 0;
|
|
4
4
|
const client_dynamodb_1 = require("@aws-sdk/client-dynamodb");
|
|
5
|
-
const
|
|
6
|
-
const helpers_1 = require("../lib/helpers");
|
|
5
|
+
const lib_1 = require("../lib");
|
|
7
6
|
async function deleteItem(key, args = {}) {
|
|
8
|
-
return
|
|
9
|
-
Key: (0,
|
|
10
|
-
...(0,
|
|
11
|
-
TableName: args?.TableName || (0,
|
|
7
|
+
return (0, lib_1.getClient)().send(new client_dynamodb_1.DeleteItemCommand({
|
|
8
|
+
Key: (0, lib_1.stripKey)(key, args),
|
|
9
|
+
...(0, lib_1.withDefaults)(args, "deleteItem"),
|
|
10
|
+
TableName: args?.TableName || (0, lib_1.getDefaultTable)(),
|
|
12
11
|
}));
|
|
13
12
|
}
|
|
14
13
|
exports.deleteItem = deleteItem;
|
|
15
14
|
async function deleteItems(keys, args = {}, retry = 0) {
|
|
16
|
-
args = (0,
|
|
15
|
+
args = (0, lib_1.withDefaults)(args, "deleteItems");
|
|
17
16
|
const uniqueKeys = Object.values(keys.reduce((acc, key) => {
|
|
18
|
-
const strippedKey = (0,
|
|
17
|
+
const strippedKey = (0, lib_1.stripKey)(key, args);
|
|
19
18
|
const keyString = JSON.stringify(strippedKey);
|
|
20
19
|
if (!acc[keyString]) {
|
|
21
20
|
acc[keyString] = strippedKey;
|
|
@@ -23,12 +22,12 @@ async function deleteItems(keys, args = {}, retry = 0) {
|
|
|
23
22
|
return acc;
|
|
24
23
|
}, {}));
|
|
25
24
|
return new Promise(async (resolve, reject) => {
|
|
26
|
-
const batches = (0,
|
|
25
|
+
const batches = (0, lib_1.splitEvery)(uniqueKeys);
|
|
27
26
|
if (retry > 3)
|
|
28
27
|
return;
|
|
29
|
-
const table = args?.TableName || (0,
|
|
28
|
+
const table = args?.TableName || (0, lib_1.getDefaultTable)();
|
|
30
29
|
for (const batch of batches) {
|
|
31
|
-
await
|
|
30
|
+
await (0, lib_1.getClient)()
|
|
32
31
|
.send(new client_dynamodb_1.BatchWriteItemCommand({
|
|
33
32
|
RequestItems: {
|
|
34
33
|
[table]: batch.map((Key) => ({
|
package/dist/operations/get.js
CHANGED
|
@@ -2,22 +2,20 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getAllItems = exports.getItems = exports.getItem = void 0;
|
|
4
4
|
const client_dynamodb_1 = require("@aws-sdk/client-dynamodb");
|
|
5
|
-
const
|
|
6
|
-
const client_1 = require("../lib/client");
|
|
7
|
-
const helpers_1 = require("../lib/helpers");
|
|
5
|
+
const lib_1 = require("../lib");
|
|
8
6
|
async function getItem(key, args = {}) {
|
|
9
|
-
args = (0,
|
|
10
|
-
return
|
|
7
|
+
args = (0, lib_1.withDefaults)(args, "getItem");
|
|
8
|
+
return (0, lib_1.getClient)()
|
|
11
9
|
.send(new client_dynamodb_1.GetItemCommand({
|
|
12
|
-
Key: (0,
|
|
10
|
+
Key: (0, lib_1.stripKey)(key, args),
|
|
13
11
|
...args,
|
|
14
|
-
TableName: args?.TableName || (0,
|
|
12
|
+
TableName: args?.TableName || (0, lib_1.getDefaultTable)(),
|
|
15
13
|
}))
|
|
16
|
-
.then((res) => res?.Item && (0,
|
|
14
|
+
.then((res) => res?.Item && (0, lib_1.unmarshallWithOptions)(res.Item));
|
|
17
15
|
}
|
|
18
16
|
exports.getItem = getItem;
|
|
19
17
|
async function getItems(keys, args = {}, retry = 0) {
|
|
20
|
-
args = (0,
|
|
18
|
+
args = (0, lib_1.withDefaults)(args, "getItems");
|
|
21
19
|
// creates batches of 100 items each and performs batchGet on every batch.
|
|
22
20
|
// also retries up to 3 times if there are unprocessed items (due to size limit of 16MB)
|
|
23
21
|
// returns items in same order as keys (not sorted by default when using batchGet)
|
|
@@ -26,22 +24,22 @@ async function getItems(keys, args = {}, retry = 0) {
|
|
|
26
24
|
const batchReadLimit = 100;
|
|
27
25
|
// duplicate key entries would cause an error, so we remove them
|
|
28
26
|
const uniqueKeys = Object.values(keys.reduce((acc, key) => {
|
|
29
|
-
const strippedKey = (0,
|
|
27
|
+
const strippedKey = (0, lib_1.stripKey)(key, args);
|
|
30
28
|
const keyString = JSON.stringify(strippedKey);
|
|
31
29
|
if (!acc[keyString]) {
|
|
32
30
|
acc[keyString] = strippedKey;
|
|
33
31
|
}
|
|
34
32
|
return acc;
|
|
35
33
|
}, {}));
|
|
36
|
-
const batches = (0,
|
|
34
|
+
const batches = (0, lib_1.splitEvery)(uniqueKeys, batchReadLimit);
|
|
37
35
|
const results = [];
|
|
38
36
|
if (retry > 2) {
|
|
39
37
|
return results;
|
|
40
38
|
}
|
|
41
|
-
const TableName = args?.TableName || (0,
|
|
39
|
+
const TableName = args?.TableName || (0, lib_1.getDefaultTable)();
|
|
42
40
|
delete args.TableName;
|
|
43
41
|
await Promise.all(batches.map(async (batch) => {
|
|
44
|
-
await
|
|
42
|
+
await (0, lib_1.getClient)()
|
|
45
43
|
.send(new client_dynamodb_1.BatchGetItemCommand({
|
|
46
44
|
RequestItems: {
|
|
47
45
|
[TableName]: {
|
|
@@ -56,27 +54,27 @@ async function getItems(keys, args = {}, retry = 0) {
|
|
|
56
54
|
if (unprocessed) {
|
|
57
55
|
return getItems(unprocessed.Keys, { ...args, TableName }, retry + 1).then((items) => allItemsFromBatch.concat(items));
|
|
58
56
|
}
|
|
59
|
-
return allItemsFromBatch.map((item) => item && (0,
|
|
57
|
+
return allItemsFromBatch.map((item) => item && (0, lib_1.unmarshallWithOptions)(item));
|
|
60
58
|
})
|
|
61
59
|
.then((items) => results.push(...items));
|
|
62
60
|
}));
|
|
63
61
|
const resultItems = results
|
|
64
62
|
.filter((i) => i)
|
|
65
63
|
.reduce((acc, item) => {
|
|
66
|
-
const keyString = JSON.stringify((0,
|
|
64
|
+
const keyString = JSON.stringify((0, lib_1.stripKey)(item, { TableName }));
|
|
67
65
|
acc[keyString] = item;
|
|
68
66
|
return acc;
|
|
69
67
|
}, {});
|
|
70
|
-
return keys.map((key) => resultItems[JSON.stringify((0,
|
|
68
|
+
return keys.map((key) => resultItems[JSON.stringify((0, lib_1.stripKey)(key, { TableName }))] || undefined);
|
|
71
69
|
}
|
|
72
70
|
exports.getItems = getItems;
|
|
73
71
|
async function getAllItems(args = {}) {
|
|
74
|
-
args = (0,
|
|
75
|
-
return
|
|
72
|
+
args = (0, lib_1.withFixes)((0, lib_1.withDefaults)(args, "getAllItems"));
|
|
73
|
+
return (0, lib_1.getClient)()
|
|
76
74
|
.send(new client_dynamodb_1.ScanCommand({
|
|
77
75
|
...args,
|
|
78
|
-
TableName: args?.TableName || (0,
|
|
76
|
+
TableName: args?.TableName || (0, lib_1.getDefaultTable)(),
|
|
79
77
|
}))
|
|
80
|
-
.then((res) => res.Items.map((item) => item && (0,
|
|
78
|
+
.then((res) => res.Items.map((item) => item && (0, lib_1.unmarshallWithOptions)(item)));
|
|
81
79
|
}
|
|
82
80
|
exports.getAllItems = getAllItems;
|
package/dist/operations/misc.js
CHANGED
|
@@ -1,21 +1,28 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getAscendingId = exports.itemExists = void 0;
|
|
4
|
-
const
|
|
5
|
-
const
|
|
4
|
+
const client_dynamodb_1 = require("@aws-sdk/client-dynamodb");
|
|
5
|
+
const lib_1 = require("../lib");
|
|
6
6
|
const query_1 = require("./query");
|
|
7
7
|
async function itemExists(key, args = {}) {
|
|
8
|
-
|
|
8
|
+
args = (0, lib_1.withDefaults)(args, "itemExists");
|
|
9
|
+
return (0, lib_1.getClient)()
|
|
10
|
+
.send(new client_dynamodb_1.GetItemCommand({
|
|
11
|
+
Key: (0, lib_1.stripKey)(key, args),
|
|
12
|
+
...args,
|
|
13
|
+
TableName: args?.TableName || (0, lib_1.getDefaultTable)(),
|
|
14
|
+
}))
|
|
15
|
+
.then((res) => !!res?.Item);
|
|
9
16
|
}
|
|
10
17
|
exports.itemExists = itemExists;
|
|
11
18
|
async function getAscendingId({ length = 8, TableName, ...keySchema }) {
|
|
12
19
|
// Assumes that you are the incrementing ID inside or as the keySchema range key
|
|
13
|
-
const table = TableName || (0,
|
|
14
|
-
const { hash, range } = (0,
|
|
20
|
+
const table = TableName || (0, lib_1.getDefaultTable)();
|
|
21
|
+
const { hash, range } = (0, lib_1.getTableSchema)(table);
|
|
15
22
|
const keySchemaHash = keySchema[hash];
|
|
16
23
|
const keySchemaRange = keySchema[range];
|
|
17
24
|
if (!keySchemaHash) {
|
|
18
|
-
throw new Error(`Cannot generate new ID: keySchemaHash is missing, expected '${hash}'`);
|
|
25
|
+
throw new Error(`[@moicky/dynamodb]: Cannot generate new ID: keySchemaHash is missing, expected '${hash}'`);
|
|
19
26
|
}
|
|
20
27
|
let lastId = "0";
|
|
21
28
|
if (!keySchemaRange) {
|
package/dist/operations/put.js
CHANGED
|
@@ -2,40 +2,38 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.putItems = exports.putItem = void 0;
|
|
4
4
|
const client_dynamodb_1 = require("@aws-sdk/client-dynamodb");
|
|
5
|
-
const
|
|
6
|
-
const client_1 = require("../lib/client");
|
|
7
|
-
const helpers_1 = require("../lib/helpers");
|
|
5
|
+
const lib_1 = require("../lib");
|
|
8
6
|
async function putItem(data, args = {}) {
|
|
9
|
-
args = (0,
|
|
7
|
+
args = (0, lib_1.withDefaults)(args, "putItem");
|
|
10
8
|
if (!Object.keys(data).includes("createdAt")) {
|
|
11
9
|
data.createdAt = Date.now();
|
|
12
10
|
}
|
|
13
|
-
return
|
|
11
|
+
return (0, lib_1.getClient)()
|
|
14
12
|
.send(new client_dynamodb_1.PutItemCommand({
|
|
15
|
-
Item: (0,
|
|
13
|
+
Item: (0, lib_1.marshallWithOptions)(data),
|
|
16
14
|
...args,
|
|
17
|
-
TableName: args?.TableName || (0,
|
|
15
|
+
TableName: args?.TableName || (0, lib_1.getDefaultTable)(),
|
|
18
16
|
}))
|
|
19
|
-
.then((res) =>
|
|
17
|
+
.then((res) => args?.ReturnValues ? (0, lib_1.unmarshallWithOptions)(res?.Attributes) : res);
|
|
20
18
|
}
|
|
21
19
|
exports.putItem = putItem;
|
|
22
20
|
async function putItems(items, args = {}) {
|
|
23
|
-
args = (0,
|
|
21
|
+
args = (0, lib_1.withDefaults)(args, "putItems");
|
|
24
22
|
return new Promise(async (resolve, reject) => {
|
|
25
23
|
const now = Date.now();
|
|
26
|
-
const batches = (0,
|
|
24
|
+
const batches = (0, lib_1.splitEvery)(items.map((item) => ({
|
|
27
25
|
...item,
|
|
28
26
|
createdAt: item?.createdAt ?? now,
|
|
29
27
|
})));
|
|
30
28
|
const results = [];
|
|
31
|
-
const table = args?.TableName || (0,
|
|
29
|
+
const table = args?.TableName || (0, lib_1.getDefaultTable)();
|
|
32
30
|
for (const batch of batches) {
|
|
33
|
-
await
|
|
31
|
+
await (0, lib_1.getClient)()
|
|
34
32
|
.send(new client_dynamodb_1.BatchWriteItemCommand({
|
|
35
33
|
RequestItems: {
|
|
36
34
|
[table]: batch.map((item) => ({
|
|
37
35
|
PutRequest: {
|
|
38
|
-
Item: (0,
|
|
36
|
+
Item: (0, lib_1.marshallWithOptions)(item),
|
|
39
37
|
},
|
|
40
38
|
})),
|
|
41
39
|
},
|
package/dist/operations/query.js
CHANGED
|
@@ -2,37 +2,36 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.queryAllItems = exports.queryItems = exports.query = void 0;
|
|
4
4
|
const client_dynamodb_1 = require("@aws-sdk/client-dynamodb");
|
|
5
|
-
const
|
|
6
|
-
const client_1 = require("../lib/client");
|
|
7
|
-
const helpers_1 = require("../lib/helpers");
|
|
5
|
+
const lib_1 = require("../lib");
|
|
8
6
|
async function _query(keyCondition, key, args = {}) {
|
|
9
|
-
|
|
7
|
+
args = (0, lib_1.withFixes)(args);
|
|
8
|
+
return (0, lib_1.getClient)().send(new client_dynamodb_1.QueryCommand({
|
|
10
9
|
KeyConditionExpression: keyCondition,
|
|
11
|
-
ExpressionAttributeValues: (0,
|
|
12
|
-
...(0,
|
|
13
|
-
...(0,
|
|
10
|
+
ExpressionAttributeValues: (0, lib_1.getAttributeValues)(key, [
|
|
11
|
+
...(0, lib_1.getAttributesFromExpression)(keyCondition, ":"),
|
|
12
|
+
...(0, lib_1.getAttributesFromExpression)(args?.FilterExpression || "", ":"),
|
|
14
13
|
]),
|
|
15
|
-
ExpressionAttributeNames: (0,
|
|
16
|
-
...(0,
|
|
17
|
-
...(0,
|
|
14
|
+
ExpressionAttributeNames: (0, lib_1.getAttributeNames)(key, [
|
|
15
|
+
...(0, lib_1.getAttributesFromExpression)(keyCondition),
|
|
16
|
+
...(0, lib_1.getAttributesFromExpression)(args?.FilterExpression || ""),
|
|
18
17
|
]),
|
|
19
18
|
...args,
|
|
20
|
-
TableName: args?.TableName || (0,
|
|
19
|
+
TableName: args?.TableName || (0, lib_1.getDefaultTable)(),
|
|
21
20
|
}));
|
|
22
21
|
}
|
|
23
22
|
async function query(keyCondition, key, args) {
|
|
24
|
-
return _query(keyCondition, key, (0,
|
|
23
|
+
return _query(keyCondition, key, (0, lib_1.withDefaults)(args, "query"));
|
|
25
24
|
}
|
|
26
25
|
exports.query = query;
|
|
27
26
|
async function queryItems(keyCondition, key, args = {}) {
|
|
28
|
-
args = (0,
|
|
27
|
+
args = (0, lib_1.withDefaults)(args, "queryItems");
|
|
29
28
|
return _query(keyCondition, key, args).then((res) => (res?.Items || [])
|
|
30
|
-
.map((item) => item && (0,
|
|
29
|
+
.map((item) => item && (0, lib_1.unmarshallWithOptions)(item))
|
|
31
30
|
.filter((item) => item));
|
|
32
31
|
}
|
|
33
32
|
exports.queryItems = queryItems;
|
|
34
33
|
async function queryAllItems(keyCondition, key, args = {}) {
|
|
35
|
-
args = (0,
|
|
34
|
+
args = (0, lib_1.withDefaults)(args, "queryAllItems");
|
|
36
35
|
let data = await _query(keyCondition, key, args);
|
|
37
36
|
while (data.LastEvaluatedKey) {
|
|
38
37
|
if (data.LastEvaluatedKey) {
|
|
@@ -47,7 +46,7 @@ async function queryAllItems(keyCondition, key, args = {}) {
|
|
|
47
46
|
}
|
|
48
47
|
}
|
|
49
48
|
return (data?.Items || [])
|
|
50
|
-
.map((item) => item && (0,
|
|
49
|
+
.map((item) => item && (0, lib_1.unmarshallWithOptions)(item))
|
|
51
50
|
.filter((item) => item);
|
|
52
51
|
}
|
|
53
52
|
exports.queryAllItems = queryAllItems;
|
|
@@ -2,48 +2,46 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.removeAttributes = exports.updateItem = void 0;
|
|
4
4
|
const client_dynamodb_1 = require("@aws-sdk/client-dynamodb");
|
|
5
|
-
const
|
|
6
|
-
const client_1 = require("../lib/client");
|
|
7
|
-
const helpers_1 = require("../lib/helpers");
|
|
5
|
+
const lib_1 = require("../lib");
|
|
8
6
|
async function updateItem(key, data, args = {}) {
|
|
9
|
-
args = (0,
|
|
7
|
+
args = (0, lib_1.withDefaults)(args, "updateItem");
|
|
10
8
|
if (!Object.keys(data).includes("updatedAt")) {
|
|
11
9
|
data.updatedAt = Date.now();
|
|
12
10
|
}
|
|
13
|
-
const valuesInCondition = (0,
|
|
14
|
-
const namesInCondition = (0,
|
|
11
|
+
const valuesInCondition = (0, lib_1.getAttributesFromExpression)(args?.ConditionExpression || "", ":");
|
|
12
|
+
const namesInCondition = (0, lib_1.getAttributesFromExpression)(args?.ConditionExpression || "");
|
|
15
13
|
const attributesToUpdate = Object.keys(data).filter((key) => !valuesInCondition.includes(key));
|
|
16
14
|
const UpdateExpression = "SET " + attributesToUpdate.map((key) => `#${key} = :${key}`).join(", ");
|
|
17
|
-
return
|
|
15
|
+
return (0, lib_1.getClient)()
|
|
18
16
|
.send(new client_dynamodb_1.UpdateItemCommand({
|
|
19
|
-
Key: (0,
|
|
17
|
+
Key: (0, lib_1.stripKey)(key, args),
|
|
20
18
|
UpdateExpression,
|
|
21
|
-
ExpressionAttributeValues: (0,
|
|
19
|
+
ExpressionAttributeValues: (0, lib_1.getAttributeValues)(data, [
|
|
22
20
|
...attributesToUpdate,
|
|
23
21
|
...valuesInCondition,
|
|
24
22
|
]),
|
|
25
|
-
ExpressionAttributeNames: (0,
|
|
23
|
+
ExpressionAttributeNames: (0, lib_1.getAttributeNames)(data, [
|
|
26
24
|
...attributesToUpdate,
|
|
27
25
|
...namesInCondition,
|
|
28
26
|
]),
|
|
29
27
|
...args,
|
|
30
|
-
TableName: args?.TableName || (0,
|
|
28
|
+
TableName: args?.TableName || (0, lib_1.getDefaultTable)(),
|
|
31
29
|
}))
|
|
32
|
-
.then((res) => args?.ReturnValues ? (0,
|
|
30
|
+
.then((res) => args?.ReturnValues ? (0, lib_1.unmarshallWithOptions)(res.Attributes) : undefined);
|
|
33
31
|
}
|
|
34
32
|
exports.updateItem = updateItem;
|
|
35
33
|
async function removeAttributes(key, attributes, args = {}) {
|
|
36
|
-
args = (0,
|
|
34
|
+
args = (0, lib_1.withDefaults)(args, "removeAttributes");
|
|
37
35
|
const UpdateExpression = "REMOVE " + attributes.map((att) => `#${att}`).join(", ");
|
|
38
|
-
return
|
|
39
|
-
Key: (0,
|
|
36
|
+
return (0, lib_1.getClient)().send(new client_dynamodb_1.UpdateItemCommand({
|
|
37
|
+
Key: (0, lib_1.stripKey)(key, args),
|
|
40
38
|
UpdateExpression,
|
|
41
|
-
ExpressionAttributeNames: (0,
|
|
39
|
+
ExpressionAttributeNames: (0, lib_1.getAttributeNames)(attributes.reduce((acc, att) => {
|
|
42
40
|
acc[att] = att;
|
|
43
41
|
return acc;
|
|
44
42
|
}, {})),
|
|
45
43
|
...args,
|
|
46
|
-
TableName: args?.TableName || (0,
|
|
44
|
+
TableName: args?.TableName || (0, lib_1.getDefaultTable)(),
|
|
47
45
|
}));
|
|
48
46
|
}
|
|
49
47
|
exports.removeAttributes = removeAttributes;
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -10,10 +10,11 @@ Contains convenience functions for all major dynamodb operations. Requires very
|
|
|
10
10
|
- 🎁 Will **automatically marshall and unmarshall** items
|
|
11
11
|
- 📦 Will **group items into batches** to avoid aws limits and improve performance
|
|
12
12
|
- ⏱ Will **automatically** add `createdAt` and `updatedAt` attributes on all items to track their most recent create/update operation timestamp. Example value: `Date.now() -> 1685138436000`
|
|
13
|
-
- 🔄 Will **retry**
|
|
13
|
+
- 🔄 Will **retry** `getItems`, `deleteItems` **up to 3 times** on unprocessed items and `queryAllItems` until finished
|
|
14
14
|
- 🔒 When specifying an item using its keySchema, all additional attributes (apart from keySchema attributes from `initSchema` or `PK` & `SK` as default) will be removed to avoid errors
|
|
15
15
|
- 👻 Will **use placeholders** to avoid colliding with [reserved words](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ReservedWords.html) if applicable
|
|
16
|
-
- 🌎 Supports globally defined default arguments for each operation
|
|
16
|
+
- 🌎 Supports globally defined default arguments for each operation ([example](#configuring-global-defaults))
|
|
17
|
+
- 🔨 Supports fixes for several issues with dynamodb ([example](#applying-fixes))
|
|
17
18
|
|
|
18
19
|
## Installation
|
|
19
20
|
|
|
@@ -36,7 +37,7 @@ initSchema({
|
|
|
36
37
|
range: "SK",
|
|
37
38
|
},
|
|
38
39
|
[process.env.SECOND_TABLE]: {
|
|
39
|
-
hash: "
|
|
40
|
+
hash: "somePK",
|
|
40
41
|
},
|
|
41
42
|
});
|
|
42
43
|
```
|
|
@@ -67,26 +68,6 @@ const item = await getItem(
|
|
|
67
68
|
await deleteItem(item, { TableName: process.env.SECOND_TABLE });
|
|
68
69
|
```
|
|
69
70
|
|
|
70
|
-
## Configuring global defaults
|
|
71
|
-
|
|
72
|
-
Global defaults can be configured using the `initDefaults` function. This allows to provide but still override every property of the `args` parameter.
|
|
73
|
-
|
|
74
|
-
Should be called before any DynamoDB operations are performed.
|
|
75
|
-
|
|
76
|
-
```ts
|
|
77
|
-
import { initDefaults } from "@moicky/dynamodb";
|
|
78
|
-
|
|
79
|
-
// Enables consistent reads for all DynamoDB operations which support it.
|
|
80
|
-
initDefaults({
|
|
81
|
-
getItem: { ConsistentRead: true },
|
|
82
|
-
getAllItems: { ConsistentRead: true },
|
|
83
|
-
|
|
84
|
-
query: { ConsistentRead: true },
|
|
85
|
-
queryItems: { ConsistentRead: true },
|
|
86
|
-
queryAllItems: { ConsistentRead: true },
|
|
87
|
-
});
|
|
88
|
-
```
|
|
89
|
-
|
|
90
71
|
## Usage Examples
|
|
91
72
|
|
|
92
73
|
### Put Items
|
|
@@ -275,6 +256,60 @@ const id4 = await getAscendingId({
|
|
|
275
256
|
console.log(id4); // "00000010"
|
|
276
257
|
```
|
|
277
258
|
|
|
259
|
+
## Configuring global defaults
|
|
260
|
+
|
|
261
|
+
Global defaults can be configured using the `initDefaults` function. This allows to provide but still override every property of the `args` parameter.
|
|
262
|
+
|
|
263
|
+
Should be called before any DynamoDB operations are performed.
|
|
264
|
+
|
|
265
|
+
```ts
|
|
266
|
+
import { initDefaultArguments } from "@moicky/dynamodb";
|
|
267
|
+
|
|
268
|
+
// Enables consistent reads for all DynamoDB operations which support it.
|
|
269
|
+
initDefaultArguments({
|
|
270
|
+
getItem: { ConsistentRead: true },
|
|
271
|
+
getAllItems: { ConsistentRead: true },
|
|
272
|
+
|
|
273
|
+
itemExists: { ConsistentRead: true },
|
|
274
|
+
|
|
275
|
+
query: { ConsistentRead: true },
|
|
276
|
+
queryItems: { ConsistentRead: true },
|
|
277
|
+
queryAllItems: { ConsistentRead: true },
|
|
278
|
+
});
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
## Applying fixes
|
|
282
|
+
|
|
283
|
+
Arguments which are passed to [marshall](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/interfaces/_aws_sdk_util_dynamodb.marshallOptions.html) and [unmarshall](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/interfaces/_aws_sdk_util_dynamodb.unmarshallOptions.html) from `@aws-sdk/util-dynamodb` can be configured using
|
|
284
|
+
|
|
285
|
+
```ts
|
|
286
|
+
import { initFixes } from "@moicky/dynamodb";
|
|
287
|
+
|
|
288
|
+
initFixes({
|
|
289
|
+
marshallOptions: {
|
|
290
|
+
removeUndefinedValues: true,
|
|
291
|
+
},
|
|
292
|
+
unmarshallOptions: {
|
|
293
|
+
wrapNumbers: true,
|
|
294
|
+
},
|
|
295
|
+
});
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
When using `GlobalSecondaryIndexes`, DynamoDb does not support using `ConsistantRead`. This is fixed by default (`ConsistantRead` is turned off) and can be configured using:
|
|
299
|
+
|
|
300
|
+
```ts
|
|
301
|
+
import { initFixes } from "@moicky/dynamodb";
|
|
302
|
+
|
|
303
|
+
initFixes({
|
|
304
|
+
disableConsistantReadWhenUsingIndexes: {
|
|
305
|
+
enabled: true, // default,
|
|
306
|
+
|
|
307
|
+
// Won't disable ConsistantRead if IndexName is specified here.
|
|
308
|
+
stillUseOnLocalIndexes: ["localIndexName1", "localIndexName1"],
|
|
309
|
+
},
|
|
310
|
+
});
|
|
311
|
+
```
|
|
312
|
+
|
|
278
313
|
## What are the benefits and why should I use it?
|
|
279
314
|
|
|
280
315
|
Generally it makes it easier to interact with the dynamodb from AWS. Here are some before and after examples using the new aws-sdk v3:
|