Skip to content

Commit c6fa0e8

Browse files
committed
feat: DynamoDBProvider
1 parent 4ee554d commit c6fa0e8

File tree

3 files changed

+405
-26
lines changed

3 files changed

+405
-26
lines changed

Diff for: packages/parameters/src/DynamoDBProvider.ts

+46-9
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,22 @@ class DynamoDBProvider extends BaseProvider {
2727
if (config.valueAttr) this.valueAttr = config.valueAttr;
2828
}
2929

30+
public async get(name: string, options?: DynamoDBGetOptionsInterface): Promise<undefined | string | Record<string, unknown>> {
31+
return super.get(name, options);
32+
}
33+
34+
public async getMultiple(path: string, options?: DynamoDBGetMultipleOptionsInterface): Promise<undefined | Record<string, unknown>> {
35+
return super.getMultiple(path, options);
36+
}
37+
3038
protected async _get(name: string, options?: DynamoDBGetOptionsInterface): Promise<string | undefined> {
3139
const sdkOptions: GetItemCommandInput = {
3240
TableName: this.tableName,
3341
Key: marshall({ [this.keyAttr]: name }),
42+
ProjectionExpression: this.valueAttr,
3443
};
35-
if (options && options.hasOwnProperty('sdkOptions')) {
36-
// Explicit arguments passed to the constructor will take precedence over ones passed to the method
37-
delete options.sdkOptions?.Key;
38-
// TODO: check if TableName is overridable
44+
if (options && options.sdkOptions) {
45+
this.removeNonOverridableOptions(options.sdkOptions as GetItemCommandInput);
3946
Object.assign(sdkOptions, options.sdkOptions);
4047
}
4148
const result = await this.client.send(new GetItemCommand(sdkOptions));
@@ -48,14 +55,13 @@ class DynamoDBProvider extends BaseProvider {
4855
TableName: this.tableName,
4956
KeyConditionExpression: `${this.keyAttr} = :key`,
5057
ExpressionAttributeValues: marshall({ ':key': path }),
58+
ProjectionExpression: `${this.sortAttr}, ${this.valueAttr}`,
5159
};
5260
const paginationOptions: PaginationConfiguration = {
5361
client: this.client,
5462
};
55-
if (options && options.hasOwnProperty('sdkOptions')) {
56-
// Explicit arguments passed to the constructor will take precedence over ones passed to the method
57-
delete options.sdkOptions?.KeyConditionExpression;
58-
delete options.sdkOptions?.ExpressionAttributeValues;
63+
if (options && options.sdkOptions) {
64+
this.removeNonOverridableOptions(options.sdkOptions as QueryCommandInput);
5965
if (options.sdkOptions?.hasOwnProperty('Limit')) {
6066
paginationOptions.pageSize = options.sdkOptions.Limit;
6167
}
@@ -66,12 +72,43 @@ class DynamoDBProvider extends BaseProvider {
6672
for await (const page of paginateQuery(paginationOptions, sdkOptions)) {
6773
for (const item of page.Items || []) {
6874
const unmarshalledItem = unmarshall(item);
69-
parameters[unmarshalledItem[this.keyAttr]] = unmarshalledItem[this.valueAttr];
75+
parameters[unmarshalledItem[this.sortAttr]] = unmarshalledItem[this.valueAttr];
7076
}
7177
}
7278

7379
return parameters;
7480
}
81+
82+
/**
83+
* This method is used as a type guard to narrow down the type of the options object.
84+
*/
85+
protected isGetItemCommandInput(options: GetItemCommandInput | QueryCommandInput): options is GetItemCommandInput {
86+
return (options as GetItemCommandInput).Key !== undefined;
87+
}
88+
89+
/**
90+
* Explicit arguments passed to the constructor will take precedence over ones passed to the method.
91+
* For users who consume the library with TypeScript, this will be enforced by the type system. However,
92+
* for JavaScript users, we need to manually delete the properties that are not allowed to be overridden.
93+
*/
94+
protected removeNonOverridableOptions(options: GetItemCommandInput | QueryCommandInput): void {
95+
if (options.hasOwnProperty('TableName')) {
96+
delete options.TableName;
97+
}
98+
if (options.hasOwnProperty('ProjectionExpression')) {
99+
delete options.ProjectionExpression;
100+
}
101+
if (options.hasOwnProperty('Key') && this.isGetItemCommandInput(options)) {
102+
delete options.Key;
103+
} else if (options.hasOwnProperty('KeyConditionExpression') && !this.isGetItemCommandInput(options)) {
104+
if (options.hasOwnProperty('KeyConditionExpression')) {
105+
delete options.KeyConditionExpression;
106+
}
107+
if (options.hasOwnProperty('ExpressionAttributeValues')) {
108+
delete options.ExpressionAttributeValues;
109+
}
110+
}
111+
}
75112
}
76113

77114
export {

Diff for: packages/parameters/src/types/DynamoDBProvider.ts

+10-6
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,16 @@ interface DynamoDBProviderOptions {
2222
clientConfig?: DynamoDBClientConfig
2323
}
2424

25-
interface DynamoDBGetOptionsInterface {
26-
maxAge?: number
27-
forceFetch?: boolean
28-
decrypt?: boolean
29-
transform?: TransformOptions
30-
sdkOptions?: Partial<GetItemCommandInput>
25+
/**
26+
* Options for the DynamoDBProvider get method.
27+
*
28+
* @interface DynamoDBGetOptionsInterface
29+
* @extends {GetOptionsInterface}
30+
* @property {boolean} decrypt - If true, the parameter will be decrypted.
31+
* @property {Partial<GetItemCommandInput>} sdkOptions - Options for the AWS SDK.
32+
*/
33+
interface DynamoDBGetOptionsInterface extends GetBaseOptionsInterface {
34+
sdkOptions?: Omit<Partial<GetItemCommandInput>, 'Key' | 'TableName' | 'ProjectionExpression'>
3135
}
3236

3337
interface DynamoDBGetMultipleOptionsInterface extends GetMultipleBaseOptionsInterface {

0 commit comments

Comments
 (0)