UNPKG

@sailplane/state-storage

Version:

Serverless state and configuration storage

96 lines (95 loc) 3.6 kB
// lib/state-storage.ts import { SSMClient, GetParameterCommand, PutParameterCommand } from "@aws-sdk/client-ssm"; import { Logger } from "@sailplane/logger"; var logger = new Logger("state-storage"); var StateStorage = class { /** * Construct * * @param namePrefix prefix string to start all parameter names with. * Should at least include the environment (dev/prod). * @param ssm the SSMClient to use */ constructor(namePrefix, ssm = new SSMClient({})) { this.namePrefix = namePrefix; this.ssm = ssm; if (!this.namePrefix.endsWith("/")) this.namePrefix = this.namePrefix + "/"; } /** * Save state for a later run. * * @param {string} service name of the service (class name?) that owns the state * @param {string} name name of the state variable to save * @param value content to save * @param optionsOrQuiet a StateStorageOptions, or if true sets quiet option. (For backward compatibility.) * @returns {Promise<void>} completes upon success - rejects if lacking ssm:PutParameter permission */ set(service, name, value, optionsOrQuiet = {}) { const options = optionsOrQuiet === true ? { quiet: true } : optionsOrQuiet; const key = this.generateName(service, name); const content = options.isRaw === true ? value : JSON.stringify(value); if (options.quiet || options.secure) { logger.info(`Saving state ${key}`); } else { logger.info(`Saving state ${key}=${content}`); } const command = new PutParameterCommand({ Name: key, Type: options.secure ? "SecureString" : "String", Value: content, Overwrite: true }); return this.ssm.send(command).then(() => void 0); } /** * Fetch last state saved. * * @param {string} service name of the service (class name?) that owns the state * @param {string} name name of the state variable to fetch * @param optionsOrQuiet a StateStorageOptions, or if true sets quiet option. (For backward compatibility.) * @returns {Promise<any>} completes with the saved value, or reject if not found or lacking ssm:GetParameter permission */ get(service, name, optionsOrQuiet = {}) { const options = optionsOrQuiet === true ? { quiet: true } : optionsOrQuiet; const key = this.generateName(service, name); const command = new GetParameterCommand({ Name: key, WithDecryption: options.secure }); return this.ssm.send(command).then((result) => { const content = result && result.Parameter ? result.Parameter.Value : void 0; if (options.quiet || options.secure) { logger.info(`Loaded state ${key}`); } else { logger.info(`Loaded state ${key}=${content}`); } return options.isRaw ? content : content ? JSON.parse(content) : void 0; }); } generateName(service, name) { return this.namePrefix + service + "/" + name; } }; // lib/state-storage-fake.ts var StateStorageFake = class extends StateStorage { constructor(namePrefix) { super(namePrefix); this.storage = {}; } set(service, name, value, _options) { const key = this.generateName(service, name); this.storage[key] = JSON.stringify(value); return Promise.resolve(); } get(service, name, _options) { const key = this.generateName(service, name); const content = this.storage[key]; if (content) return Promise.resolve(JSON.parse(content)); else return Promise.reject(new Error("mock StateStorage.get not found: " + key)); } }; export { StateStorage, StateStorageFake }; //# sourceMappingURL=index.mjs.map