UNPKG

@sugarcoated/fondant-query

Version:
316 lines (279 loc) 7.76 kB
/** * Declaration of the Query class. Query makes parsing query strings manageable * without manipulating strings manually. * * @fileoverview Query. Manageable query strings. * @author Joshua Crowe, Junior Web Developer. * @copyright Joshua Crowe, 2017. */ /** * Query makes query strings manageable. * * @class Query * @classdesc Query string manager. */ class Query extends Actionable { /** * @property pointer * @description Indicator of a query string. * @type {String} */ set pointer (pointerChange) { this._queryPointer = pointerChange return this._queryPointer } /** * @property pointer * @description Indicator of a query string. * @type {String} */ get pointer () { return this._queryPointer } /** * @property seperator * @description Seperator between KVP. * @type {String} */ set seperator (seperatorChange) { this._querySeperator = seperatorChange return this._querySeperator } /** * @property seperator * @description Seperator between KVP. * @type {String} */ get seperator () { return this._querySeperator } /** * @property items * @description KVP. * @type {Collection} */ get items () { return this._queryItems } /** * Create a new Query. * * @name Query#constructor * @example new Query('&&', '?') * @param {String} [querySeperator] Seperator of each KVP. * @param {String} [queryPointer] Identifer for the query. * @returns {Query} */ constructor (querySeperator = '&&', queryPointer = '?') { super(['Insertion', 'Extraction', 'Parsed', 'Stringification']) /** * @property _queryPointer * @description Identifier for the query. * @type {String} * @private */ this._queryPointer = queryPointer /** * @property _querySeperator * @description Seperator of each KVP. * @type {String} * @private */ this._querySeperator = querySeperator /** * @property _queryItems * @description KVPs. * @type {Collection} * @private */ this._queryItems = new Collection() } /** * Insert a new item into the Query. * * @name Query#insert * @example myQuery.insert(myKey) * @param {Key} insertKey Key to insert. * @param {String} insertKey.keyName Name of the Key. * @param {String} insertKey.keyValue Value of the Key. * @param {Date} insertKey.keyCreated Creation date of the Key. * @returns {Key} */ insert ({keyName, keyValue, keyCreated}) { /** * @const insertItems * @description Object reference to the items. * @type {Collection} */ const insertItems = this._queryItems insertItems.add(keyName, keyValue) /** * @const insertKey * @description Key mirror. * @type {Key} */ const insertKey = new Key(keyName, keyValue, keyCreated) this.run('Insertion', insertKey) return insertKey } /** * Handle the insertion event. * * @name Query#insertion * @example myQuery.insertion(() => {}) * @param {Function} insertionHandler Handler for the insertion event. * @returns {Void} */ insertion (insertionHandler) { this.on('Insertion', insertionHandler, this) } /** * Extract a Key from the Query. * * @name Query#extract * @example myQuery.extract('myKey') * @param {String} extractName Name of the Key to extract. * @returns {Key} */ extract (extractName) { /** * @const extractItems * @description Object reference to the items of the Query. * @type {Collection} */ const extractItems = this._queryItems /** * @const extractFound * @description Found value inside the items Collection. * @type {String} */ const extractFound = extractItems.get(extractName) /** * @const extractKey * @description Key to represent that found. * @type {Key} */ const extractKey = new Key(extractName, extractFound) extractItems.delete(extractName) this.run('Extraction', extractKey) return extractKey } /** * Handle the extraction event. * * @name Query#extraction * @example myQuery.extraction(() => {}) * @param {Function} extractionHandler Handler for the extraction event. * @returns {Void} */ extraction (extractionHandler) { this.on('Extraction', extractionHandler, this) } /** * Parse a query string. * * @name Query#parse * @example myQuery.parse('?x=1&&y=2') * @param {String} parseString Query string to parse. * @returns {Collection} */ parse (parseString) { /** * @const parsePointer * @description Pointer of the Query. * @type {String} */ const parsePointer = this._queryPointer if (parseString.startsWith(parsePointer)) { parseString = parseString.substring(1) } /** * @const parseSeperator * @description Seperator of the Query. * @type {String} */ const parseSeperator = this._querySeperator /** * @const parseSplit * @description Split of the string into KVP as Strings. * @type {Array.<String>} */ const parseSplit = parseString.split(parseSeperator) /** * @const parseMap * @description Splitting String KVP into literal KVP. * @type {Array.<Array.<String, String>>} */ const parseMap = parseSplit.map(s => s.split('=')) this._queryItems = new Collection(parseMap) this.run('Parsed', this._queryItems) return this._queryItems } /** * Handle the parsed event. * * @name Query#parsed * @example myQuery.parsed(() => {}) * @param {Function} parsedHandler Handler for the parsed event. * @returns {Void} */ parsed (parsedHandler) { this.on('Parsed', parsedHandler, this) } /** * Stringify the query. * * @name Query#stringify * @example myQuery.stringify() * @param {Void} * @returns {String} */ stringify () { /** * @const stringifyItems * @description Object reference to the items Collection. * @type {Collection} */ const stringifyItems = this._queryItems /** * @const stringifySeperator * @description Seperator of the Query. * @type {String} */ const stringifySeperator = this._querySeperator /** * @const stringifyPointer * @description Pointer of the Query. * @type {String} */ const stringifyPointer = this._queryPointer /** * @const stringifyReduction * @description Concatenation of full query string. * @type {String} */ const stringifyReduction = stringifyItems.items.reduce(stringifyItem => { return `${stringifyItem[0]}=${stringifyItem[1]}${stringifySeperator}` }) /** * @const stringifyConcatenation * @description Concatenation with the Pointer. * @type {String} */ const stringifyConcatenation = `${stringifyPointer}${stringifyReduction}` this.run('Stringified', stringifyConcatenation) return stringifyConcatenation } /** * Handle the stringified event. * * @name Query#stringified * @example myQuery.stringified(() => {}) * @param {Function} stringifiedHandler Handler for the stringified event. * @returns {Void} */ stringified (stringifiedHandler) { this.on('Stringified', stringifiedHandler, this) } } module.exports = Query;