@bifravst/aws-ssm-settings-helpers
Advanced tools
Comparing version 1.0.1 to 1.0.2
import { SSMClient } from '@aws-sdk/client-ssm'; | ||
export declare const settingsPath: ({ stackName, scope, context, property, }: { | ||
type ParameterNameArgs = { | ||
stackName: string; | ||
scope: string; | ||
} | { | ||
stackName: string; | ||
scope: string; | ||
context: string; | ||
property?: string | undefined; | ||
}) => string; | ||
export declare const getSettings: <Settings extends Record<string, string>>({ ssm, stackName, scope, context, }: { | ||
ssm: SSMClient; | ||
} | { | ||
stackName: string; | ||
scope: string; | ||
context: string; | ||
}) => () => Promise<Settings>; | ||
export declare const putSettings: ({ ssm, stackName, scope, context, }: { | ||
ssm: SSMClient; | ||
property: string; | ||
}; | ||
export declare const settingsPath: (args: ParameterNameArgs) => string; | ||
export declare const get: (ssm: SSMClient) => <Settings extends Record<string, string>>({ stackName, ...nameParams }: { | ||
stackName: string; | ||
} & ParameterNameArgs) => () => Promise<Settings>; | ||
export declare const put: (ssm: SSMClient) => ({ stackName, scope, context, }: { | ||
stackName: string; | ||
scope: string; | ||
@@ -29,4 +33,3 @@ context: string; | ||
}>; | ||
export declare const deleteSettings: ({ ssm, stackName, scope, context, }: { | ||
ssm: SSMClient; | ||
export declare const remove: (ssm: SSMClient) => ({ stackName, scope, context, }: { | ||
stackName: string; | ||
@@ -40,2 +43,3 @@ scope: string; | ||
}>; | ||
export declare const getSettingsOptional: <Settings extends Record<string, string>, Default>(args: Parameters<typeof getSettings>[0]) => (defaultValue: Default) => Promise<Settings | Default>; | ||
export declare const maybe: (ssm: SSMClient) => <Settings extends Record<string, string>>(args: ParameterNameArgs) => Promise<Settings | null>; | ||
export {}; |
import { DeleteParameterCommand, GetParametersByPathCommand, PutParameterCommand, SSMClient, } from '@aws-sdk/client-ssm'; | ||
import { paginate } from './paginate.js'; | ||
const nameRx = /^[a-zA-Z0-9_.-]+$/; | ||
export const settingsPath = ({ stackName, scope, context, property, }) => { | ||
export const settingsPath = (args) => { | ||
const { stackName, scope } = args; | ||
if (!nameRx.test(stackName)) | ||
@@ -9,14 +10,19 @@ throw new Error(`Invalid stackName value: ${stackName}!`); | ||
throw new Error(`Invalid scope value: ${scope}!`); | ||
if (!nameRx.test(context)) | ||
throw new Error(`Invalid context value: ${context}!`); | ||
const parts = [stackName, scope, context]; | ||
if (property !== undefined) { | ||
if (!nameRx.test(property)) | ||
throw new Error(`Invalid property value: ${property}!`); | ||
parts.push(property); | ||
const parts = [stackName, scope]; | ||
if ('context' in args) { | ||
if (!nameRx.test(args.context)) | ||
throw new Error(`Invalid context value: ${args.context}!`); | ||
parts.push(args.context); | ||
} | ||
if ('property' in args) { | ||
if (!('context' in args)) | ||
throw new Error(`Missing context!`); | ||
if (!nameRx.test(args.property)) | ||
throw new Error(`Invalid property value: ${args.property}!`); | ||
parts.push(args.property); | ||
} | ||
return `/${parts.join('/')}`; | ||
}; | ||
export const getSettings = ({ ssm, stackName, scope, context, }) => async () => { | ||
const Path = settingsPath({ stackName, scope, context }); | ||
export const get = (ssm) => ({ stackName, ...nameParams }) => async () => { | ||
const Path = settingsPath({ stackName, ...nameParams }); | ||
const Parameters = []; | ||
@@ -46,3 +52,3 @@ await paginate({ | ||
}; | ||
export const putSettings = ({ ssm, stackName, scope, context, }) => async ({ property, value, deleteBeforeUpdate, }) => { | ||
export const put = (ssm) => ({ stackName, scope, context, }) => async ({ property, value, deleteBeforeUpdate, }) => { | ||
const Name = settingsPath({ stackName, scope, context, property }); | ||
@@ -67,3 +73,3 @@ if (deleteBeforeUpdate ?? false) { | ||
}; | ||
export const deleteSettings = ({ ssm, stackName, scope, context, }) => async ({ property }) => { | ||
export const remove = (ssm) => ({ stackName, scope, context, }) => async ({ property }) => { | ||
const Name = settingsPath({ stackName, scope, context, property }); | ||
@@ -85,13 +91,13 @@ try { | ||
}; | ||
export const getSettingsOptional = (args) => | ||
export const maybe = (ssm) => | ||
/** | ||
* In case of an unconfigured stack, returns default values | ||
*/ | ||
async (defaultValue) => { | ||
async (args) => { | ||
try { | ||
return await getSettings(args)(); | ||
return await get(ssm)(args)(); | ||
} | ||
catch { | ||
return defaultValue; | ||
return null; | ||
} | ||
}; |
import { describe, it } from 'node:test'; | ||
import assert from 'node:assert/strict'; | ||
import { getSettingsOptional, settingsPath, getSettings } from './settings.js'; | ||
void describe('getSettingsOptional()', () => { | ||
import { maybe, settingsPath, get } from './settings.js'; | ||
void describe('maybe()', () => { | ||
void it('should return the given default value if parameter does not exist', async () => { | ||
const stackConfig = getSettingsOptional({ | ||
ssm: { | ||
send: async () => Promise.resolve({ Parameters: undefined }), | ||
}, | ||
const stackConfig = await maybe({ | ||
send: async () => Promise.resolve({ Parameters: undefined }), | ||
})({ | ||
stackName: 'STACK_NAME', | ||
@@ -14,4 +13,3 @@ scope: 'stack', | ||
}); | ||
const result = await stackConfig({}); | ||
assert.deepEqual(result, {}); | ||
assert.equal(stackConfig, null); | ||
}); | ||
@@ -26,2 +24,11 @@ }); | ||
}), '/hello-nrfcloud/stack/context/someProperty')); | ||
void it('should produce a fully qualified parameter name (without a context)', () => assert.equal(settingsPath({ | ||
scope: 'stack', | ||
stackName: 'hello-nrfcloud', | ||
}), '/hello-nrfcloud/stack')); | ||
void it('should not allow parameter without context', () => assert.throws(() => settingsPath({ | ||
scope: 'stack', | ||
stackName: 'hello-nrfcloud', | ||
property: 'foo', | ||
}), /Missing context!/)); | ||
void it('should produce a fully qualified parameter name for valid string scope', () => assert.equal(settingsPath({ | ||
@@ -42,3 +49,3 @@ scope: 'thirdParty', | ||
}); | ||
void describe('getSettings()', () => { | ||
void describe('get()', () => { | ||
void it('should return the object with same scope', async () => { | ||
@@ -59,6 +66,5 @@ const returnedValues = [ | ||
]; | ||
const stackConfig = getSettings({ | ||
ssm: { | ||
send: async () => Promise.resolve({ Parameters: returnedValues }), | ||
}, | ||
const stackConfig = get({ | ||
send: async () => Promise.resolve({ Parameters: returnedValues }), | ||
})({ | ||
stackName: 'hello-nrfcloud', | ||
@@ -65,0 +71,0 @@ scope: 'stack', |
{ | ||
"name": "@bifravst/aws-ssm-settings-helpers", | ||
"version": "1.0.1", | ||
"version": "1.0.2", | ||
"description": "Helper functions written in TypeScript for storing and retrieving application settings in AWS SSM Parameter Store.", | ||
@@ -5,0 +5,0 @@ "exports": { |
13473
251