UNPKG

@barchart/common-node-js

Version:

Common classes, utilities, and functions for building Node.js servers

214 lines (176 loc) 6.4 kB
const assert = require('@barchart/common-js/lang/assert'); const Index = require('./../definitions/Index'), IndexType = require('./../definitions/IndexType'), Projection = require('./../definitions/Projection'), ProjectionType = require('./../definitions/ProjectionType'); const KeyBuilder = require('./KeyBuilder'), ProjectionBuilder = require('./ProjectionBuilder'), ProvisionedThroughputBuilder = require('./ProvisionedThroughputBuilder'); const LambdaStage = require('../../../lambda/LambdaStage'); const Table = require("../definitions/Table"); module.exports = (() => { 'use strict'; /** * Fluent interface for building an {@link Index}. * * @public * @param {string} name * @param {TableBuilder} parent */ class IndexBuilder { constructor(name, parent) { assert.argumentIsRequired(name, 'name', String); this._index = new Index(name, null, [ ], null, null); this._parent = parent; } /** * The {@link Index}, given all the information provided thus far. * * @public * @returns {Index} */ get index() { return this._index; } /** * Adds a logic for specific environment (via a callback that fires * if the current configuration applies to the desired environment). * * @public * @param {LambdaStage} stage * @param {IndexBuilder~stageCallback} callback * @return {IndexBuilder} */ forStage(stage, callback) { assert.argumentIsRequired(stage, 'stage', LambdaStage, 'LambdaStage'); assert.argumentIsRequired(callback, 'callback', Function); if (LambdaStage.getStageFromName(this._parent.table.name) === stage) { callback(this); } return this; } /** * Sets the {@link IndexType} and returns the current instance. * * @public * @param {IndexType} type * @returns {IndexBuilder} */ withType(type) { assert.argumentIsRequired(type, 'type', IndexType, 'IndexType'); this._index = new Index(this._index.name, type, this._index.keys, this._index.projection, this._index.provisionedThroughput); return this; } /** * Adds a {@link Key} to the index, given all the components of an * key, then returns the current instance. * * @public * @param {string} name - The key name. * @param {KeyType} keyType * @returns {IndexBuilder} */ withKey(name, keyType) { return this.withKeyBuilder(name, kb => kb.withKeyType(keyType)); } /** * Adds an {@link Key} to the index, using a callback that * provides the consumer with a {@KeyBuilder}, then returns * the current instance. * * @public * @param {string} name - The key name. * @param {Function} callback - Synchronously called, providing a {@link KeyBuilder} tied to the current instance. * @returns {IndexBuilder} */ withKeyBuilder(name, callback) { assert.argumentIsRequired(callback, 'callback', Function); const keyBuilder = new KeyBuilder(name, this._parent); callback(keyBuilder); const key = keyBuilder.key; const keys = this._index.keys.filter(k => k.attribute.name !== key.attribute.name).concat(key); this._index = new Index(this._index.name, this._index.type, keys, this._index.projection, this._index.provisionedThroughput); return this; } /** * Adds a {@link Projection} to the index, given all the components * of a projection, then returns the current instance. * * @public * @param {ProjectionType} projectionType * @param {Array<String>=} attributeNames * @returns {IndexBuilder} */ withProjection(projectionType, attributeNames) { const namesToUse = attributeNames || [ ]; return this.withProjectionBuilder(projectionType, pb => namesToUse.forEach(n => pb.withAttribute(n))); } /** * Adds an {@link Projection} to the index, using a callback that * provides the consumer with a {@ProjectionBuilder}, then returns * the current instance. * * @public * @param {ProjectionType} projectionType * @param {Function} callback - Synchronously called, providing a {@link ProjectionBuilder} tied to the current instance. * @returns {IndexBuilder} */ withProjectionBuilder(projectionType, callback) { assert.argumentIsRequired(callback, 'callback', Function); const projectionBuilder = new ProjectionBuilder(projectionType, this._parent); callback(projectionBuilder); this._index = new Index(this._index.name, this._index.type, this._index.keys, projectionBuilder.projection, this._index.provisionedThroughput); return this; } /** * Adds a {@link ProvisionedThroughput} specification to the index * then returns the current instance. * * @public * @param {Number} readUnits * @param {Number} writeUnits * @returns {IndexBuilder} */ withProvisionedThroughput(readUnits, writeUnits) { const provisionedThroughputBuilder = new ProvisionedThroughputBuilder(readUnits, writeUnits); return this.withProvisionedThroughputBuilder(provisionedThroughputBuilder); } /** * Adds an {@link ProvisionedThroughput} specification to the index, using * a callback that provides the consumer with a {@ProvisionedThroughputBuilder}, * then returns the current instance. * * @public * @param {ProvisionedThroughputBuilder} provisionedThroughputBuilder * @returns {IndexBuilder} */ withProvisionedThroughputBuilder(provisionedThroughputBuilder) { assert.argumentIsRequired(provisionedThroughputBuilder, 'provisionedThroughputBuilder', ProvisionedThroughputBuilder, 'ProvisionedThroughputBuilder'); this._index = new Index(this._index.name, this._index.type, this._index.keys, this._index.projection, provisionedThroughputBuilder.provisionedThroughput); return this; } /** * Indicates the index should use on-demand throughput (i.e. pricing), instead of * provisioned throughput. * * @public * @returns {IndexBuilder} */ withOnDemandThroughput() { this._index = new Index(this._index.name, this._index.type, this._index.keys, this._index.projection, null); return this; } toString() { return '[IndexBuilder]'; } } /** * A callback that provides the consumer with an {@link IndexBuilder} -- assuming * the configuration applies to the correct environment (i.e. {@link LambdaStage}). * * @public * @callback IndexBuilder~stageCallback * @param {IndexBuilder} indexBuilder */ return IndexBuilder; })();