Skip to content

Commit

Permalink
feat: DynamoDBProvider
Browse files Browse the repository at this point in the history
  • Loading branch information
dreamorosi committed Dec 29, 2022
1 parent 7af3fee commit 0aa6b56
Show file tree
Hide file tree
Showing 3 changed files with 405 additions and 26 deletions.
55 changes: 46 additions & 9 deletions packages/parameters/src/DynamoDBProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,22 @@ class DynamoDBProvider extends BaseProvider {
if (config.valueAttr) this.valueAttr = config.valueAttr;
}

public async get(name: string, options?: DynamoDBGetOptionsInterface): Promise<undefined | string | Record<string, unknown>> {
return super.get(name, options);
}

public async getMultiple(path: string, options?: DynamoDBGetMultipleOptionsInterface): Promise<undefined | Record<string, unknown>> {
return super.getMultiple(path, options);
}

protected async _get(name: string, options?: DynamoDBGetOptionsInterface): Promise<string | undefined> {
const sdkOptions: GetItemCommandInput = {
TableName: this.tableName,
Key: marshall({ [this.keyAttr]: name }),
ProjectionExpression: this.valueAttr,
};
if (options && options.hasOwnProperty('sdkOptions')) {
// Explicit arguments passed to the constructor will take precedence over ones passed to the method
delete options.sdkOptions?.Key;
// TODO: check if TableName is overridable
if (options && options.sdkOptions) {
this.removeNonOverridableOptions(options.sdkOptions as GetItemCommandInput);
Object.assign(sdkOptions, options.sdkOptions);
}
const result = await this.client.send(new GetItemCommand(sdkOptions));
Expand All @@ -48,14 +55,13 @@ class DynamoDBProvider extends BaseProvider {
TableName: this.tableName,
KeyConditionExpression: `${this.keyAttr} = :key`,
ExpressionAttributeValues: marshall({ ':key': path }),
ProjectionExpression: `${this.sortAttr}, ${this.valueAttr}`,
};
const paginationOptions: PaginationConfiguration = {
client: this.client,
};
if (options && options.hasOwnProperty('sdkOptions')) {
// Explicit arguments passed to the constructor will take precedence over ones passed to the method
delete options.sdkOptions?.KeyConditionExpression;
delete options.sdkOptions?.ExpressionAttributeValues;
if (options && options.sdkOptions) {
this.removeNonOverridableOptions(options.sdkOptions as QueryCommandInput);
if (options.sdkOptions?.hasOwnProperty('Limit')) {
paginationOptions.pageSize = options.sdkOptions.Limit;
}
Expand All @@ -66,12 +72,43 @@ class DynamoDBProvider extends BaseProvider {
for await (const page of paginateQuery(paginationOptions, sdkOptions)) {
for (const item of page.Items || []) {
const unmarshalledItem = unmarshall(item);
parameters[unmarshalledItem[this.keyAttr]] = unmarshalledItem[this.valueAttr];
parameters[unmarshalledItem[this.sortAttr]] = unmarshalledItem[this.valueAttr];
}
}

return parameters;
}

/**
* This method is used as a type guard to narrow down the type of the options object.
*/
protected isGetItemCommandInput(options: GetItemCommandInput | QueryCommandInput): options is GetItemCommandInput {
return (options as GetItemCommandInput).Key !== undefined;
}

/**
* Explicit arguments passed to the constructor will take precedence over ones passed to the method.
* For users who consume the library with TypeScript, this will be enforced by the type system. However,
* for JavaScript users, we need to manually delete the properties that are not allowed to be overridden.
*/
protected removeNonOverridableOptions(options: GetItemCommandInput | QueryCommandInput): void {
if (options.hasOwnProperty('TableName')) {
delete options.TableName;
}
if (options.hasOwnProperty('ProjectionExpression')) {
delete options.ProjectionExpression;
}
if (options.hasOwnProperty('Key') && this.isGetItemCommandInput(options)) {
delete options.Key;
} else if (options.hasOwnProperty('KeyConditionExpression') && !this.isGetItemCommandInput(options)) {
if (options.hasOwnProperty('KeyConditionExpression')) {
delete options.KeyConditionExpression;
}
if (options.hasOwnProperty('ExpressionAttributeValues')) {
delete options.ExpressionAttributeValues;
}
}
}
}

export {
Expand Down
16 changes: 10 additions & 6 deletions packages/parameters/src/types/DynamoDBProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,16 @@ interface DynamoDBProviderOptions {
clientConfig?: DynamoDBClientConfig
}

interface DynamoDBGetOptionsInterface {
maxAge?: number
forceFetch?: boolean
decrypt?: boolean
transform?: TransformOptions
sdkOptions?: Partial<GetItemCommandInput>
/**
* Options for the DynamoDBProvider get method.
*
* @interface DynamoDBGetOptionsInterface
* @extends {GetOptionsInterface}
* @property {boolean} decrypt - If true, the parameter will be decrypted.
* @property {Partial<GetItemCommandInput>} sdkOptions - Options for the AWS SDK.
*/
interface DynamoDBGetOptionsInterface extends GetBaseOptionsInterface {
sdkOptions?: Omit<Partial<GetItemCommandInput>, 'Key' | 'TableName' | 'ProjectionExpression'>
}

interface DynamoDBGetMultipleOptionsInterface extends GetMultipleBaseOptionsInterface {
Expand Down

0 comments on commit 0aa6b56

Please sign in to comment.