Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(parameters): stronger types for SSM getParameter #1387

Merged
merged 5 commits into from
Apr 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 24 additions & 20 deletions packages/parameters/src/ssm/SSMProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,12 @@ import type {
} from '@aws-sdk/client-ssm';
import type {
SSMProviderOptions,
SSMGetMultipleOptionsInterface,
SSMGetOptionsInterface,
SSMGetOptions,
SSMGetOutput,
SSMGetMultipleOptions,
SSMGetMultipleOptionsUnion,
SSMGetMultipleOutput,
SSMGetParametersByNameOutput,
SSMGetParametersByNameOutputInterface,
SSMGetParametersByNameOptionsInterface,
SSMSplitBatchAndDecryptParametersOutputType,
Expand Down Expand Up @@ -312,14 +316,14 @@ class SSMProvider extends BaseProvider {
* For usage examples check {@link SSMProvider}.
*
* @param {string} name - The name of the value to retrieve (i.e. the partition key)
* @param {SSMGetOptionsInterface} options - Options to configure the provider
* @param {SSMGetOptions} options - Options to configure the provider
* @see https://awslabs.github.io/aws-lambda-powertools-typescript/latest/utilities/parameters/
*/
public async get(
public async get<T = undefined, O extends SSMGetOptions | undefined = SSMGetOptions>(
name: string,
options?: SSMGetOptionsInterface | undefined
): Promise<string | Record<string, unknown> | undefined> {
return super.get(name, options) as Promise<string | Record<string, unknown> | undefined>;
options?: O & SSMGetOptions
): Promise<SSMGetOutput<T, O> | undefined> {
return super.get(name, options) as Promise<SSMGetOutput<T, O> | undefined>;
}

/**
Expand Down Expand Up @@ -349,14 +353,14 @@ class SSMProvider extends BaseProvider {
* For usage examples check {@link SSMProvider}.
*
* @param {string} path - The path of the parameters to retrieve
* @param {SSMGetMultipleOptionsInterface} options - Options to configure the retrieval
* @param {SSMGetMultipleOptions} options - Options to configure the retrieval
* @see https://awslabs.github.io/aws-lambda-powertools-typescript/latest/utilities/parameters/
*/
public async getMultiple(
public async getMultiple<T = undefined, O extends SSMGetMultipleOptionsUnion | undefined = undefined>(
path: string,
options?: SSMGetMultipleOptionsInterface | undefined
): Promise<undefined | Record<string, unknown>> {
return super.getMultiple(path, options);
options?: O & SSMGetMultipleOptions
): Promise<SSMGetMultipleOutput<T, O> | undefined> {
return super.getMultiple(path, options) as Promise<SSMGetMultipleOutput<T, O> | undefined>;
}

/**
Expand Down Expand Up @@ -409,10 +413,10 @@ class SSMProvider extends BaseProvider {
* @param {SSMGetParametersByNameOptionsInterface} options - Options to configure the retrieval
* @see https://awslabs.github.io/aws-lambda-powertools-typescript/latest/utilities/parameters/
*/
public async getParametersByName(
public async getParametersByName<T = undefined>(
parameters: Record<string, SSMGetParametersByNameOptionsInterface>,
options?: SSMGetParametersByNameOptionsInterface
): Promise<Record<string, unknown>> {
): Promise<SSMGetParametersByNameOutput<T>> {
const configs = { ...{
decrypt: this.resolveDecryptionConfigValue({}) || false,
maxAge: DEFAULT_MAX_AGE_SECS,
Expand Down Expand Up @@ -460,18 +464,18 @@ class SSMProvider extends BaseProvider {
}
}

return response;
return response as unknown as Promise<SSMGetParametersByNameOutput<T>>;
}

/**
* Retrieve a parameter from AWS Systems Manager.
*
* @param {string} name - Name of the parameter to retrieve
* @param {SSMGetOptionsInterface} options - Options to customize the retrieval
* @param {SSMGetOptions} options - Options to customize the retrieval
*/
protected async _get(
name: string,
options?: SSMGetOptionsInterface
options?: SSMGetOptions
): Promise<string | undefined> {
const sdkOptions: GetParameterCommandInput = {
...(options?.sdkOptions || {}),
Expand All @@ -487,11 +491,11 @@ class SSMProvider extends BaseProvider {
* Retrieve multiple items from AWS Systems Manager.
*
* @param {string} path - The path of the parameters to retrieve
* @param {SSMGetMultipleOptionsInterface} options - Options to configure the provider
* @param {SSMGetMultipleOptions} options - Options to configure the provider
*/
protected async _getMultiple(
path: string,
options?: SSMGetMultipleOptionsInterface
options?: SSMGetMultipleOptions
): Promise<Record<string, string | undefined>> {
const sdkOptions: GetParametersByPathCommandInput = {
...(options?.sdkOptions || {}),
Expand Down Expand Up @@ -733,7 +737,7 @@ class SSMProvider extends BaseProvider {
}

protected resolveDecryptionConfigValue(
options: SSMGetOptionsInterface | SSMGetMultipleOptionsInterface = {},
options: SSMGetOptions | SSMGetMultipleOptions = {},
sdkOptions?: GetParameterCommandInput | GetParametersByPathCommandInput
): boolean | undefined {
if (options?.decrypt !== undefined) return options.decrypt;
Expand Down
17 changes: 11 additions & 6 deletions packages/parameters/src/ssm/getParameter.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { SSMProvider, DEFAULT_PROVIDERS } from './SSMProvider';
import type { SSMGetOptionsInterface } from '../types/SSMProvider';
import type {
SSMGetOptions,
SSMGetOutput,
} from '../types/SSMProvider';

/**
* ## Intro
Expand Down Expand Up @@ -133,18 +136,20 @@ import type { SSMGetOptionsInterface } from '../types/SSMProvider';
* For more usage examples, see [our documentation](https://awslabs.github.io/aws-lambda-powertools-typescript/latest/utilities/parameters/).
*
* @param {string} name - The name of the parameter to retrieve
* @param {SSMGetOptionsInterface} options - Options to configure the provider
* @param {SSMGetOptions} options - Options to configure the provider
* @see https://awslabs.github.io/aws-lambda-powertools-typescript/latest/utilities/parameters/
*/
const getParameter = (
const getParameter = <T = undefined, O extends SSMGetOptions | undefined = SSMGetOptions>(
name: string,
options?: SSMGetOptionsInterface
): Promise<undefined | string | Record<string, unknown>> => {
options?: O & SSMGetOptions
): Promise<SSMGetOutput<T, O> | undefined> => {
if (!DEFAULT_PROVIDERS.hasOwnProperty('ssm')) {
DEFAULT_PROVIDERS.ssm = new SSMProvider();
}

return (DEFAULT_PROVIDERS.ssm as SSMProvider).get(name, options);
return (
DEFAULT_PROVIDERS.ssm as SSMProvider
).get(name, options) as Promise<SSMGetOutput<T, O> | undefined>;
};

export {
Expand Down
18 changes: 12 additions & 6 deletions packages/parameters/src/ssm/getParameters.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { SSMProvider, DEFAULT_PROVIDERS } from './SSMProvider';
import type { SSMGetMultipleOptionsInterface } from '../types/SSMProvider';
import type {
SSMGetMultipleOptions,
SSMGetMultipleOptionsUnion,
SSMGetMultipleOutput,
} from '../types/SSMProvider';

/**
* ## Intro
Expand Down Expand Up @@ -134,18 +138,20 @@ import type { SSMGetMultipleOptionsInterface } from '../types/SSMProvider';
* For more usage examples, see [our documentation](https://awslabs.github.io/aws-lambda-powertools-typescript/latest/utilities/parameters/).
*
* @param {string} path - The path of the parameters to retrieve
* @param {SSMGetMultipleOptionsInterface} options - Options to configure the provider
* @param {SSMGetMultipleOptions} options - Options to configure the provider
* @see https://awslabs.github.io/aws-lambda-powertools-typescript/latest/utilities/parameters/
*/
const getParameters = (
const getParameters = <T = undefined, O extends SSMGetMultipleOptionsUnion | undefined = SSMGetMultipleOptionsUnion>(
path: string,
options?: SSMGetMultipleOptionsInterface
): Promise<undefined | Record<string, unknown>> => {
options?: O & SSMGetMultipleOptions
): Promise<SSMGetMultipleOutput<T, O> | undefined> => {
if (!DEFAULT_PROVIDERS.hasOwnProperty('ssm')) {
DEFAULT_PROVIDERS.ssm = new SSMProvider();
}

return (DEFAULT_PROVIDERS.ssm as SSMProvider).getMultiple(path, options);
return (
DEFAULT_PROVIDERS.ssm as SSMProvider
).getMultiple(path, options) as Promise<SSMGetMultipleOutput<T, O> | undefined>;
};

export {
Expand Down
11 changes: 7 additions & 4 deletions packages/parameters/src/ssm/getParametersByName.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { SSMProvider, DEFAULT_PROVIDERS } from './SSMProvider';
import type {
SSMGetParametersByNameOptionsInterface
SSMGetParametersByNameOptionsInterface,
SSMGetParametersByNameOutput,
} from '../types/SSMProvider';

/**
Expand Down Expand Up @@ -160,15 +161,17 @@ import type {
* @param {SSMGetParametersByNameOptionsInterface} options - Options to configure the provider
* @see https://awslabs.github.io/aws-lambda-powertools-typescript/latest/utilities/parameters/
*/
const getParametersByName = (
const getParametersByName = <T = undefined>(
parameters: Record<string, SSMGetParametersByNameOptionsInterface>,
options?: SSMGetParametersByNameOptionsInterface
): Promise<Record<string, unknown> & { _errors?: string[] }> => {
): Promise<SSMGetParametersByNameOutput<T>> => {
if (!DEFAULT_PROVIDERS.hasOwnProperty('ssm')) {
DEFAULT_PROVIDERS.ssm = new SSMProvider();
}

return (DEFAULT_PROVIDERS.ssm as SSMProvider).getParametersByName(parameters, options);
return (
DEFAULT_PROVIDERS.ssm as SSMProvider
).getParametersByName(parameters, options) as Promise<SSMGetParametersByNameOutput<T>>;
};

export {
Expand Down
8 changes: 6 additions & 2 deletions packages/parameters/src/types/BaseProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ interface GetOptionsInterface {
*/
sdkOptions?: unknown
/**
* Transform to be applied, can be 'json', 'binary', or 'auto'.
* Transform to be applied, can be `json` or `binary`.
*/
transform?: TransformOptions
transform?: Omit<TransformOptions, 'auto'>
}

/**
Expand All @@ -40,6 +40,10 @@ interface GetOptionsInterface {
* @property {boolean} throwOnTransformError - Whether to throw an error if a value cannot be transformed.
*/
interface GetMultipleOptionsInterface extends GetOptionsInterface {
/**
* Transform to be applied, can be `json`, `binary`, or `auto`.
*/
transform?: TransformOptions
/**
* Whether to throw an error if a value cannot be transformed.
*/
Expand Down
101 changes: 94 additions & 7 deletions packages/parameters/src/types/SSMProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,46 @@ type SSMProviderOptions = SSMProviderOptionsWithClientConfig | SSMProviderOption
* @extends {GetOptionsInterface}
* @property {number} maxAge - Maximum age of the value in the cache, in seconds.
* @property {boolean} forceFetch - Force fetch the value from the parameter store, ignoring the cache.
* @property {GetItemCommandInput} [sdkOptions] - Additional options to pass to the AWS SDK v3 client.
* @property {GetItemCommandInput} [sdkOptions] - Additional options to pass to the AWS SDK v3 client. Supports all options from `GetParameterCommandInput`.
* @property {TransformOptions} transform - Transform to be applied, can be 'json' or 'binary'.
* @property {boolean} decrypt - If true, the parameter will be decrypted.
* @property {boolean} decrypt - If true, the parameter will be decrypted. Defaults to `false`.
*/
interface SSMGetOptionsInterface extends GetOptionsInterface {
interface SSMGetOptions extends GetOptionsInterface {
/**
* If true, the parameter will be decrypted. Defaults to `false`.
*/
decrypt?: boolean
/**
* Additional options to pass to the AWS SDK v3 client. Supports all options from `GetParameterCommandInput`.
*/
sdkOptions?: Partial<GetParameterCommandInput>

transform?: Exclude<TransformOptions, 'auto'>
}

interface SSMGetOptionsTransformJson extends SSMGetOptions {
transform: 'json'
}

interface SSMGetOptionsTransformBinary extends SSMGetOptions {
transform: 'binary'
}

interface SSMGetOptionsTransformNone extends SSMGetOptions {
transform?: never
}

/**
* Generic output type for the SSMProvider get method.
*/
type SSMGetOutput<T = undefined, O = undefined> =
undefined extends T ?
undefined extends O ? string :
O extends SSMGetOptionsTransformNone | SSMGetOptionsTransformBinary ? string :
O extends SSMGetOptionsTransformJson ? Record<string, unknown> :
never
: T;

/**
* Options for the SSMProvider getMultiple method.
*
Expand All @@ -72,13 +103,60 @@ interface SSMGetOptionsInterface extends GetOptionsInterface {
* @property {boolean} recursive - If true, the parameter will be fetched recursively.
* @property {boolean} throwOnTransformError - If true, the method will throw an error if the transform fails.
*/
interface SSMGetMultipleOptionsInterface extends GetMultipleOptionsInterface {
interface SSMGetMultipleOptions extends GetMultipleOptionsInterface {
/**
* Additional options to pass to the AWS SDK v3 client. Supports all options from `GetParametersByPathCommandInput`.
*/
sdkOptions?: Partial<GetParametersByPathCommandInput>
/**
* If true, the parameters will be decrypted. Defaults to `false`.
*/
decrypt?: boolean
/**
* If true, the parameters will be fetched recursively. Defaults to `false`.
*/
recursive?: boolean
/**
* If true, the method will throw an error if the transform fails.
*/
throwOnTransformError?: boolean
}

interface SSMGetMultipleOptionsTransformJson extends SSMGetMultipleOptions {
transform: 'json'
}

interface SSMGetMultipleOptionsTransformBinary extends SSMGetMultipleOptions {
transform: 'binary'
}

interface SSMGetMultipleOptionsTransformAuto extends SSMGetMultipleOptions {
transform: 'auto'
}

interface SSMGetMultipleOptionsTransformNone extends SSMGetMultipleOptions {
transform?: never
}

type SSMGetMultipleOptionsUnion =
SSMGetMultipleOptionsTransformJson |
SSMGetMultipleOptionsTransformBinary |
SSMGetMultipleOptionsTransformAuto |
SSMGetMultipleOptionsTransformNone |
undefined;

/**
* Generic output type for the SSMProvider getMultiple method.
*/
type SSMGetMultipleOutput<T = undefined, O = undefined> =
undefined extends T ?
undefined extends O ? Record<string, string> :
O extends SSMGetMultipleOptionsTransformNone | SSMGetMultipleOptionsTransformBinary ? Record<string, string> :
O extends SSMGetMultipleOptionsTransformAuto ? Record<string, unknown> :
O extends SSMGetMultipleOptionsTransformJson ? Record<string, Record<string, unknown>> :
never
: Record<string, T>;

/**
* Options for the SSMProvider getParametersByName method.
*
Expand All @@ -92,7 +170,7 @@ interface SSMGetParametersByNameOptionsInterface {
maxAge?: number
throwOnError?: boolean
decrypt?: boolean
transform?: TransformOptions
transform?: Exclude<TransformOptions, 'auto'>
}

/**
Expand All @@ -119,12 +197,21 @@ type SSMGetParametersByNameFromCacheOutputType = {
toFetch: Record<string, SSMGetParametersByNameOptionsInterface>
};

type SSMGetParametersByNameOutput<T = undefined> =
undefined extends T ?
Record<string, unknown> & { _errors?: string[] } :
Record<string, T> & { _errors?: string[] };

export type {
SSMProviderOptions,
SSMGetOptionsInterface,
SSMGetMultipleOptionsInterface,
SSMGetOptions,
SSMGetOutput,
SSMGetMultipleOptions,
SSMGetMultipleOptionsUnion,
SSMGetMultipleOutput,
SSMGetParametersByNameOptionsInterface,
SSMSplitBatchAndDecryptParametersOutputType,
SSMGetParametersByNameOutputInterface,
SSMGetParametersByNameFromCacheOutputType,
SSMGetParametersByNameOutput,
};
Loading