├── .coveralls.yml ├── .editorconfig ├── .eslintrc ├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── NestHydrationJS.js ├── README.md ├── package-lock.json ├── package.json └── spec ├── .eslintrc ├── NestHydrationJS ├── buildMeta.spec.js ├── nest.spec.js ├── registerType.spec.js ├── structPropToColumnMapFromColumnHints.spec.js └── typeHandlers.spec.js └── support └── jasmine.json /.coveralls.yml: -------------------------------------------------------------------------------- 1 | repo_token: 82ZdsghnaiT9pSt7CVPgsUMsrEFpwqjnC 2 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = tab 5 | charset = utf-8 6 | trim_trailing_whitespace = true 7 | insert_final_newline = true 8 | end_of_line = lf 9 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | --- 2 | env: 3 | es6: true 4 | node: true 5 | extends: 'eslint:recommended' 6 | rules: 7 | indent: 8 | - error 9 | - tab 10 | linebreak-style: 11 | - error 12 | - unix 13 | quotes: 14 | - error 15 | - single 16 | semi: 17 | - error 18 | - always 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | 3 | !/spec 4 | !/spec/** 5 | !/.coveralls.yml 6 | !/.editorconfig 7 | !/.eslintrc 8 | !/.travis.yml 9 | !/CHANGELOG.md 10 | !/NestHydrationJS.js 11 | !/package-lock.json 12 | !/package.json 13 | !/README.md 14 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | branches: 3 | only: 4 | - master 5 | - qc 6 | node_js: 7 | - "8" 8 | - "10" 9 | - "12" 10 | script: 11 | - npm test 12 | after_script: 13 | - npm run coverage 14 | - npm run coveralls 15 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | This project adheres to [Semantic Versioning](http://semver.org/). 5 | 6 | ## [2.0.0] - 2019-11-16 7 | 8 | No usage changes except removal of support for deprecated javascript engines. 9 | 10 | ### Fixed 11 | 12 | - devDependencies update 13 | - standardize README and CHANGELOG markdown styling 14 | 15 | ### Removed 16 | 17 | - Node.js <= 6 and IE <= 10 compatibility is no longer an objective of this library 18 | 19 | ## [1.0.6] - 2018-05-17 20 | 21 | ### Fixed 22 | 23 | - Fix coveralls builds using travis 24 | 25 | ## [1.0.5] - 2018-05-11 26 | 27 | ### Fixed 28 | 29 | - Use specific lodash components directly for smaller module size 30 | 31 | ## [1.0.4] - 2018-04-25 32 | 33 | ### Fixed 34 | 35 | - update dependencies 36 | - Update lodash to 4.17.5 to address security issue 37 | 38 | ## [1.0.3] - 2018-01-03 39 | 40 | ### Fixed 41 | 42 | - Fixed issue with null data and nested structure where error was thrown, thank you Tim de Koning 43 | 44 | ## [1.0.2] - 2017-03-18 45 | 46 | ### Fixed 47 | 48 | - Implements check for unsupported multiple ids 49 | 50 | ## [1.0.1] - 2017-02-28 51 | 52 | ### Fixed 53 | 54 | - Replace complete lodash with partial includes, thank you Saviio 55 | 56 | ## [1.0.0] - 2016-11-25 57 | 58 | ### Added 59 | 60 | - Uses export function to allowed scoped usage 61 | 62 | ## [0.4.0] 63 | 64 | ### Added 65 | 66 | - Support for specified ids properties and columns 67 | - Some general improvements to README 68 | - License changed to ISC 69 | 70 | ## [0.3.0] - 2016-06-07 71 | 72 | ### Added 73 | 74 | - Changelog 75 | - Custom types 76 | - Default values 77 | 78 | ## [0.2.13] - 2016-06-06 79 | 80 | ### Added 81 | 82 | - Added eslint checks 83 | 84 | ### Changed 85 | 86 | - Minor style and error fixes 87 | 88 | ## [0.2.12] - 2016-05-25 89 | 90 | ### Added 91 | 92 | - Added type constants 93 | 94 | ### Changed 95 | 96 | - Upgraded dependencies 97 | 98 | ## [0.2.11] - 2015-07-21 99 | 100 | ### Added 101 | 102 | - Coverage badge to README 103 | - Build status badge to README 104 | 105 | ## [0.2.9] - 2015-07-20 106 | 107 | ### Added 108 | 109 | - TravisCI build 110 | - Test coverage reporting 111 | 112 | ### Changed 113 | 114 | - Now throws errors instead of Strings 115 | 116 | ## [0.2.8] - 2015-07-20 117 | 118 | ### Fixed 119 | 120 | - Typo on column list length check 121 | 122 | ## [0.2.7] - 2015-07-20 123 | 124 | ### Changed 125 | 126 | - Updated lodash library 127 | 128 | ## [0.2.6] - 2015-07-20 129 | 130 | ### Changed 131 | 132 | - Updated q library 133 | 134 | ## [0.2.5] - 2015-07-19 135 | 136 | ### Changed 137 | 138 | - Performance improvements 139 | 140 | ## [0.2.4] - 2015-02-02 141 | 142 | ### Added 143 | 144 | - Additional tests around non-standard structure 145 | 146 | ## [0.2.3] - 2015-01-22 147 | 148 | ### Fixes 149 | 150 | - Base layer is an object with id having `___NUMBER` postfix or was mapped 151 | 152 | ## [0.2.2] - 2014-09-10 153 | 154 | ### Added 155 | 156 | - Documentation updates 157 | 158 | ## [0.2.1] - 2014-09-05 159 | 160 | ### Fixes 161 | 162 | - Column confusion 163 | 164 | ## [0.2.0] - 2014-09-04 165 | 166 | ### Added 167 | 168 | - Type casting 169 | 170 | ## [0.1.4] - 2014-09-03 171 | 172 | ### Added 173 | 174 | - Usage documentation 175 | - Related projects to README 176 | 177 | ## [0.1.3] - 2014-08-20 178 | 179 | ### Added 180 | 181 | - Package repository property 182 | 183 | ## [0.1.2] - 2014-08-19 184 | 185 | ### Added 186 | 187 | - Rename mapping 188 | 189 | ## [0.1.1] - 2014-08-18 190 | 191 | ### Fixed 192 | 193 | - Package main property 194 | 195 | ## 0.1.0 - 2014-08-18 196 | 197 | ### Added 198 | 199 | - Initial nest hydration project 200 | 201 | [Unreleased]: https://github.com/CoursePark/NestHydrationJS/compare/v0.2.13...HEAD 202 | [0.2.13]: https://github.com/CoursePark/NestHydrationJS/compare/v0.2.12...v0.2.13 203 | [0.2.12]: https://github.com/CoursePark/NestHydrationJS/compare/v0.2.11...v0.2.12 204 | [0.2.11]: https://github.com/CoursePark/NestHydrationJS/compare/v0.2.10...v0.2.11 205 | [0.2.10]: https://github.com/CoursePark/NestHydrationJS/compare/v0.2.9...v0.2.10 206 | [0.2.9]: https://github.com/CoursePark/NestHydrationJS/compare/v0.2.8...v0.2.9 207 | [0.2.8]: https://github.com/CoursePark/NestHydrationJS/compare/v0.2.7...v0.2.8 208 | [0.2.7]: https://github.com/CoursePark/NestHydrationJS/compare/v0.2.6...v0.2.7 209 | [0.2.6]: https://github.com/CoursePark/NestHydrationJS/compare/v0.2.5...v0.2.6 210 | [0.2.5]: https://github.com/CoursePark/NestHydrationJS/compare/v0.2.4...v0.2.5 211 | [0.2.4]: https://github.com/CoursePark/NestHydrationJS/compare/v0.2.3...v0.2.4 212 | [0.2.3]: https://github.com/CoursePark/NestHydrationJS/compare/v0.2.2...v0.2.3 213 | [0.2.2]: https://github.com/CoursePark/NestHydrationJS/compare/v0.2.1...v0.2.2 214 | [0.2.1]: https://github.com/CoursePark/NestHydrationJS/compare/v0.2.0...v0.2.1 215 | [0.2.0]: https://github.com/CoursePark/NestHydrationJS/compare/v0.1.4...v0.2.0 216 | [0.1.4]: https://github.com/CoursePark/NestHydrationJS/compare/v0.1.3...v0.1.4 217 | [0.1.3]: https://github.com/CoursePark/NestHydrationJS/compare/v0.1.2...v0.1.3 218 | [0.1.2]: https://github.com/CoursePark/NestHydrationJS/compare/v0.1.1...v0.1.2 219 | [0.1.1]: https://github.com/CoursePark/NestHydrationJS/compare/v0.1.0...v0.1.1 220 | -------------------------------------------------------------------------------- /NestHydrationJS.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | function nestHydrationJS() { 4 | var NestHydrationJS; 5 | 6 | var isArray = require('lodash.isarray'); 7 | var isFunction = require('lodash.isfunction'); 8 | var keys = require('lodash.keys'); 9 | var values = require('lodash.values'); 10 | var isPlainObject = require('lodash.isplainobject'); 11 | 12 | NestHydrationJS = {}; 13 | 14 | NestHydrationJS.typeHandlers = { 15 | NUMBER: function (cellValue) { 16 | return parseFloat(cellValue); 17 | }, 18 | BOOLEAN: function (cellValue) { 19 | return cellValue == true; 20 | } 21 | }; 22 | 23 | /* Creates a data structure containing nested objects and/or arrays from 24 | * tabular data based on a structure definition provided by 25 | * structPropToColumnMap. If structPropToColumnMap is not provided but 26 | * the data has column names that follow a particular convention then a 27 | * nested structures can also be created. 28 | */ 29 | NestHydrationJS.nest = function (data, structPropToColumnMap) { 30 | var listOnEmpty, table, meta, struct, i, row, j, _nest, primeIdColumn; 31 | 32 | // VALIDATE PARAMS AND BASIC INITIALIZATION 33 | 34 | listOnEmpty = false; 35 | 36 | if (typeof structPropToColumnMap === 'undefined') { 37 | structPropToColumnMap = null; 38 | } 39 | 40 | if (data === null) { 41 | return null; 42 | } 43 | 44 | if (!isArray(structPropToColumnMap) && !isPlainObject(structPropToColumnMap) && structPropToColumnMap !== null && structPropToColumnMap !== true) { 45 | throw new Error('nest expects param structPropToColumnMap to be an array, plain object, null, or true'); 46 | } 47 | 48 | if (isPlainObject(data)) { 49 | // internal table should be a table format but a plain object 50 | // could be passed as the first (and only) row of that table 51 | table = [data]; 52 | } else if (isArray(data)) { 53 | table = data; 54 | } else { 55 | throw Error('nest expects param data to be in the form of a plain object or an array of plain objects (forming a table)'); 56 | } 57 | 58 | // structPropToColumnMap can be set to true as a tie break between 59 | // returning null (empty structure) or an empty list 60 | if (structPropToColumnMap === true) { 61 | listOnEmpty = true; 62 | structPropToColumnMap = null; 63 | } 64 | 65 | if (structPropToColumnMap === null && table.length > 0) { 66 | // property mapping not specified, determine it from column names 67 | structPropToColumnMap = NestHydrationJS.structPropToColumnMapFromColumnHints(keys(table[0])); 68 | } 69 | 70 | if (structPropToColumnMap === null) { 71 | // properties is empty, can't form structure or determine content 72 | // for a list. Assume a structure unless listOnEmpty 73 | return listOnEmpty ? [] : null; 74 | } else if (table.length === 0) { 75 | // table is empty, return the appropriate empty result based on input definition 76 | return isArray(structPropToColumnMap) ? [] : null; 77 | } 78 | 79 | // COMPLETE VALIDATING PARAMS AND BASIC INITIALIZATION 80 | 81 | meta = NestHydrationJS.buildMeta(structPropToColumnMap); 82 | 83 | // BUILD FROM TABLE 84 | 85 | // defines function that can be called recursively 86 | _nest = function (row, idColumn) { 87 | var value, objMeta, obj, k, containingId, container, cell, cellValue, valueTypeFunction; 88 | 89 | value = row[idColumn]; 90 | 91 | // only really concerned with the meta data for this identity column 92 | objMeta = meta.idMap[idColumn]; 93 | 94 | if (value === null) { 95 | if (objMeta.default !== null && typeof objMeta.default !== 'undefined') { 96 | value = objMeta.default; 97 | } else { 98 | return; 99 | } 100 | } 101 | 102 | if (typeof objMeta.cache[value] !== 'undefined') { 103 | // object already exists in cache 104 | if (objMeta.containingIdUsage === null) { 105 | // at the top level, parent is root 106 | return; 107 | } 108 | 109 | containingId = row[objMeta.containingColumn]; 110 | if (typeof objMeta.containingIdUsage[value] !== 'undefined' 111 | && typeof objMeta.containingIdUsage[value][containingId] !== 'undefined' 112 | ) { 113 | // already placed as to-many relation in container, done 114 | return; 115 | } 116 | 117 | // not already placed as to-many relation in container 118 | obj = objMeta.cache[value]; 119 | } else { 120 | // don't have an object defined for this yet, create it 121 | obj = {}; 122 | objMeta.cache[value] = obj; 123 | 124 | // copy in properties from table data 125 | for (k = 0; k < objMeta.valueList.length; k++) { 126 | cell = objMeta.valueList[k]; 127 | cellValue = row[cell.column]; 128 | if (cellValue !== null) { 129 | if (isFunction(cell.type)) { 130 | valueTypeFunction = cell.type; 131 | } else { 132 | valueTypeFunction = NestHydrationJS.typeHandlers[cell.type]; 133 | } 134 | if (valueTypeFunction) { 135 | cellValue = valueTypeFunction(cellValue, cell.column, row); 136 | } 137 | } else if (typeof cell.default !== 'undefined') { 138 | cellValue = cell.default; 139 | } 140 | 141 | obj[cell.prop] = cellValue; 142 | } 143 | 144 | // initialize empty to-many relations, they will be populated when 145 | // those objects build themselves and find this containing object 146 | for (k = 0; k < objMeta.toManyPropList.length; k++) { 147 | obj[objMeta.toManyPropList[k]] = []; 148 | } 149 | 150 | // initialize null to-one relations and then recursively build them 151 | for (k = 0; k < objMeta.toOneList.length; k++) { 152 | obj[objMeta.toOneList[k].prop] = null; 153 | _nest(row, objMeta.toOneList[k].column); 154 | } 155 | } 156 | 157 | // link from the parent 158 | if (objMeta.containingColumn === null) { 159 | // parent is the top level 160 | if (objMeta.isOneOfMany) { 161 | // it is an array 162 | if (struct === null) { 163 | struct = []; 164 | } 165 | struct.push(obj); 166 | } else { 167 | // it is this object 168 | struct = obj; 169 | } 170 | } else { 171 | containingId = row[objMeta.containingColumn]; 172 | container = meta.idMap[objMeta.containingColumn].cache[containingId]; 173 | 174 | if (container) { 175 | if (objMeta.isOneOfMany) { 176 | // it is an array 177 | container[objMeta.ownProp].push(obj); 178 | } else { 179 | // it is this object 180 | container[objMeta.ownProp] = obj; 181 | } 182 | } 183 | 184 | // record the containing id 185 | if (typeof objMeta.containingIdUsage[value] === 'undefined') { 186 | objMeta.containingIdUsage[value] = {}; 187 | } 188 | objMeta.containingIdUsage[value][containingId] = true; 189 | } 190 | }; 191 | 192 | // struct is populated inside the build function 193 | struct = null; 194 | 195 | for (i = 0; i < table.length; i++) { 196 | // go through each row of the table 197 | row = table[i]; 198 | 199 | for (j = 0; j < meta.primeIdColumnList.length; j++) { 200 | // for each prime id column (corresponding to a to-many relation or 201 | // the top level) attempted to build an object 202 | primeIdColumn = meta.primeIdColumnList[j]; 203 | 204 | _nest(row, primeIdColumn); 205 | } 206 | } 207 | 208 | return struct; 209 | }; 210 | 211 | /* Create a data structure that contains lookups and cache spaces for quick 212 | * reference and action for the workings of the nest method. 213 | */ 214 | NestHydrationJS.buildMeta = function (structPropToColumnMap) { 215 | // internally defines recursive function with extra param. This allows cleaner API 216 | var meta, _buildMeta, primeIdColumn; 217 | 218 | // recursive internal function 219 | _buildMeta = function (structPropToColumnMap, isOneOfMany, containingColumn, ownProp) { 220 | var propList, idProp, idColumn, i, prop, objMeta, subIdColumn; 221 | 222 | 223 | propList = keys(structPropToColumnMap); 224 | if (propList.length === 0) { 225 | throw new Error('invalid structPropToColumnMap format - property \'' + ownProp + '\' can not be an empty array'); 226 | } 227 | 228 | for (i = 0; i < propList.length; i++) { 229 | prop = propList[i]; 230 | if (structPropToColumnMap[prop].id === true) { 231 | idProp = prop; 232 | break; 233 | } 234 | } 235 | 236 | if (idProp === undefined) { 237 | idProp = propList[0]; 238 | } 239 | 240 | idColumn = structPropToColumnMap[idProp].column || structPropToColumnMap[idProp]; 241 | 242 | if (isOneOfMany) { 243 | meta.primeIdColumnList.push(idColumn); 244 | } 245 | 246 | objMeta = { 247 | valueList: [], 248 | toOneList: [], 249 | toManyPropList: [], 250 | containingColumn: containingColumn, 251 | ownProp: ownProp, 252 | isOneOfMany: isOneOfMany === true, 253 | cache: {}, 254 | containingIdUsage: containingColumn === null ? null : {}, 255 | default: typeof structPropToColumnMap[idProp].default === 'undefined' ? null : structPropToColumnMap[idProp].default 256 | }; 257 | 258 | for (i = 0; i < propList.length; i++) { 259 | prop = propList[i]; 260 | if (typeof structPropToColumnMap[prop] === 'string') { 261 | // value property 262 | objMeta.valueList.push({ 263 | prop: prop, 264 | column: structPropToColumnMap[prop], 265 | type: undefined, 266 | default: undefined 267 | }); 268 | } else if (structPropToColumnMap[prop].column) { 269 | // value property 270 | objMeta.valueList.push({ 271 | prop: prop, 272 | column: structPropToColumnMap[prop].column, 273 | type: structPropToColumnMap[prop].type, 274 | default: structPropToColumnMap[prop].default 275 | }); 276 | } else if (isArray(structPropToColumnMap[prop])) { 277 | // list of objects / to-many relation 278 | objMeta.toManyPropList.push(prop); 279 | 280 | _buildMeta(structPropToColumnMap[prop][0], true, idColumn, prop); 281 | } else if (isPlainObject(structPropToColumnMap[prop])) { 282 | // object / to-one relation 283 | 284 | subIdColumn = values(structPropToColumnMap[prop])[0]; 285 | if (typeof subIdColumn === 'undefined') { 286 | throw new Error('invalid structPropToColumnMap format - property \'' + prop + '\' can not be an empty object'); 287 | } 288 | 289 | if (subIdColumn.column) { 290 | subIdColumn = subIdColumn.column; 291 | } 292 | 293 | objMeta.toOneList.push({ 294 | prop: prop, 295 | column: subIdColumn 296 | }); 297 | _buildMeta(structPropToColumnMap[prop], false, idColumn, prop); 298 | } else { 299 | throw new Error('invalid structPropToColumnMap format - property \'' + prop + '\' must be either a string, a plain object or an array'); 300 | } 301 | } 302 | 303 | meta.idMap[idColumn] = objMeta; 304 | }; 305 | 306 | // this data structure is populated by the _buildMeta function 307 | meta = { 308 | primeIdColumnList: [], 309 | idMap: {} 310 | }; 311 | 312 | if (isArray(structPropToColumnMap)) { 313 | if (structPropToColumnMap.length !== 1) { 314 | throw new Error('invalid structPropToColumnMap format - can not have multiple roots for structPropToColumnMap, if an array it must only have one item'); 315 | } 316 | // call with first object, but inform _buildMeta it is an array 317 | _buildMeta(structPropToColumnMap[0], true, null, null); 318 | } else if (isPlainObject(structPropToColumnMap)) { 319 | // register first column as prime id column 320 | primeIdColumn = values(structPropToColumnMap)[0]; 321 | if (typeof primeIdColumn === 'undefined') { 322 | throw new Error('invalid structPropToColumnMap format - the base object can not be an empty object'); 323 | } 324 | 325 | if (typeof primeIdColumn !== 'string') { 326 | primeIdColumn = primeIdColumn.column; 327 | } 328 | 329 | meta.primeIdColumnList.push(primeIdColumn); 330 | 331 | // construct the rest 332 | _buildMeta(structPropToColumnMap, false, null, null); 333 | } 334 | 335 | return meta; 336 | }; 337 | 338 | /* Returns a property mapping data structure based on the names of columns 339 | * in columnList. Used internally by nest when its propertyMapping param 340 | * is not specified. 341 | */ 342 | NestHydrationJS.structPropToColumnMapFromColumnHints = function (columnList, renameMapping) { 343 | var propertyMapping, prop, i, columnType, type, isId, column, pointer, navList, j, nav, renamedColumn, prevKeyList, k; 344 | 345 | if (typeof renameMapping === 'undefined') { 346 | renameMapping = {}; 347 | } 348 | 349 | propertyMapping = {base: null}; 350 | 351 | for (i = 0; i < columnList.length; i++) { 352 | column = columnList[i]; 353 | 354 | columnType = column.split('___'); 355 | 356 | type = null; 357 | isId = false; 358 | for (j = 1; j < columnType.length; j++) { 359 | if (columnType[j] === 'ID') { 360 | isId = true; 361 | } else if (typeof NestHydrationJS.typeHandlers[columnType[j]] !== 'undefined') { 362 | type = columnType[j]; 363 | } 364 | } 365 | 366 | pointer = propertyMapping; // point to base on each new column 367 | prop = 'base'; 368 | 369 | navList = columnType[0].split('_'); 370 | 371 | for (j = 0; j < navList.length; j++) { 372 | nav = navList[j]; 373 | 374 | if (nav === '') { 375 | if (pointer[prop] === null) { 376 | pointer[prop] = [null]; 377 | } 378 | pointer = pointer[prop]; 379 | prop = 0; 380 | } else { 381 | if (pointer[prop] === null) { 382 | pointer[prop] = {}; 383 | } 384 | if (typeof pointer[prop][nav] === 'undefined') { 385 | renamedColumn = typeof renameMapping[column] === 'undefined' 386 | ? column 387 | : renameMapping[column] 388 | ; 389 | if (type !== null || isId) { 390 | // no longer a simple mapping, has need of the type or id properties 391 | renamedColumn = {column: renamedColumn}; 392 | } 393 | if (type !== null) { 394 | // detail the type in the column map if type provided 395 | renamedColumn.type = type; 396 | } 397 | if (isId) { 398 | // set the id property in the column map 399 | renamedColumn.id = true; 400 | // check for any existing id keys that are conflicting 401 | prevKeyList = keys(pointer[prop]); 402 | for (k = 0; k < prevKeyList.length; k++) { 403 | if (pointer[prop][prevKeyList[k]].id === true) { 404 | return 'invalid - multiple id - ' + pointer[prop][prevKeyList[k]].column + ' and ' + renamedColumn.column + ' conflict'; 405 | } 406 | } 407 | } 408 | pointer[prop][nav] = j === (navList.length - 1) 409 | ? renamedColumn // is leaf node, store full column string 410 | : null // iteration will replace with object or array 411 | ; 412 | } 413 | pointer = pointer[prop]; 414 | prop = nav; 415 | } 416 | } 417 | } 418 | 419 | return propertyMapping.base; 420 | }; 421 | 422 | /* Registers a custom type handler */ 423 | NestHydrationJS.registerType = function (name, handler) { 424 | if (NestHydrationJS.typeHandlers[name]) { 425 | throw new Error('Handler with type, ' + name + ', already exists'); 426 | } 427 | 428 | NestHydrationJS.typeHandlers[name] = handler; 429 | }; 430 | return NestHydrationJS; 431 | } 432 | module.exports = nestHydrationJS; 433 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NestHydrationJS 2 | 3 | [![Build Status](https://travis-ci.org/CoursePark/NestHydrationJS.svg?branch=master)](https://travis-ci.org/CoursePark/NestHydrationJS) 4 | [![Coverage Status](https://coveralls.io/repos/github/CoursePark/NestHydration/badge.svg?branch=master)](https://coveralls.io/github/CoursePark/NestHydration?branch=master) 5 | [![Dependency Status](https://david-dm.org/CoursePark/NestHydrationJS.svg)](https://david-dm.org/CoursePark/NestHydrationJS) 6 | [![NPM version](https://img.shields.io/npm/v/nesthydrationjs.svg)](https://www.npmjs.com/package/nesthydrationjs) 7 | 8 | [Change Log](CHANGELOG.md) 9 | 10 | Converts tabular data into a nested object/array structure based on a definition object or specially named columns. 11 | 12 | ## Tabular Data With Definition Object 13 | 14 | Tabular data is considered to be an array of objects where each object represents a row and the properties of those objects are cell values with the keys representing the column names. 15 | 16 | ### Tabular Data 17 | 18 | ```javascript 19 | var table = [ 20 | { 21 | id: '1', title: 'Tabular to Objects', required: '1', 22 | teacher_id: '1', teacher_name: 'David', 23 | lesson_id: '1', lesson_title: 'Definitions' 24 | }, 25 | { 26 | id: '1', title: 'Tabular to Objects', required: '1', 27 | teacher_id: '1', teacher_name: 'David', 28 | lesson_id: '2', lesson_title: 'Table Data' 29 | }, 30 | { 31 | id: '1', title: 'Tabular to Objects', required: '1', 32 | teacher_id: '1', teacher_name: 'David', 33 | lesson_id: '3', lesson_title: 'Objects' 34 | }, 35 | { 36 | id: '2', title: 'Column Names Define Structure', required: '0', 37 | teacher_id: '2', teacher_name: 'Chris', 38 | lesson_id: '4', lesson_title: 'Column Names' 39 | }, 40 | { 41 | id: '2', title: 'Column Names Define Structure', required: '0', 42 | teacher_id: '2', teacher_name: 'Chris', 43 | lesson_id: '2', lesson_title: 'Table Data' 44 | }, 45 | { 46 | id: '2', title: 'Column Names Define Structure', required: '0', 47 | teacher_id: '2', teacher_name: 'Chris', 48 | lesson_id: '3', lesson_title: 'Objects' 49 | }, 50 | { 51 | id: '3', title: 'Object On Bottom', required: '0', 52 | teacher_id: '1', teacher_name: 'David', 53 | lesson_id: '5', lesson_title: 'Non Array Input' 54 | } 55 | ]; 56 | ``` 57 | 58 | Above are 7 rows each with the cells data for the columns `id`, `title`, `required`, `teacher_id`, `teacher_name`, `lesson_id`, `lesson_title`. 59 | 60 | Mapping from the property keys of the tabular data to nested objects is done in accordance to the definition object. 61 | 62 | ### Definition 63 | 64 | ```javascript 65 | var definition = [{ 66 | id: {column: 'id', type: 'NUMBER'}, 67 | title: 'title', 68 | required: {column: 'required', type: 'BOOLEAN'}, 69 | teacher: { 70 | id: {column: 'teacher_id', type: 'NUMBER'}, 71 | name: 'teacher_name' 72 | }, 73 | lesson: [{ 74 | id: {column: 'lesson_id', type: 'NUMBER'}, 75 | title: 'lesson_title' 76 | }] 77 | }]; 78 | ``` 79 | 80 | The definition object above maps: 81 | 82 | - `id` to `result[#].id` with a type caste to a number 83 | - `title` to `result[#].title` 84 | - `required` to `result[#].required` with a type caste to a boolean 85 | - `teacher_id` to `result[#].teacher.id` with a type caste to a number 86 | - `teacher_name` to `result[#].teacher.name` 87 | - `lesson_id` to `result[#].lesson[#].id` with a type caste to a number 88 | - `lesson_title` to `result[#].lesson[#].title` 89 | 90 | ### Transformation 91 | 92 | ```javascript 93 | var NestHydrationJS = require('nesthydrationjs')(); 94 | result = NestHydrationJS.nest(table, definition); 95 | ``` 96 | 97 | ### Result 98 | 99 | ```javascript 100 | [ 101 | {id: 1, title: 'Tabular to Objects', required: true, teacher: {id: 1, name: 'David'}, lesson: [ 102 | {id: 1, title: 'Defintions'}, 103 | {id: 2, title: 'Table Data'}, 104 | {id: 3, title: 'Objects'} 105 | ]}, 106 | {id: 2, title: 'Column Names Define Structure', required: false, teacher: {id: 2, name: 'Chris'}, lesson: [ 107 | {id: 4, title: 'Column Names'}, 108 | {id: 2, title: 'Table Data'}, 109 | {id: 3, title: 'Objects'} 110 | ]}, 111 | {id: 3, title: 'Object On Bottom', required: false, teacher: {id: 1, name: 'David'}, lesson: [ 112 | {id: 5, title: 'Non Array Input'} 113 | ]} 114 | ] 115 | ``` 116 | 117 | ## SQL-ish Example 118 | 119 | It is common to want to define an SQL query and then just get back objects. NestHydrationJS was created with this in mind. 120 | 121 | The following example gives same result as above but a column naming convention is used instead of a definition object. 122 | 123 | Nesting is achieved by using a underscore (`_`). A *x to one* relation is defined by a single underscore and a *x to many* relation is defined by preceeding properties of the many object with a 2nd underscore. 124 | 125 | If a column alias ends in a triple underscore (`___`) followed by either `NUMBER` or `BOOLEAN` then the values in those columns will be caste to the respective type unless the value is null. Triple underscore with `ID` (`___ID`) can be used to specify a column that is an id propery of that level of object. If an id is not specified the default is for the first column in that object to be the id property. The id specifier can be used in combination with a type caste, so either `___ID___NUMBER`, or `___NUMBER___ID` would be valid appends to a column name. 126 | 127 | **Note:** that this means that almost always base level properties will be prefixed with a underscore, as this is actually a *x to many* relation from the variable returned from the `nest` function. 128 | 129 | ### Query 130 | 131 | ```javascript 132 | var sql = '' 133 | + 'SELECT' 134 | + 'c.id AS _id___NUMBER,' 135 | + 'c.title AS _title,' 136 | + 'c.requried AS _required___BOOLEAN,' 137 | + 't.teacher AS _teacher_id___NUMBER,' 138 | + 't.name AS _teacher_name,' 139 | + 'l.title AS _lesson__title' 140 | + 'l.id AS _lesson__id___NUMBER___ID,' 141 | + 'FROM course AS c' 142 | + 'JOIN teacher AS t ON t.id = c.teacher_id' 143 | + 'JOIN course_lesson AS cl ON cl.course_id = c.id' 144 | + 'JOIN lesson AS l ON l.id = cl.lesson_id' 145 | ; 146 | ``` 147 | 148 | For this example the following query produces the following tabular data. 149 | 150 | **Note** that this is the same cell values as the `Tabular Data With Definition Object` example above but with different column names. 151 | 152 | ```javascript 153 | var table = db.fetchAll(sql); 154 | [ 155 | { 156 | _id: '1', _title: 'Tabular to Objects', _required: '1', 157 | _teacher_id: '1', _teacher_name: 'David', 158 | _lesson__title: 'Defintions', _lesson__id: '1' 159 | }, 160 | { 161 | _id: '1', _title: 'Tabular to Objects', _required: '1', 162 | _teacher_id: '1', _teacher_name: 'David', 163 | _lesson__title: 'Table Data', _lesson__id: '2' 164 | }, 165 | { 166 | _id: '1', _title: 'Tabular to Objects', _required: '1', 167 | _teacher_id: '1', _teacher_name: 'David', 168 | _lesson__title: 'Objects', _lesson__id: '3' 169 | }, 170 | { 171 | _id: '2', _title: 'Column Names Define Structure', _required: '0', 172 | _teacher_id: '2', _teacher_name: 'Chris', 173 | _lesson__title: 'Column Names', _lesson__id: '4' 174 | }, 175 | { 176 | _id: '2', _title: 'Column Names Define Structure', _required: '0', 177 | _teacher_id: '2', _teacher_name: 'Chris', 178 | _lesson__title: 'Table Data', _lesson__id: '2' 179 | }, 180 | { 181 | _id: '2', _title: 'Column Names Define Structure', _required: '0', 182 | _teacher_id: '2', _teacher_name: 'Chris', 183 | _lesson__title: 'Objects', _lesson__id: '3' 184 | }, 185 | { 186 | _id: '3', _title: 'Object On Bottom', _required: '0', 187 | _teacher_id: '1', _teacher_name: 'David', 188 | _lesson__title: 'Non Array Input', _lesson__id: '5' 189 | } 190 | ] 191 | ``` 192 | 193 | ### Transformation 194 | 195 | ```javascript 196 | var NestHydrationJS = require('nesthydrationjs')(); 197 | result = NestHydrationJS.nest(table); 198 | ``` 199 | 200 | ### Result 201 | 202 | **Note** this is the same output as the `Tabular Data With Definition Object` example above. 203 | 204 | ```javascript 205 | [ 206 | {id: 1, title: 'Tabular to Objects', required: true, teacher: {id: 1, name: 'David'}, lesson: [ 207 | {id: 1, title: 'Definitions'}, 208 | {id: 2, title: 'Table Data'}, 209 | {id: 3, title: 'Objects'} 210 | ]}, 211 | {id: 2, title: 'Column Names Define Structure', required: false, teacher: {id: 2, name: 'Chris'}, lesson: [ 212 | {id: 4, title: 'Column Names'}, 213 | {id: 2, title: 'Table Data'}, 214 | {id: 3, title: 'Objects'} 215 | ]}, 216 | {id: 3, title: 'Object On Bottom', required: false, teacher: {id: 1, name: 'David'}, lesson: [ 217 | {id: 5, title: 'Non Array Input'} 218 | ]} 219 | ] 220 | ``` 221 | 222 | ## Additional Definition Object Capabilities 223 | 224 | ### Ids That Aren't First In Definition Properties 225 | 226 | It is possible to specify an id column for mapping to objects instead of having it default to the first property of each object specified in the definition. If multiple properties for an object are specified to be ids only the first will be used. 227 | 228 | ```javascript 229 | var NestHydrationJS = require('nesthydrationjs')(); 230 | 231 | var table = [ 232 | {bookTitle: 'Anathem', bookId: 1, authorId: 1, authorName: 'Neal Stephenson'}, 233 | {bookTitle: 'Seveneves', bookId: 2, authorId: 1, authorName: 'Neal Stephenson'} 234 | ]; 235 | var definition = [{ 236 | name: {column: 'authorName'}, 237 | id: {column: 'authorId', id: true}, 238 | books: [{ 239 | title: {column: 'bookTitle'}, 240 | id: {column: 'bookId', id: true} 241 | }] 242 | }]; 243 | result = NestHydrationJS.nest(table, definition); 244 | /* result would be the following: 245 | [ 246 | { 247 | "name": "Neal Stephenson", 248 | "id": 1, 249 | "books": [ 250 | { 251 | "title": "Anathem", 252 | "id": 1 253 | }, 254 | { 255 | "title": "Seveneves", 256 | "id": 2 257 | } 258 | ] 259 | } 260 | ] 261 | */ 262 | ``` 263 | 264 | ### Default Values 265 | 266 | You can specify a default value for a property by specifying the `default` property in the definition object. The value of the property will be replaced with the default value when it's row data is `null`. 267 | 268 | #### Example 269 | 270 | ```javascript 271 | var NestHydrationJS = require('nesthydrationjs')(); 272 | 273 | var table = [ 274 | { 275 | id: 1, title: null 276 | } 277 | ]; 278 | var definition = [{ 279 | id: 'id' 280 | title: {column: 'title', default: 'my default'}, 281 | }]; 282 | result = NestHydrationJS.nest(table, definition); 283 | /* result would be the following: 284 | [ 285 | {id: 1, title: 'my default'} 286 | ] 287 | */ 288 | ``` 289 | 290 | ### Custom Type Definition 291 | 292 | #### As a custom type 293 | 294 | New types can be registered using the `registerType(name, handler)` function. `handler(cellValue, name, row)` is a callback function that takes the cell value, column name and the full row data. 295 | 296 | ##### Example Usage 297 | 298 | ```javascript 299 | var NestHydrationJS = require('nesthydrationjs')(); 300 | NestHydrationJS.registerType('CUSTOM_TYPE', function(value, name, row) { 301 | return '::' + value + '::'; 302 | }); 303 | 304 | var table = [ 305 | { 306 | id: 1, title: 'Custom Data Types' 307 | } 308 | ]; 309 | var definition = [{ 310 | id: 'id' 311 | title: {column: 'title', type: 'CUSTOM_TYPE'}, 312 | }]; 313 | result = NestHydrationJS.nest(table, definition); 314 | /* result would be the following: 315 | [ 316 | {id: 1, title: '::Custom Data Types::'} 317 | ] 318 | */ 319 | ``` 320 | 321 | #### Type as a function 322 | 323 | You can also define the type of a column in the definition object as a function and that function will be called for each value provided. The arguments passed are the same as those passed to a custom type handler. This allows formatting of a type without defining it as a global type. 324 | 325 | ##### Example 326 | 327 | ```javascript 328 | var NestHydrationJS = require('nesthydrationjs')(); 329 | 330 | var table = [ 331 | { 332 | id: 1, title: 'Custom Data Types' 333 | } 334 | ]; 335 | var definition = [{ 336 | id: 'id' 337 | title: {column: 'title', type: function(value, name, row) { 338 | return '::' + value + '::'; 339 | }}, 340 | }]; 341 | result = NestHydrationJS.nest(table, definition); 342 | /* result would be the following: 343 | [ 344 | {id: 1, title: '::Custom Data Types::'} 345 | ] 346 | */ 347 | ``` 348 | 349 | ### Related Projects 350 | 351 | - [NestHydration for PHP](https://github.com/CoursePark/NestHydration) : The original. But a new algorithm was implemented for the JS (this) version and ported back to PHP. 352 | - [KnexNest](https://github.com/CoursePark/KnexNest) : Takes a [Knex.js](http://knexjs.org/) query object and returns objects. 353 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nesthydrationjs", 3 | "version": "1.0.7", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@babel/code-frame": { 8 | "version": "7.5.5", 9 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", 10 | "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", 11 | "dev": true, 12 | "requires": { 13 | "@babel/highlight": "^7.0.0" 14 | } 15 | }, 16 | "@babel/generator": { 17 | "version": "7.7.4", 18 | "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.7.4.tgz", 19 | "integrity": "sha512-m5qo2WgdOJeyYngKImbkyQrnUN1mPceaG5BV+G0E3gWsa4l/jCSryWJdM2x8OuGAOyh+3d5pVYfZWCiNFtynxg==", 20 | "dev": true, 21 | "requires": { 22 | "@babel/types": "^7.7.4", 23 | "jsesc": "^2.5.1", 24 | "lodash": "^4.17.13", 25 | "source-map": "^0.5.0" 26 | } 27 | }, 28 | "@babel/helper-function-name": { 29 | "version": "7.7.4", 30 | "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.4.tgz", 31 | "integrity": "sha512-AnkGIdiBhEuiwdoMnKm7jfPfqItZhgRaZfMg1XX3bS25INOnLPjPG1Ppnajh8eqgt5kPJnfqrRHqFqmjKDZLzQ==", 32 | "dev": true, 33 | "requires": { 34 | "@babel/helper-get-function-arity": "^7.7.4", 35 | "@babel/template": "^7.7.4", 36 | "@babel/types": "^7.7.4" 37 | } 38 | }, 39 | "@babel/helper-get-function-arity": { 40 | "version": "7.7.4", 41 | "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.4.tgz", 42 | "integrity": "sha512-QTGKEdCkjgzgfJ3bAyRwF4yyT3pg+vDgan8DSivq1eS0gwi+KGKE5x8kRcbeFTb/673mkO5SN1IZfmCfA5o+EA==", 43 | "dev": true, 44 | "requires": { 45 | "@babel/types": "^7.7.4" 46 | } 47 | }, 48 | "@babel/helper-split-export-declaration": { 49 | "version": "7.7.4", 50 | "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.4.tgz", 51 | "integrity": "sha512-guAg1SXFcVr04Guk9eq0S4/rWS++sbmyqosJzVs8+1fH5NI+ZcmkaSkc7dmtAFbHFva6yRJnjW3yAcGxjueDug==", 52 | "dev": true, 53 | "requires": { 54 | "@babel/types": "^7.7.4" 55 | } 56 | }, 57 | "@babel/highlight": { 58 | "version": "7.5.0", 59 | "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", 60 | "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", 61 | "dev": true, 62 | "requires": { 63 | "chalk": "^2.0.0", 64 | "esutils": "^2.0.2", 65 | "js-tokens": "^4.0.0" 66 | } 67 | }, 68 | "@babel/parser": { 69 | "version": "7.7.4", 70 | "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.4.tgz", 71 | "integrity": "sha512-jIwvLO0zCL+O/LmEJQjWA75MQTWwx3c3u2JOTDK5D3/9egrWRRA0/0hk9XXywYnXZVVpzrBYeIQTmhwUaePI9g==", 72 | "dev": true 73 | }, 74 | "@babel/template": { 75 | "version": "7.7.4", 76 | "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.4.tgz", 77 | "integrity": "sha512-qUzihgVPguAzXCK7WXw8pqs6cEwi54s3E+HrejlkuWO6ivMKx9hZl3Y2fSXp9i5HgyWmj7RKP+ulaYnKM4yYxw==", 78 | "dev": true, 79 | "requires": { 80 | "@babel/code-frame": "^7.0.0", 81 | "@babel/parser": "^7.7.4", 82 | "@babel/types": "^7.7.4" 83 | } 84 | }, 85 | "@babel/traverse": { 86 | "version": "7.7.4", 87 | "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.7.4.tgz", 88 | "integrity": "sha512-P1L58hQyupn8+ezVA2z5KBm4/Zr4lCC8dwKCMYzsa5jFMDMQAzaBNy9W5VjB+KAmBjb40U7a/H6ao+Xo+9saIw==", 89 | "dev": true, 90 | "requires": { 91 | "@babel/code-frame": "^7.5.5", 92 | "@babel/generator": "^7.7.4", 93 | "@babel/helper-function-name": "^7.7.4", 94 | "@babel/helper-split-export-declaration": "^7.7.4", 95 | "@babel/parser": "^7.7.4", 96 | "@babel/types": "^7.7.4", 97 | "debug": "^4.1.0", 98 | "globals": "^11.1.0", 99 | "lodash": "^4.17.13" 100 | }, 101 | "dependencies": { 102 | "debug": { 103 | "version": "4.1.1", 104 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", 105 | "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", 106 | "dev": true, 107 | "requires": { 108 | "ms": "^2.1.1" 109 | } 110 | }, 111 | "globals": { 112 | "version": "11.12.0", 113 | "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", 114 | "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", 115 | "dev": true 116 | }, 117 | "ms": { 118 | "version": "2.1.2", 119 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 120 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 121 | "dev": true 122 | } 123 | } 124 | }, 125 | "@babel/types": { 126 | "version": "7.7.4", 127 | "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.4.tgz", 128 | "integrity": "sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA==", 129 | "dev": true, 130 | "requires": { 131 | "esutils": "^2.0.2", 132 | "lodash": "^4.17.13", 133 | "to-fast-properties": "^2.0.0" 134 | } 135 | }, 136 | "acorn": { 137 | "version": "7.1.0", 138 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz", 139 | "integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==", 140 | "dev": true 141 | }, 142 | "acorn-jsx": { 143 | "version": "5.1.0", 144 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.1.0.tgz", 145 | "integrity": "sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw==", 146 | "dev": true 147 | }, 148 | "ajv": { 149 | "version": "6.10.2", 150 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", 151 | "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", 152 | "dev": true, 153 | "requires": { 154 | "fast-deep-equal": "^2.0.1", 155 | "fast-json-stable-stringify": "^2.0.0", 156 | "json-schema-traverse": "^0.4.1", 157 | "uri-js": "^4.2.2" 158 | } 159 | }, 160 | "ansi-escapes": { 161 | "version": "4.3.0", 162 | "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.0.tgz", 163 | "integrity": "sha512-EiYhwo0v255HUL6eDyuLrXEkTi7WwVCLAw+SeOQ7M7qdun1z1pum4DEm/nuqIVbPvi9RPPc9k9LbyBv6H0DwVg==", 164 | "dev": true, 165 | "requires": { 166 | "type-fest": "^0.8.1" 167 | } 168 | }, 169 | "ansi-regex": { 170 | "version": "5.0.0", 171 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", 172 | "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", 173 | "dev": true 174 | }, 175 | "ansi-styles": { 176 | "version": "3.2.1", 177 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 178 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 179 | "dev": true, 180 | "requires": { 181 | "color-convert": "^1.9.0" 182 | } 183 | }, 184 | "append-transform": { 185 | "version": "1.0.0", 186 | "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-1.0.0.tgz", 187 | "integrity": "sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw==", 188 | "dev": true, 189 | "requires": { 190 | "default-require-extensions": "^2.0.0" 191 | } 192 | }, 193 | "archy": { 194 | "version": "1.0.0", 195 | "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", 196 | "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", 197 | "dev": true 198 | }, 199 | "argparse": { 200 | "version": "1.0.10", 201 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", 202 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", 203 | "dev": true, 204 | "requires": { 205 | "sprintf-js": "~1.0.2" 206 | } 207 | }, 208 | "asn1": { 209 | "version": "0.2.4", 210 | "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", 211 | "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", 212 | "dev": true, 213 | "requires": { 214 | "safer-buffer": "~2.1.0" 215 | } 216 | }, 217 | "assert-plus": { 218 | "version": "1.0.0", 219 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", 220 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", 221 | "dev": true 222 | }, 223 | "astral-regex": { 224 | "version": "1.0.0", 225 | "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", 226 | "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", 227 | "dev": true 228 | }, 229 | "asynckit": { 230 | "version": "0.4.0", 231 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 232 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", 233 | "dev": true 234 | }, 235 | "aws-sign2": { 236 | "version": "0.7.0", 237 | "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", 238 | "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", 239 | "dev": true 240 | }, 241 | "aws4": { 242 | "version": "1.8.0", 243 | "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", 244 | "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", 245 | "dev": true 246 | }, 247 | "balanced-match": { 248 | "version": "1.0.0", 249 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 250 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", 251 | "dev": true 252 | }, 253 | "bcrypt-pbkdf": { 254 | "version": "1.0.2", 255 | "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", 256 | "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", 257 | "dev": true, 258 | "requires": { 259 | "tweetnacl": "^0.14.3" 260 | } 261 | }, 262 | "brace-expansion": { 263 | "version": "1.1.11", 264 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 265 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 266 | "dev": true, 267 | "requires": { 268 | "balanced-match": "^1.0.0", 269 | "concat-map": "0.0.1" 270 | } 271 | }, 272 | "browser-stdout": { 273 | "version": "1.3.1", 274 | "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", 275 | "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", 276 | "dev": true 277 | }, 278 | "caching-transform": { 279 | "version": "3.0.2", 280 | "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-3.0.2.tgz", 281 | "integrity": "sha512-Mtgcv3lh3U0zRii/6qVgQODdPA4G3zhG+jtbCWj39RXuUFTMzH0vcdMtaJS1jPowd+It2Pqr6y3NJMQqOqCE2w==", 282 | "dev": true, 283 | "requires": { 284 | "hasha": "^3.0.0", 285 | "make-dir": "^2.0.0", 286 | "package-hash": "^3.0.0", 287 | "write-file-atomic": "^2.4.2" 288 | } 289 | }, 290 | "callsites": { 291 | "version": "3.1.0", 292 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", 293 | "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", 294 | "dev": true 295 | }, 296 | "camelcase": { 297 | "version": "5.3.1", 298 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", 299 | "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", 300 | "dev": true 301 | }, 302 | "caseless": { 303 | "version": "0.12.0", 304 | "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", 305 | "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", 306 | "dev": true 307 | }, 308 | "chalk": { 309 | "version": "2.4.2", 310 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 311 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 312 | "dev": true, 313 | "requires": { 314 | "ansi-styles": "^3.2.1", 315 | "escape-string-regexp": "^1.0.5", 316 | "supports-color": "^5.3.0" 317 | }, 318 | "dependencies": { 319 | "has-flag": { 320 | "version": "3.0.0", 321 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 322 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 323 | "dev": true 324 | }, 325 | "supports-color": { 326 | "version": "5.5.0", 327 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 328 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 329 | "dev": true, 330 | "requires": { 331 | "has-flag": "^3.0.0" 332 | } 333 | } 334 | } 335 | }, 336 | "chardet": { 337 | "version": "0.7.0", 338 | "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", 339 | "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", 340 | "dev": true 341 | }, 342 | "cli-cursor": { 343 | "version": "3.1.0", 344 | "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", 345 | "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", 346 | "dev": true, 347 | "requires": { 348 | "restore-cursor": "^3.1.0" 349 | } 350 | }, 351 | "cli-width": { 352 | "version": "2.2.0", 353 | "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", 354 | "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", 355 | "dev": true 356 | }, 357 | "cliui": { 358 | "version": "5.0.0", 359 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", 360 | "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", 361 | "dev": true, 362 | "requires": { 363 | "string-width": "^3.1.0", 364 | "strip-ansi": "^5.2.0", 365 | "wrap-ansi": "^5.1.0" 366 | }, 367 | "dependencies": { 368 | "emoji-regex": { 369 | "version": "7.0.3", 370 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", 371 | "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", 372 | "dev": true 373 | }, 374 | "is-fullwidth-code-point": { 375 | "version": "2.0.0", 376 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 377 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", 378 | "dev": true 379 | }, 380 | "string-width": { 381 | "version": "3.1.0", 382 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", 383 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", 384 | "dev": true, 385 | "requires": { 386 | "emoji-regex": "^7.0.1", 387 | "is-fullwidth-code-point": "^2.0.0", 388 | "strip-ansi": "^5.1.0" 389 | } 390 | } 391 | } 392 | }, 393 | "cobertura-parse": { 394 | "version": "1.0.5", 395 | "resolved": "https://registry.npmjs.org/cobertura-parse/-/cobertura-parse-1.0.5.tgz", 396 | "integrity": "sha512-uYJfkGhzw1wibe/8jqqHmSaPNWFguzq/IlSj83u3cSnZho/lUnfj0mLTmZGmB3AiKCOTYr22TYwpR1sXy2JEkg==", 397 | "dev": true, 398 | "requires": { 399 | "mocha": "5.0.5", 400 | "xml2js": "0.4.19" 401 | } 402 | }, 403 | "color-convert": { 404 | "version": "1.9.3", 405 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 406 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 407 | "dev": true, 408 | "requires": { 409 | "color-name": "1.1.3" 410 | } 411 | }, 412 | "color-name": { 413 | "version": "1.1.3", 414 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 415 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", 416 | "dev": true 417 | }, 418 | "combined-stream": { 419 | "version": "1.0.8", 420 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", 421 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", 422 | "dev": true, 423 | "requires": { 424 | "delayed-stream": "~1.0.0" 425 | } 426 | }, 427 | "commander": { 428 | "version": "2.11.0", 429 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", 430 | "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", 431 | "dev": true 432 | }, 433 | "commondir": { 434 | "version": "1.0.1", 435 | "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", 436 | "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", 437 | "dev": true 438 | }, 439 | "concat-map": { 440 | "version": "0.0.1", 441 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 442 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 443 | "dev": true 444 | }, 445 | "convert-source-map": { 446 | "version": "1.7.0", 447 | "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", 448 | "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", 449 | "dev": true, 450 | "requires": { 451 | "safe-buffer": "~5.1.1" 452 | }, 453 | "dependencies": { 454 | "safe-buffer": { 455 | "version": "5.1.2", 456 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 457 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", 458 | "dev": true 459 | } 460 | } 461 | }, 462 | "core-util-is": { 463 | "version": "1.0.2", 464 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 465 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", 466 | "dev": true 467 | }, 468 | "coveralls": { 469 | "version": "3.0.8", 470 | "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.0.8.tgz", 471 | "integrity": "sha512-lkQlg29RhV9zwB0gDaEAWoap8xPgFxtPsVIpTNiDDtWNrvtP1/RmGJRRAV/Loz2gihmppObkSL0wnptEGUXaOQ==", 472 | "dev": true, 473 | "requires": { 474 | "cobertura-parse": "^1.0.5", 475 | "js-yaml": "^3.13.1", 476 | "lcov-parse": "^1.0.0", 477 | "log-driver": "^1.2.7", 478 | "minimist": "^1.2.0", 479 | "request": "^2.88.0" 480 | } 481 | }, 482 | "cp-file": { 483 | "version": "6.2.0", 484 | "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-6.2.0.tgz", 485 | "integrity": "sha512-fmvV4caBnofhPe8kOcitBwSn2f39QLjnAnGq3gO9dfd75mUytzKNZB1hde6QHunW2Rt+OwuBOMc3i1tNElbszA==", 486 | "dev": true, 487 | "requires": { 488 | "graceful-fs": "^4.1.2", 489 | "make-dir": "^2.0.0", 490 | "nested-error-stacks": "^2.0.0", 491 | "pify": "^4.0.1", 492 | "safe-buffer": "^5.0.1" 493 | } 494 | }, 495 | "cross-spawn": { 496 | "version": "6.0.5", 497 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", 498 | "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", 499 | "dev": true, 500 | "requires": { 501 | "nice-try": "^1.0.4", 502 | "path-key": "^2.0.1", 503 | "semver": "^5.5.0", 504 | "shebang-command": "^1.2.0", 505 | "which": "^1.2.9" 506 | }, 507 | "dependencies": { 508 | "semver": { 509 | "version": "5.7.1", 510 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", 511 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", 512 | "dev": true 513 | } 514 | } 515 | }, 516 | "dashdash": { 517 | "version": "1.14.1", 518 | "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", 519 | "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", 520 | "dev": true, 521 | "requires": { 522 | "assert-plus": "^1.0.0" 523 | } 524 | }, 525 | "debug": { 526 | "version": "3.1.0", 527 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", 528 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", 529 | "dev": true, 530 | "requires": { 531 | "ms": "2.0.0" 532 | } 533 | }, 534 | "decamelize": { 535 | "version": "1.2.0", 536 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", 537 | "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", 538 | "dev": true 539 | }, 540 | "deep-is": { 541 | "version": "0.1.3", 542 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", 543 | "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", 544 | "dev": true 545 | }, 546 | "default-require-extensions": { 547 | "version": "2.0.0", 548 | "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", 549 | "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=", 550 | "dev": true, 551 | "requires": { 552 | "strip-bom": "^3.0.0" 553 | } 554 | }, 555 | "delayed-stream": { 556 | "version": "1.0.0", 557 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 558 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", 559 | "dev": true 560 | }, 561 | "diff": { 562 | "version": "3.5.0", 563 | "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", 564 | "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", 565 | "dev": true 566 | }, 567 | "doctrine": { 568 | "version": "3.0.0", 569 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", 570 | "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", 571 | "dev": true, 572 | "requires": { 573 | "esutils": "^2.0.2" 574 | } 575 | }, 576 | "ecc-jsbn": { 577 | "version": "0.1.2", 578 | "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", 579 | "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", 580 | "dev": true, 581 | "requires": { 582 | "jsbn": "~0.1.0", 583 | "safer-buffer": "^2.1.0" 584 | } 585 | }, 586 | "emoji-regex": { 587 | "version": "8.0.0", 588 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 589 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 590 | "dev": true 591 | }, 592 | "error-ex": { 593 | "version": "1.3.2", 594 | "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", 595 | "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", 596 | "dev": true, 597 | "requires": { 598 | "is-arrayish": "^0.2.1" 599 | } 600 | }, 601 | "es6-error": { 602 | "version": "4.1.1", 603 | "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", 604 | "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", 605 | "dev": true 606 | }, 607 | "escape-string-regexp": { 608 | "version": "1.0.5", 609 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 610 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", 611 | "dev": true 612 | }, 613 | "eslint": { 614 | "version": "6.7.1", 615 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.7.1.tgz", 616 | "integrity": "sha512-UWzBS79pNcsDSxgxbdjkmzn/B6BhsXMfUaOHnNwyE8nD+Q6pyT96ow2MccVayUTV4yMid4qLhMiQaywctRkBLA==", 617 | "dev": true, 618 | "requires": { 619 | "@babel/code-frame": "^7.0.0", 620 | "ajv": "^6.10.0", 621 | "chalk": "^2.1.0", 622 | "cross-spawn": "^6.0.5", 623 | "debug": "^4.0.1", 624 | "doctrine": "^3.0.0", 625 | "eslint-scope": "^5.0.0", 626 | "eslint-utils": "^1.4.3", 627 | "eslint-visitor-keys": "^1.1.0", 628 | "espree": "^6.1.2", 629 | "esquery": "^1.0.1", 630 | "esutils": "^2.0.2", 631 | "file-entry-cache": "^5.0.1", 632 | "functional-red-black-tree": "^1.0.1", 633 | "glob-parent": "^5.0.0", 634 | "globals": "^12.1.0", 635 | "ignore": "^4.0.6", 636 | "import-fresh": "^3.0.0", 637 | "imurmurhash": "^0.1.4", 638 | "inquirer": "^7.0.0", 639 | "is-glob": "^4.0.0", 640 | "js-yaml": "^3.13.1", 641 | "json-stable-stringify-without-jsonify": "^1.0.1", 642 | "levn": "^0.3.0", 643 | "lodash": "^4.17.14", 644 | "minimatch": "^3.0.4", 645 | "mkdirp": "^0.5.1", 646 | "natural-compare": "^1.4.0", 647 | "optionator": "^0.8.3", 648 | "progress": "^2.0.0", 649 | "regexpp": "^2.0.1", 650 | "semver": "^6.1.2", 651 | "strip-ansi": "^5.2.0", 652 | "strip-json-comments": "^3.0.1", 653 | "table": "^5.2.3", 654 | "text-table": "^0.2.0", 655 | "v8-compile-cache": "^2.0.3" 656 | }, 657 | "dependencies": { 658 | "debug": { 659 | "version": "4.1.1", 660 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", 661 | "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", 662 | "dev": true, 663 | "requires": { 664 | "ms": "^2.1.1" 665 | } 666 | }, 667 | "ms": { 668 | "version": "2.1.2", 669 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 670 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 671 | "dev": true 672 | } 673 | } 674 | }, 675 | "eslint-scope": { 676 | "version": "5.0.0", 677 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", 678 | "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", 679 | "dev": true, 680 | "requires": { 681 | "esrecurse": "^4.1.0", 682 | "estraverse": "^4.1.1" 683 | } 684 | }, 685 | "eslint-utils": { 686 | "version": "1.4.3", 687 | "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", 688 | "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", 689 | "dev": true, 690 | "requires": { 691 | "eslint-visitor-keys": "^1.1.0" 692 | } 693 | }, 694 | "eslint-visitor-keys": { 695 | "version": "1.1.0", 696 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", 697 | "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", 698 | "dev": true 699 | }, 700 | "espree": { 701 | "version": "6.1.2", 702 | "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.2.tgz", 703 | "integrity": "sha512-2iUPuuPP+yW1PZaMSDM9eyVf8D5P0Hi8h83YtZ5bPc/zHYjII5khoixIUTMO794NOY8F/ThF1Bo8ncZILarUTA==", 704 | "dev": true, 705 | "requires": { 706 | "acorn": "^7.1.0", 707 | "acorn-jsx": "^5.1.0", 708 | "eslint-visitor-keys": "^1.1.0" 709 | } 710 | }, 711 | "esprima": { 712 | "version": "4.0.1", 713 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", 714 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", 715 | "dev": true 716 | }, 717 | "esquery": { 718 | "version": "1.0.1", 719 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", 720 | "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", 721 | "dev": true, 722 | "requires": { 723 | "estraverse": "^4.0.0" 724 | } 725 | }, 726 | "esrecurse": { 727 | "version": "4.2.1", 728 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", 729 | "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", 730 | "dev": true, 731 | "requires": { 732 | "estraverse": "^4.1.0" 733 | } 734 | }, 735 | "estraverse": { 736 | "version": "4.3.0", 737 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", 738 | "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", 739 | "dev": true 740 | }, 741 | "esutils": { 742 | "version": "2.0.3", 743 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", 744 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", 745 | "dev": true 746 | }, 747 | "extend": { 748 | "version": "3.0.2", 749 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", 750 | "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", 751 | "dev": true 752 | }, 753 | "external-editor": { 754 | "version": "3.1.0", 755 | "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", 756 | "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", 757 | "dev": true, 758 | "requires": { 759 | "chardet": "^0.7.0", 760 | "iconv-lite": "^0.4.24", 761 | "tmp": "^0.0.33" 762 | } 763 | }, 764 | "extsprintf": { 765 | "version": "1.3.0", 766 | "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", 767 | "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", 768 | "dev": true 769 | }, 770 | "fast-deep-equal": { 771 | "version": "2.0.1", 772 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", 773 | "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", 774 | "dev": true 775 | }, 776 | "fast-json-stable-stringify": { 777 | "version": "2.0.0", 778 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", 779 | "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", 780 | "dev": true 781 | }, 782 | "fast-levenshtein": { 783 | "version": "2.0.6", 784 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 785 | "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", 786 | "dev": true 787 | }, 788 | "figures": { 789 | "version": "3.1.0", 790 | "resolved": "https://registry.npmjs.org/figures/-/figures-3.1.0.tgz", 791 | "integrity": "sha512-ravh8VRXqHuMvZt/d8GblBeqDMkdJMBdv/2KntFH+ra5MXkO7nxNKpzQ3n6QD/2da1kH0aWmNISdvhM7gl2gVg==", 792 | "dev": true, 793 | "requires": { 794 | "escape-string-regexp": "^1.0.5" 795 | } 796 | }, 797 | "file-entry-cache": { 798 | "version": "5.0.1", 799 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", 800 | "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", 801 | "dev": true, 802 | "requires": { 803 | "flat-cache": "^2.0.1" 804 | } 805 | }, 806 | "find-cache-dir": { 807 | "version": "2.1.0", 808 | "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", 809 | "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", 810 | "dev": true, 811 | "requires": { 812 | "commondir": "^1.0.1", 813 | "make-dir": "^2.0.0", 814 | "pkg-dir": "^3.0.0" 815 | } 816 | }, 817 | "find-up": { 818 | "version": "3.0.0", 819 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", 820 | "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", 821 | "dev": true, 822 | "requires": { 823 | "locate-path": "^3.0.0" 824 | } 825 | }, 826 | "flat-cache": { 827 | "version": "2.0.1", 828 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", 829 | "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", 830 | "dev": true, 831 | "requires": { 832 | "flatted": "^2.0.0", 833 | "rimraf": "2.6.3", 834 | "write": "1.0.3" 835 | } 836 | }, 837 | "flatted": { 838 | "version": "2.0.1", 839 | "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", 840 | "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", 841 | "dev": true 842 | }, 843 | "foreground-child": { 844 | "version": "1.5.6", 845 | "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz", 846 | "integrity": "sha1-T9ca0t/elnibmApcCilZN8svXOk=", 847 | "dev": true, 848 | "requires": { 849 | "cross-spawn": "^4", 850 | "signal-exit": "^3.0.0" 851 | }, 852 | "dependencies": { 853 | "cross-spawn": { 854 | "version": "4.0.2", 855 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", 856 | "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", 857 | "dev": true, 858 | "requires": { 859 | "lru-cache": "^4.0.1", 860 | "which": "^1.2.9" 861 | } 862 | } 863 | } 864 | }, 865 | "forever-agent": { 866 | "version": "0.6.1", 867 | "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", 868 | "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", 869 | "dev": true 870 | }, 871 | "form-data": { 872 | "version": "2.3.3", 873 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", 874 | "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", 875 | "dev": true, 876 | "requires": { 877 | "asynckit": "^0.4.0", 878 | "combined-stream": "^1.0.6", 879 | "mime-types": "^2.1.12" 880 | } 881 | }, 882 | "fs.realpath": { 883 | "version": "1.0.0", 884 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 885 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 886 | "dev": true 887 | }, 888 | "functional-red-black-tree": { 889 | "version": "1.0.1", 890 | "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", 891 | "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", 892 | "dev": true 893 | }, 894 | "get-caller-file": { 895 | "version": "2.0.5", 896 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", 897 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", 898 | "dev": true 899 | }, 900 | "getpass": { 901 | "version": "0.1.7", 902 | "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", 903 | "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", 904 | "dev": true, 905 | "requires": { 906 | "assert-plus": "^1.0.0" 907 | } 908 | }, 909 | "glob": { 910 | "version": "7.1.2", 911 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", 912 | "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", 913 | "dev": true, 914 | "requires": { 915 | "fs.realpath": "^1.0.0", 916 | "inflight": "^1.0.4", 917 | "inherits": "2", 918 | "minimatch": "^3.0.4", 919 | "once": "^1.3.0", 920 | "path-is-absolute": "^1.0.0" 921 | } 922 | }, 923 | "glob-parent": { 924 | "version": "5.1.0", 925 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", 926 | "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", 927 | "dev": true, 928 | "requires": { 929 | "is-glob": "^4.0.1" 930 | } 931 | }, 932 | "globals": { 933 | "version": "12.3.0", 934 | "resolved": "https://registry.npmjs.org/globals/-/globals-12.3.0.tgz", 935 | "integrity": "sha512-wAfjdLgFsPZsklLJvOBUBmzYE8/CwhEqSBEMRXA3qxIiNtyqvjYurAtIfDh6chlEPUfmTY3MnZh5Hfh4q0UlIw==", 936 | "dev": true, 937 | "requires": { 938 | "type-fest": "^0.8.1" 939 | } 940 | }, 941 | "graceful-fs": { 942 | "version": "4.2.3", 943 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", 944 | "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", 945 | "dev": true 946 | }, 947 | "growl": { 948 | "version": "1.10.3", 949 | "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", 950 | "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", 951 | "dev": true 952 | }, 953 | "handlebars": { 954 | "version": "4.5.3", 955 | "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.5.3.tgz", 956 | "integrity": "sha512-3yPecJoJHK/4c6aZhSvxOyG4vJKDshV36VHp0iVCDVh7o9w2vwi3NSnL2MMPj3YdduqaBcu7cGbggJQM0br9xA==", 957 | "dev": true, 958 | "requires": { 959 | "neo-async": "^2.6.0", 960 | "optimist": "^0.6.1", 961 | "source-map": "^0.6.1", 962 | "uglify-js": "^3.1.4" 963 | }, 964 | "dependencies": { 965 | "source-map": { 966 | "version": "0.6.1", 967 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 968 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 969 | "dev": true 970 | } 971 | } 972 | }, 973 | "har-schema": { 974 | "version": "2.0.0", 975 | "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", 976 | "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", 977 | "dev": true 978 | }, 979 | "har-validator": { 980 | "version": "5.1.3", 981 | "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", 982 | "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", 983 | "dev": true, 984 | "requires": { 985 | "ajv": "^6.5.5", 986 | "har-schema": "^2.0.0" 987 | } 988 | }, 989 | "has-flag": { 990 | "version": "2.0.0", 991 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", 992 | "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", 993 | "dev": true 994 | }, 995 | "hasha": { 996 | "version": "3.0.0", 997 | "resolved": "https://registry.npmjs.org/hasha/-/hasha-3.0.0.tgz", 998 | "integrity": "sha1-UqMvq4Vp1BymmmH/GiFPjrfIvTk=", 999 | "dev": true, 1000 | "requires": { 1001 | "is-stream": "^1.0.1" 1002 | } 1003 | }, 1004 | "he": { 1005 | "version": "1.1.1", 1006 | "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", 1007 | "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", 1008 | "dev": true 1009 | }, 1010 | "hosted-git-info": { 1011 | "version": "2.8.5", 1012 | "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.5.tgz", 1013 | "integrity": "sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==", 1014 | "dev": true 1015 | }, 1016 | "http-signature": { 1017 | "version": "1.2.0", 1018 | "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", 1019 | "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", 1020 | "dev": true, 1021 | "requires": { 1022 | "assert-plus": "^1.0.0", 1023 | "jsprim": "^1.2.2", 1024 | "sshpk": "^1.7.0" 1025 | } 1026 | }, 1027 | "iconv-lite": { 1028 | "version": "0.4.24", 1029 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 1030 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 1031 | "dev": true, 1032 | "requires": { 1033 | "safer-buffer": ">= 2.1.2 < 3" 1034 | } 1035 | }, 1036 | "ignore": { 1037 | "version": "4.0.6", 1038 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", 1039 | "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", 1040 | "dev": true 1041 | }, 1042 | "import-fresh": { 1043 | "version": "3.2.1", 1044 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", 1045 | "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", 1046 | "dev": true, 1047 | "requires": { 1048 | "parent-module": "^1.0.0", 1049 | "resolve-from": "^4.0.0" 1050 | } 1051 | }, 1052 | "imurmurhash": { 1053 | "version": "0.1.4", 1054 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 1055 | "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", 1056 | "dev": true 1057 | }, 1058 | "inflight": { 1059 | "version": "1.0.6", 1060 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 1061 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 1062 | "dev": true, 1063 | "requires": { 1064 | "once": "^1.3.0", 1065 | "wrappy": "1" 1066 | } 1067 | }, 1068 | "inherits": { 1069 | "version": "2.0.4", 1070 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 1071 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 1072 | "dev": true 1073 | }, 1074 | "inquirer": { 1075 | "version": "7.0.0", 1076 | "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.0.0.tgz", 1077 | "integrity": "sha512-rSdC7zelHdRQFkWnhsMu2+2SO41mpv2oF2zy4tMhmiLWkcKbOAs87fWAJhVXttKVwhdZvymvnuM95EyEXg2/tQ==", 1078 | "dev": true, 1079 | "requires": { 1080 | "ansi-escapes": "^4.2.1", 1081 | "chalk": "^2.4.2", 1082 | "cli-cursor": "^3.1.0", 1083 | "cli-width": "^2.0.0", 1084 | "external-editor": "^3.0.3", 1085 | "figures": "^3.0.0", 1086 | "lodash": "^4.17.15", 1087 | "mute-stream": "0.0.8", 1088 | "run-async": "^2.2.0", 1089 | "rxjs": "^6.4.0", 1090 | "string-width": "^4.1.0", 1091 | "strip-ansi": "^5.1.0", 1092 | "through": "^2.3.6" 1093 | } 1094 | }, 1095 | "is-arrayish": { 1096 | "version": "0.2.1", 1097 | "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", 1098 | "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", 1099 | "dev": true 1100 | }, 1101 | "is-extglob": { 1102 | "version": "2.1.1", 1103 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 1104 | "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", 1105 | "dev": true 1106 | }, 1107 | "is-fullwidth-code-point": { 1108 | "version": "3.0.0", 1109 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 1110 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", 1111 | "dev": true 1112 | }, 1113 | "is-glob": { 1114 | "version": "4.0.1", 1115 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", 1116 | "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", 1117 | "dev": true, 1118 | "requires": { 1119 | "is-extglob": "^2.1.1" 1120 | } 1121 | }, 1122 | "is-promise": { 1123 | "version": "2.1.0", 1124 | "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", 1125 | "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", 1126 | "dev": true 1127 | }, 1128 | "is-stream": { 1129 | "version": "1.1.0", 1130 | "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", 1131 | "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", 1132 | "dev": true 1133 | }, 1134 | "is-typedarray": { 1135 | "version": "1.0.0", 1136 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", 1137 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", 1138 | "dev": true 1139 | }, 1140 | "isexe": { 1141 | "version": "2.0.0", 1142 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 1143 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", 1144 | "dev": true 1145 | }, 1146 | "isstream": { 1147 | "version": "0.1.2", 1148 | "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", 1149 | "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", 1150 | "dev": true 1151 | }, 1152 | "istanbul-lib-coverage": { 1153 | "version": "2.0.5", 1154 | "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", 1155 | "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", 1156 | "dev": true 1157 | }, 1158 | "istanbul-lib-hook": { 1159 | "version": "2.0.7", 1160 | "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-2.0.7.tgz", 1161 | "integrity": "sha512-vrRztU9VRRFDyC+aklfLoeXyNdTfga2EI3udDGn4cZ6fpSXpHLV9X6CHvfoMCPtggg8zvDDmC4b9xfu0z6/llA==", 1162 | "dev": true, 1163 | "requires": { 1164 | "append-transform": "^1.0.0" 1165 | } 1166 | }, 1167 | "istanbul-lib-instrument": { 1168 | "version": "3.3.0", 1169 | "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz", 1170 | "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==", 1171 | "dev": true, 1172 | "requires": { 1173 | "@babel/generator": "^7.4.0", 1174 | "@babel/parser": "^7.4.3", 1175 | "@babel/template": "^7.4.0", 1176 | "@babel/traverse": "^7.4.3", 1177 | "@babel/types": "^7.4.0", 1178 | "istanbul-lib-coverage": "^2.0.5", 1179 | "semver": "^6.0.0" 1180 | } 1181 | }, 1182 | "istanbul-lib-report": { 1183 | "version": "2.0.8", 1184 | "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz", 1185 | "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==", 1186 | "dev": true, 1187 | "requires": { 1188 | "istanbul-lib-coverage": "^2.0.5", 1189 | "make-dir": "^2.1.0", 1190 | "supports-color": "^6.1.0" 1191 | }, 1192 | "dependencies": { 1193 | "has-flag": { 1194 | "version": "3.0.0", 1195 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 1196 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 1197 | "dev": true 1198 | }, 1199 | "supports-color": { 1200 | "version": "6.1.0", 1201 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", 1202 | "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", 1203 | "dev": true, 1204 | "requires": { 1205 | "has-flag": "^3.0.0" 1206 | } 1207 | } 1208 | } 1209 | }, 1210 | "istanbul-lib-source-maps": { 1211 | "version": "3.0.6", 1212 | "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", 1213 | "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", 1214 | "dev": true, 1215 | "requires": { 1216 | "debug": "^4.1.1", 1217 | "istanbul-lib-coverage": "^2.0.5", 1218 | "make-dir": "^2.1.0", 1219 | "rimraf": "^2.6.3", 1220 | "source-map": "^0.6.1" 1221 | }, 1222 | "dependencies": { 1223 | "debug": { 1224 | "version": "4.1.1", 1225 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", 1226 | "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", 1227 | "dev": true, 1228 | "requires": { 1229 | "ms": "^2.1.1" 1230 | } 1231 | }, 1232 | "ms": { 1233 | "version": "2.1.2", 1234 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 1235 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 1236 | "dev": true 1237 | }, 1238 | "source-map": { 1239 | "version": "0.6.1", 1240 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 1241 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 1242 | "dev": true 1243 | } 1244 | } 1245 | }, 1246 | "istanbul-reports": { 1247 | "version": "2.2.6", 1248 | "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.6.tgz", 1249 | "integrity": "sha512-SKi4rnMyLBKe0Jy2uUdx28h8oG7ph2PPuQPvIAh31d+Ci+lSiEu4C+h3oBPuJ9+mPKhOyW0M8gY4U5NM1WLeXA==", 1250 | "dev": true, 1251 | "requires": { 1252 | "handlebars": "^4.1.2" 1253 | } 1254 | }, 1255 | "jasmine": { 1256 | "version": "3.5.0", 1257 | "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-3.5.0.tgz", 1258 | "integrity": "sha512-DYypSryORqzsGoMazemIHUfMkXM7I7easFaxAvNM3Mr6Xz3Fy36TupTrAOxZWN8MVKEU5xECv22J4tUQf3uBzQ==", 1259 | "dev": true, 1260 | "requires": { 1261 | "glob": "^7.1.4", 1262 | "jasmine-core": "~3.5.0" 1263 | }, 1264 | "dependencies": { 1265 | "glob": { 1266 | "version": "7.1.6", 1267 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", 1268 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", 1269 | "dev": true, 1270 | "requires": { 1271 | "fs.realpath": "^1.0.0", 1272 | "inflight": "^1.0.4", 1273 | "inherits": "2", 1274 | "minimatch": "^3.0.4", 1275 | "once": "^1.3.0", 1276 | "path-is-absolute": "^1.0.0" 1277 | } 1278 | } 1279 | } 1280 | }, 1281 | "jasmine-core": { 1282 | "version": "3.5.0", 1283 | "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-3.5.0.tgz", 1284 | "integrity": "sha512-nCeAiw37MIMA9w9IXso7bRaLl+c/ef3wnxsoSAlYrzS+Ot0zTG6nU8G/cIfGkqpkjX2wNaIW9RFG0TwIFnG6bA==", 1285 | "dev": true 1286 | }, 1287 | "js-tokens": { 1288 | "version": "4.0.0", 1289 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", 1290 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", 1291 | "dev": true 1292 | }, 1293 | "js-yaml": { 1294 | "version": "3.13.1", 1295 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", 1296 | "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", 1297 | "dev": true, 1298 | "requires": { 1299 | "argparse": "^1.0.7", 1300 | "esprima": "^4.0.0" 1301 | } 1302 | }, 1303 | "jsbn": { 1304 | "version": "0.1.1", 1305 | "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", 1306 | "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", 1307 | "dev": true 1308 | }, 1309 | "jsesc": { 1310 | "version": "2.5.2", 1311 | "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", 1312 | "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", 1313 | "dev": true 1314 | }, 1315 | "json-parse-better-errors": { 1316 | "version": "1.0.2", 1317 | "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", 1318 | "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", 1319 | "dev": true 1320 | }, 1321 | "json-schema": { 1322 | "version": "0.2.3", 1323 | "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", 1324 | "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", 1325 | "dev": true 1326 | }, 1327 | "json-schema-traverse": { 1328 | "version": "0.4.1", 1329 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 1330 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", 1331 | "dev": true 1332 | }, 1333 | "json-stable-stringify-without-jsonify": { 1334 | "version": "1.0.1", 1335 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", 1336 | "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", 1337 | "dev": true 1338 | }, 1339 | "json-stringify-safe": { 1340 | "version": "5.0.1", 1341 | "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", 1342 | "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", 1343 | "dev": true 1344 | }, 1345 | "jsprim": { 1346 | "version": "1.4.1", 1347 | "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", 1348 | "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", 1349 | "dev": true, 1350 | "requires": { 1351 | "assert-plus": "1.0.0", 1352 | "extsprintf": "1.3.0", 1353 | "json-schema": "0.2.3", 1354 | "verror": "1.10.0" 1355 | } 1356 | }, 1357 | "lcov-parse": { 1358 | "version": "1.0.0", 1359 | "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-1.0.0.tgz", 1360 | "integrity": "sha1-6w1GtUER68VhrLTECO+TY73I9+A=", 1361 | "dev": true 1362 | }, 1363 | "levn": { 1364 | "version": "0.3.0", 1365 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", 1366 | "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", 1367 | "dev": true, 1368 | "requires": { 1369 | "prelude-ls": "~1.1.2", 1370 | "type-check": "~0.3.2" 1371 | } 1372 | }, 1373 | "load-json-file": { 1374 | "version": "4.0.0", 1375 | "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", 1376 | "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", 1377 | "dev": true, 1378 | "requires": { 1379 | "graceful-fs": "^4.1.2", 1380 | "parse-json": "^4.0.0", 1381 | "pify": "^3.0.0", 1382 | "strip-bom": "^3.0.0" 1383 | }, 1384 | "dependencies": { 1385 | "pify": { 1386 | "version": "3.0.0", 1387 | "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", 1388 | "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", 1389 | "dev": true 1390 | } 1391 | } 1392 | }, 1393 | "locate-path": { 1394 | "version": "3.0.0", 1395 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", 1396 | "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", 1397 | "dev": true, 1398 | "requires": { 1399 | "p-locate": "^3.0.0", 1400 | "path-exists": "^3.0.0" 1401 | } 1402 | }, 1403 | "lodash": { 1404 | "version": "4.17.15", 1405 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", 1406 | "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", 1407 | "dev": true 1408 | }, 1409 | "lodash.flattendeep": { 1410 | "version": "4.4.0", 1411 | "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", 1412 | "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", 1413 | "dev": true 1414 | }, 1415 | "lodash.isarray": { 1416 | "version": "4.0.0", 1417 | "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-4.0.0.tgz", 1418 | "integrity": "sha1-KspJayjEym1yZxUxNZDALm6jRAM=" 1419 | }, 1420 | "lodash.isfunction": { 1421 | "version": "3.0.9", 1422 | "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz", 1423 | "integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==" 1424 | }, 1425 | "lodash.isplainobject": { 1426 | "version": "4.0.6", 1427 | "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", 1428 | "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" 1429 | }, 1430 | "lodash.keys": { 1431 | "version": "4.2.0", 1432 | "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-4.2.0.tgz", 1433 | "integrity": "sha1-oIYCrBLk+4P5H8H7ejYKTZujUgU=" 1434 | }, 1435 | "lodash.values": { 1436 | "version": "4.3.0", 1437 | "resolved": "https://registry.npmjs.org/lodash.values/-/lodash.values-4.3.0.tgz", 1438 | "integrity": "sha1-o6bCsOvsxcLLocF+bmIP6BtT00c=" 1439 | }, 1440 | "log-driver": { 1441 | "version": "1.2.7", 1442 | "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", 1443 | "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==", 1444 | "dev": true 1445 | }, 1446 | "lru-cache": { 1447 | "version": "4.1.5", 1448 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", 1449 | "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", 1450 | "dev": true, 1451 | "requires": { 1452 | "pseudomap": "^1.0.2", 1453 | "yallist": "^2.1.2" 1454 | } 1455 | }, 1456 | "make-dir": { 1457 | "version": "2.1.0", 1458 | "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", 1459 | "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", 1460 | "dev": true, 1461 | "requires": { 1462 | "pify": "^4.0.1", 1463 | "semver": "^5.6.0" 1464 | }, 1465 | "dependencies": { 1466 | "semver": { 1467 | "version": "5.7.1", 1468 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", 1469 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", 1470 | "dev": true 1471 | } 1472 | } 1473 | }, 1474 | "merge-source-map": { 1475 | "version": "1.1.0", 1476 | "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", 1477 | "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", 1478 | "dev": true, 1479 | "requires": { 1480 | "source-map": "^0.6.1" 1481 | }, 1482 | "dependencies": { 1483 | "source-map": { 1484 | "version": "0.6.1", 1485 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 1486 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 1487 | "dev": true 1488 | } 1489 | } 1490 | }, 1491 | "mime-db": { 1492 | "version": "1.42.0", 1493 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.42.0.tgz", 1494 | "integrity": "sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ==", 1495 | "dev": true 1496 | }, 1497 | "mime-types": { 1498 | "version": "2.1.25", 1499 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.25.tgz", 1500 | "integrity": "sha512-5KhStqB5xpTAeGqKBAMgwaYMnQik7teQN4IAzC7npDv6kzeU6prfkR67bc87J1kWMPGkoaZSq1npmexMgkmEVg==", 1501 | "dev": true, 1502 | "requires": { 1503 | "mime-db": "1.42.0" 1504 | } 1505 | }, 1506 | "mimic-fn": { 1507 | "version": "2.1.0", 1508 | "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", 1509 | "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", 1510 | "dev": true 1511 | }, 1512 | "minimatch": { 1513 | "version": "3.0.4", 1514 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 1515 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 1516 | "dev": true, 1517 | "requires": { 1518 | "brace-expansion": "^1.1.7" 1519 | } 1520 | }, 1521 | "minimist": { 1522 | "version": "1.2.0", 1523 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", 1524 | "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", 1525 | "dev": true 1526 | }, 1527 | "mkdirp": { 1528 | "version": "0.5.1", 1529 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", 1530 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", 1531 | "dev": true, 1532 | "requires": { 1533 | "minimist": "0.0.8" 1534 | }, 1535 | "dependencies": { 1536 | "minimist": { 1537 | "version": "0.0.8", 1538 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", 1539 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", 1540 | "dev": true 1541 | } 1542 | } 1543 | }, 1544 | "mocha": { 1545 | "version": "5.0.5", 1546 | "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.0.5.tgz", 1547 | "integrity": "sha512-3MM3UjZ5p8EJrYpG7s+29HAI9G7sTzKEe4+w37Dg0QP7qL4XGsV+Q2xet2cE37AqdgN1OtYQB6Vl98YiPV3PgA==", 1548 | "dev": true, 1549 | "requires": { 1550 | "browser-stdout": "1.3.1", 1551 | "commander": "2.11.0", 1552 | "debug": "3.1.0", 1553 | "diff": "3.5.0", 1554 | "escape-string-regexp": "1.0.5", 1555 | "glob": "7.1.2", 1556 | "growl": "1.10.3", 1557 | "he": "1.1.1", 1558 | "mkdirp": "0.5.1", 1559 | "supports-color": "4.4.0" 1560 | } 1561 | }, 1562 | "ms": { 1563 | "version": "2.0.0", 1564 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 1565 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", 1566 | "dev": true 1567 | }, 1568 | "mute-stream": { 1569 | "version": "0.0.8", 1570 | "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", 1571 | "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", 1572 | "dev": true 1573 | }, 1574 | "natural-compare": { 1575 | "version": "1.4.0", 1576 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", 1577 | "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", 1578 | "dev": true 1579 | }, 1580 | "neo-async": { 1581 | "version": "2.6.1", 1582 | "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", 1583 | "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", 1584 | "dev": true 1585 | }, 1586 | "nested-error-stacks": { 1587 | "version": "2.1.0", 1588 | "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz", 1589 | "integrity": "sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug==", 1590 | "dev": true 1591 | }, 1592 | "nice-try": { 1593 | "version": "1.0.5", 1594 | "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", 1595 | "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", 1596 | "dev": true 1597 | }, 1598 | "normalize-package-data": { 1599 | "version": "2.5.0", 1600 | "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", 1601 | "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", 1602 | "dev": true, 1603 | "requires": { 1604 | "hosted-git-info": "^2.1.4", 1605 | "resolve": "^1.10.0", 1606 | "semver": "2 || 3 || 4 || 5", 1607 | "validate-npm-package-license": "^3.0.1" 1608 | }, 1609 | "dependencies": { 1610 | "semver": { 1611 | "version": "5.7.1", 1612 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", 1613 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", 1614 | "dev": true 1615 | } 1616 | } 1617 | }, 1618 | "nyc": { 1619 | "version": "14.1.1", 1620 | "resolved": "https://registry.npmjs.org/nyc/-/nyc-14.1.1.tgz", 1621 | "integrity": "sha512-OI0vm6ZGUnoGZv/tLdZ2esSVzDwUC88SNs+6JoSOMVxA+gKMB8Tk7jBwgemLx4O40lhhvZCVw1C+OYLOBOPXWw==", 1622 | "dev": true, 1623 | "requires": { 1624 | "archy": "^1.0.0", 1625 | "caching-transform": "^3.0.2", 1626 | "convert-source-map": "^1.6.0", 1627 | "cp-file": "^6.2.0", 1628 | "find-cache-dir": "^2.1.0", 1629 | "find-up": "^3.0.0", 1630 | "foreground-child": "^1.5.6", 1631 | "glob": "^7.1.3", 1632 | "istanbul-lib-coverage": "^2.0.5", 1633 | "istanbul-lib-hook": "^2.0.7", 1634 | "istanbul-lib-instrument": "^3.3.0", 1635 | "istanbul-lib-report": "^2.0.8", 1636 | "istanbul-lib-source-maps": "^3.0.6", 1637 | "istanbul-reports": "^2.2.4", 1638 | "js-yaml": "^3.13.1", 1639 | "make-dir": "^2.1.0", 1640 | "merge-source-map": "^1.1.0", 1641 | "resolve-from": "^4.0.0", 1642 | "rimraf": "^2.6.3", 1643 | "signal-exit": "^3.0.2", 1644 | "spawn-wrap": "^1.4.2", 1645 | "test-exclude": "^5.2.3", 1646 | "uuid": "^3.3.2", 1647 | "yargs": "^13.2.2", 1648 | "yargs-parser": "^13.0.0" 1649 | }, 1650 | "dependencies": { 1651 | "glob": { 1652 | "version": "7.1.6", 1653 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", 1654 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", 1655 | "dev": true, 1656 | "requires": { 1657 | "fs.realpath": "^1.0.0", 1658 | "inflight": "^1.0.4", 1659 | "inherits": "2", 1660 | "minimatch": "^3.0.4", 1661 | "once": "^1.3.0", 1662 | "path-is-absolute": "^1.0.0" 1663 | } 1664 | } 1665 | } 1666 | }, 1667 | "oauth-sign": { 1668 | "version": "0.9.0", 1669 | "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", 1670 | "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", 1671 | "dev": true 1672 | }, 1673 | "once": { 1674 | "version": "1.4.0", 1675 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1676 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 1677 | "dev": true, 1678 | "requires": { 1679 | "wrappy": "1" 1680 | } 1681 | }, 1682 | "onetime": { 1683 | "version": "5.1.0", 1684 | "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", 1685 | "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", 1686 | "dev": true, 1687 | "requires": { 1688 | "mimic-fn": "^2.1.0" 1689 | } 1690 | }, 1691 | "optimist": { 1692 | "version": "0.6.1", 1693 | "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", 1694 | "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", 1695 | "dev": true, 1696 | "requires": { 1697 | "minimist": "~0.0.1", 1698 | "wordwrap": "~0.0.2" 1699 | }, 1700 | "dependencies": { 1701 | "minimist": { 1702 | "version": "0.0.10", 1703 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", 1704 | "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", 1705 | "dev": true 1706 | } 1707 | } 1708 | }, 1709 | "optionator": { 1710 | "version": "0.8.3", 1711 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", 1712 | "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", 1713 | "dev": true, 1714 | "requires": { 1715 | "deep-is": "~0.1.3", 1716 | "fast-levenshtein": "~2.0.6", 1717 | "levn": "~0.3.0", 1718 | "prelude-ls": "~1.1.2", 1719 | "type-check": "~0.3.2", 1720 | "word-wrap": "~1.2.3" 1721 | } 1722 | }, 1723 | "os-homedir": { 1724 | "version": "1.0.2", 1725 | "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", 1726 | "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", 1727 | "dev": true 1728 | }, 1729 | "os-tmpdir": { 1730 | "version": "1.0.2", 1731 | "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", 1732 | "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", 1733 | "dev": true 1734 | }, 1735 | "p-limit": { 1736 | "version": "2.2.1", 1737 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", 1738 | "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", 1739 | "dev": true, 1740 | "requires": { 1741 | "p-try": "^2.0.0" 1742 | } 1743 | }, 1744 | "p-locate": { 1745 | "version": "3.0.0", 1746 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", 1747 | "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", 1748 | "dev": true, 1749 | "requires": { 1750 | "p-limit": "^2.0.0" 1751 | } 1752 | }, 1753 | "p-try": { 1754 | "version": "2.2.0", 1755 | "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", 1756 | "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", 1757 | "dev": true 1758 | }, 1759 | "package-hash": { 1760 | "version": "3.0.0", 1761 | "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-3.0.0.tgz", 1762 | "integrity": "sha512-lOtmukMDVvtkL84rJHI7dpTYq+0rli8N2wlnqUcBuDWCfVhRUfOmnR9SsoHFMLpACvEV60dX7rd0rFaYDZI+FA==", 1763 | "dev": true, 1764 | "requires": { 1765 | "graceful-fs": "^4.1.15", 1766 | "hasha": "^3.0.0", 1767 | "lodash.flattendeep": "^4.4.0", 1768 | "release-zalgo": "^1.0.0" 1769 | } 1770 | }, 1771 | "parent-module": { 1772 | "version": "1.0.1", 1773 | "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", 1774 | "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", 1775 | "dev": true, 1776 | "requires": { 1777 | "callsites": "^3.0.0" 1778 | } 1779 | }, 1780 | "parse-json": { 1781 | "version": "4.0.0", 1782 | "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", 1783 | "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", 1784 | "dev": true, 1785 | "requires": { 1786 | "error-ex": "^1.3.1", 1787 | "json-parse-better-errors": "^1.0.1" 1788 | } 1789 | }, 1790 | "path-exists": { 1791 | "version": "3.0.0", 1792 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", 1793 | "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", 1794 | "dev": true 1795 | }, 1796 | "path-is-absolute": { 1797 | "version": "1.0.1", 1798 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 1799 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 1800 | "dev": true 1801 | }, 1802 | "path-key": { 1803 | "version": "2.0.1", 1804 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", 1805 | "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", 1806 | "dev": true 1807 | }, 1808 | "path-parse": { 1809 | "version": "1.0.6", 1810 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", 1811 | "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", 1812 | "dev": true 1813 | }, 1814 | "path-type": { 1815 | "version": "3.0.0", 1816 | "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", 1817 | "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", 1818 | "dev": true, 1819 | "requires": { 1820 | "pify": "^3.0.0" 1821 | }, 1822 | "dependencies": { 1823 | "pify": { 1824 | "version": "3.0.0", 1825 | "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", 1826 | "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", 1827 | "dev": true 1828 | } 1829 | } 1830 | }, 1831 | "performance-now": { 1832 | "version": "2.1.0", 1833 | "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", 1834 | "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", 1835 | "dev": true 1836 | }, 1837 | "pify": { 1838 | "version": "4.0.1", 1839 | "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", 1840 | "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", 1841 | "dev": true 1842 | }, 1843 | "pkg-dir": { 1844 | "version": "3.0.0", 1845 | "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", 1846 | "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", 1847 | "dev": true, 1848 | "requires": { 1849 | "find-up": "^3.0.0" 1850 | } 1851 | }, 1852 | "prelude-ls": { 1853 | "version": "1.1.2", 1854 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", 1855 | "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", 1856 | "dev": true 1857 | }, 1858 | "progress": { 1859 | "version": "2.0.3", 1860 | "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", 1861 | "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", 1862 | "dev": true 1863 | }, 1864 | "pseudomap": { 1865 | "version": "1.0.2", 1866 | "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", 1867 | "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", 1868 | "dev": true 1869 | }, 1870 | "psl": { 1871 | "version": "1.4.0", 1872 | "resolved": "https://registry.npmjs.org/psl/-/psl-1.4.0.tgz", 1873 | "integrity": "sha512-HZzqCGPecFLyoRj5HLfuDSKYTJkAfB5thKBIkRHtGjWwY7p1dAyveIbXIq4tO0KYfDF2tHqPUgY9SDnGm00uFw==", 1874 | "dev": true 1875 | }, 1876 | "punycode": { 1877 | "version": "2.1.1", 1878 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", 1879 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", 1880 | "dev": true 1881 | }, 1882 | "qs": { 1883 | "version": "6.5.2", 1884 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", 1885 | "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", 1886 | "dev": true 1887 | }, 1888 | "read-pkg": { 1889 | "version": "3.0.0", 1890 | "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", 1891 | "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", 1892 | "dev": true, 1893 | "requires": { 1894 | "load-json-file": "^4.0.0", 1895 | "normalize-package-data": "^2.3.2", 1896 | "path-type": "^3.0.0" 1897 | } 1898 | }, 1899 | "read-pkg-up": { 1900 | "version": "4.0.0", 1901 | "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", 1902 | "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", 1903 | "dev": true, 1904 | "requires": { 1905 | "find-up": "^3.0.0", 1906 | "read-pkg": "^3.0.0" 1907 | } 1908 | }, 1909 | "regexpp": { 1910 | "version": "2.0.1", 1911 | "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", 1912 | "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", 1913 | "dev": true 1914 | }, 1915 | "release-zalgo": { 1916 | "version": "1.0.0", 1917 | "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", 1918 | "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", 1919 | "dev": true, 1920 | "requires": { 1921 | "es6-error": "^4.0.1" 1922 | } 1923 | }, 1924 | "request": { 1925 | "version": "2.88.0", 1926 | "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", 1927 | "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", 1928 | "dev": true, 1929 | "requires": { 1930 | "aws-sign2": "~0.7.0", 1931 | "aws4": "^1.8.0", 1932 | "caseless": "~0.12.0", 1933 | "combined-stream": "~1.0.6", 1934 | "extend": "~3.0.2", 1935 | "forever-agent": "~0.6.1", 1936 | "form-data": "~2.3.2", 1937 | "har-validator": "~5.1.0", 1938 | "http-signature": "~1.2.0", 1939 | "is-typedarray": "~1.0.0", 1940 | "isstream": "~0.1.2", 1941 | "json-stringify-safe": "~5.0.1", 1942 | "mime-types": "~2.1.19", 1943 | "oauth-sign": "~0.9.0", 1944 | "performance-now": "^2.1.0", 1945 | "qs": "~6.5.2", 1946 | "safe-buffer": "^5.1.2", 1947 | "tough-cookie": "~2.4.3", 1948 | "tunnel-agent": "^0.6.0", 1949 | "uuid": "^3.3.2" 1950 | } 1951 | }, 1952 | "require-directory": { 1953 | "version": "2.1.1", 1954 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", 1955 | "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", 1956 | "dev": true 1957 | }, 1958 | "require-main-filename": { 1959 | "version": "2.0.0", 1960 | "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", 1961 | "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", 1962 | "dev": true 1963 | }, 1964 | "resolve": { 1965 | "version": "1.12.2", 1966 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.2.tgz", 1967 | "integrity": "sha512-cAVTI2VLHWYsGOirfeYVVQ7ZDejtQ9fp4YhYckWDEkFfqbVjaT11iM8k6xSAfGFMM+gDpZjMnFssPu8we+mqFw==", 1968 | "dev": true, 1969 | "requires": { 1970 | "path-parse": "^1.0.6" 1971 | } 1972 | }, 1973 | "resolve-from": { 1974 | "version": "4.0.0", 1975 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", 1976 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", 1977 | "dev": true 1978 | }, 1979 | "restore-cursor": { 1980 | "version": "3.1.0", 1981 | "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", 1982 | "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", 1983 | "dev": true, 1984 | "requires": { 1985 | "onetime": "^5.1.0", 1986 | "signal-exit": "^3.0.2" 1987 | } 1988 | }, 1989 | "rimraf": { 1990 | "version": "2.6.3", 1991 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", 1992 | "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", 1993 | "dev": true, 1994 | "requires": { 1995 | "glob": "^7.1.3" 1996 | }, 1997 | "dependencies": { 1998 | "glob": { 1999 | "version": "7.1.6", 2000 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", 2001 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", 2002 | "dev": true, 2003 | "requires": { 2004 | "fs.realpath": "^1.0.0", 2005 | "inflight": "^1.0.4", 2006 | "inherits": "2", 2007 | "minimatch": "^3.0.4", 2008 | "once": "^1.3.0", 2009 | "path-is-absolute": "^1.0.0" 2010 | } 2011 | } 2012 | } 2013 | }, 2014 | "run-async": { 2015 | "version": "2.3.0", 2016 | "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", 2017 | "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", 2018 | "dev": true, 2019 | "requires": { 2020 | "is-promise": "^2.1.0" 2021 | } 2022 | }, 2023 | "rxjs": { 2024 | "version": "6.5.3", 2025 | "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.3.tgz", 2026 | "integrity": "sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA==", 2027 | "dev": true, 2028 | "requires": { 2029 | "tslib": "^1.9.0" 2030 | } 2031 | }, 2032 | "safe-buffer": { 2033 | "version": "5.2.0", 2034 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", 2035 | "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==", 2036 | "dev": true 2037 | }, 2038 | "safer-buffer": { 2039 | "version": "2.1.2", 2040 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 2041 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", 2042 | "dev": true 2043 | }, 2044 | "sax": { 2045 | "version": "1.2.4", 2046 | "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", 2047 | "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", 2048 | "dev": true 2049 | }, 2050 | "semver": { 2051 | "version": "6.3.0", 2052 | "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", 2053 | "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", 2054 | "dev": true 2055 | }, 2056 | "set-blocking": { 2057 | "version": "2.0.0", 2058 | "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", 2059 | "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", 2060 | "dev": true 2061 | }, 2062 | "shebang-command": { 2063 | "version": "1.2.0", 2064 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", 2065 | "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", 2066 | "dev": true, 2067 | "requires": { 2068 | "shebang-regex": "^1.0.0" 2069 | } 2070 | }, 2071 | "shebang-regex": { 2072 | "version": "1.0.0", 2073 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", 2074 | "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", 2075 | "dev": true 2076 | }, 2077 | "signal-exit": { 2078 | "version": "3.0.2", 2079 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", 2080 | "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", 2081 | "dev": true 2082 | }, 2083 | "slice-ansi": { 2084 | "version": "2.1.0", 2085 | "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", 2086 | "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", 2087 | "dev": true, 2088 | "requires": { 2089 | "ansi-styles": "^3.2.0", 2090 | "astral-regex": "^1.0.0", 2091 | "is-fullwidth-code-point": "^2.0.0" 2092 | }, 2093 | "dependencies": { 2094 | "is-fullwidth-code-point": { 2095 | "version": "2.0.0", 2096 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 2097 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", 2098 | "dev": true 2099 | } 2100 | } 2101 | }, 2102 | "source-map": { 2103 | "version": "0.5.7", 2104 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", 2105 | "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", 2106 | "dev": true 2107 | }, 2108 | "spawn-wrap": { 2109 | "version": "1.4.3", 2110 | "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-1.4.3.tgz", 2111 | "integrity": "sha512-IgB8md0QW/+tWqcavuFgKYR/qIRvJkRLPJDFaoXtLLUaVcCDK0+HeFTkmQHj3eprcYhc+gOl0aEA1w7qZlYezw==", 2112 | "dev": true, 2113 | "requires": { 2114 | "foreground-child": "^1.5.6", 2115 | "mkdirp": "^0.5.0", 2116 | "os-homedir": "^1.0.1", 2117 | "rimraf": "^2.6.2", 2118 | "signal-exit": "^3.0.2", 2119 | "which": "^1.3.0" 2120 | } 2121 | }, 2122 | "spdx-correct": { 2123 | "version": "3.1.0", 2124 | "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", 2125 | "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", 2126 | "dev": true, 2127 | "requires": { 2128 | "spdx-expression-parse": "^3.0.0", 2129 | "spdx-license-ids": "^3.0.0" 2130 | } 2131 | }, 2132 | "spdx-exceptions": { 2133 | "version": "2.2.0", 2134 | "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", 2135 | "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", 2136 | "dev": true 2137 | }, 2138 | "spdx-expression-parse": { 2139 | "version": "3.0.0", 2140 | "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", 2141 | "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", 2142 | "dev": true, 2143 | "requires": { 2144 | "spdx-exceptions": "^2.1.0", 2145 | "spdx-license-ids": "^3.0.0" 2146 | } 2147 | }, 2148 | "spdx-license-ids": { 2149 | "version": "3.0.5", 2150 | "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", 2151 | "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", 2152 | "dev": true 2153 | }, 2154 | "sprintf-js": { 2155 | "version": "1.0.3", 2156 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", 2157 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", 2158 | "dev": true 2159 | }, 2160 | "sshpk": { 2161 | "version": "1.16.1", 2162 | "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", 2163 | "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", 2164 | "dev": true, 2165 | "requires": { 2166 | "asn1": "~0.2.3", 2167 | "assert-plus": "^1.0.0", 2168 | "bcrypt-pbkdf": "^1.0.0", 2169 | "dashdash": "^1.12.0", 2170 | "ecc-jsbn": "~0.1.1", 2171 | "getpass": "^0.1.1", 2172 | "jsbn": "~0.1.0", 2173 | "safer-buffer": "^2.0.2", 2174 | "tweetnacl": "~0.14.0" 2175 | } 2176 | }, 2177 | "string-width": { 2178 | "version": "4.2.0", 2179 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", 2180 | "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", 2181 | "dev": true, 2182 | "requires": { 2183 | "emoji-regex": "^8.0.0", 2184 | "is-fullwidth-code-point": "^3.0.0", 2185 | "strip-ansi": "^6.0.0" 2186 | }, 2187 | "dependencies": { 2188 | "strip-ansi": { 2189 | "version": "6.0.0", 2190 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", 2191 | "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", 2192 | "dev": true, 2193 | "requires": { 2194 | "ansi-regex": "^5.0.0" 2195 | } 2196 | } 2197 | } 2198 | }, 2199 | "strip-ansi": { 2200 | "version": "5.2.0", 2201 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", 2202 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", 2203 | "dev": true, 2204 | "requires": { 2205 | "ansi-regex": "^4.1.0" 2206 | }, 2207 | "dependencies": { 2208 | "ansi-regex": { 2209 | "version": "4.1.0", 2210 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", 2211 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", 2212 | "dev": true 2213 | } 2214 | } 2215 | }, 2216 | "strip-bom": { 2217 | "version": "3.0.0", 2218 | "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", 2219 | "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", 2220 | "dev": true 2221 | }, 2222 | "strip-json-comments": { 2223 | "version": "3.0.1", 2224 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", 2225 | "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", 2226 | "dev": true 2227 | }, 2228 | "supports-color": { 2229 | "version": "4.4.0", 2230 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", 2231 | "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", 2232 | "dev": true, 2233 | "requires": { 2234 | "has-flag": "^2.0.0" 2235 | } 2236 | }, 2237 | "table": { 2238 | "version": "5.4.6", 2239 | "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", 2240 | "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", 2241 | "dev": true, 2242 | "requires": { 2243 | "ajv": "^6.10.2", 2244 | "lodash": "^4.17.14", 2245 | "slice-ansi": "^2.1.0", 2246 | "string-width": "^3.0.0" 2247 | }, 2248 | "dependencies": { 2249 | "emoji-regex": { 2250 | "version": "7.0.3", 2251 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", 2252 | "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", 2253 | "dev": true 2254 | }, 2255 | "is-fullwidth-code-point": { 2256 | "version": "2.0.0", 2257 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 2258 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", 2259 | "dev": true 2260 | }, 2261 | "string-width": { 2262 | "version": "3.1.0", 2263 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", 2264 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", 2265 | "dev": true, 2266 | "requires": { 2267 | "emoji-regex": "^7.0.1", 2268 | "is-fullwidth-code-point": "^2.0.0", 2269 | "strip-ansi": "^5.1.0" 2270 | } 2271 | } 2272 | } 2273 | }, 2274 | "test-exclude": { 2275 | "version": "5.2.3", 2276 | "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz", 2277 | "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==", 2278 | "dev": true, 2279 | "requires": { 2280 | "glob": "^7.1.3", 2281 | "minimatch": "^3.0.4", 2282 | "read-pkg-up": "^4.0.0", 2283 | "require-main-filename": "^2.0.0" 2284 | }, 2285 | "dependencies": { 2286 | "glob": { 2287 | "version": "7.1.6", 2288 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", 2289 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", 2290 | "dev": true, 2291 | "requires": { 2292 | "fs.realpath": "^1.0.0", 2293 | "inflight": "^1.0.4", 2294 | "inherits": "2", 2295 | "minimatch": "^3.0.4", 2296 | "once": "^1.3.0", 2297 | "path-is-absolute": "^1.0.0" 2298 | } 2299 | } 2300 | } 2301 | }, 2302 | "text-table": { 2303 | "version": "0.2.0", 2304 | "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", 2305 | "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", 2306 | "dev": true 2307 | }, 2308 | "through": { 2309 | "version": "2.3.8", 2310 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", 2311 | "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", 2312 | "dev": true 2313 | }, 2314 | "tmp": { 2315 | "version": "0.0.33", 2316 | "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", 2317 | "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", 2318 | "dev": true, 2319 | "requires": { 2320 | "os-tmpdir": "~1.0.2" 2321 | } 2322 | }, 2323 | "to-fast-properties": { 2324 | "version": "2.0.0", 2325 | "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", 2326 | "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", 2327 | "dev": true 2328 | }, 2329 | "tough-cookie": { 2330 | "version": "2.4.3", 2331 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", 2332 | "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", 2333 | "dev": true, 2334 | "requires": { 2335 | "psl": "^1.1.24", 2336 | "punycode": "^1.4.1" 2337 | }, 2338 | "dependencies": { 2339 | "punycode": { 2340 | "version": "1.4.1", 2341 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", 2342 | "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", 2343 | "dev": true 2344 | } 2345 | } 2346 | }, 2347 | "tslib": { 2348 | "version": "1.10.0", 2349 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", 2350 | "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", 2351 | "dev": true 2352 | }, 2353 | "tunnel-agent": { 2354 | "version": "0.6.0", 2355 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", 2356 | "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", 2357 | "dev": true, 2358 | "requires": { 2359 | "safe-buffer": "^5.0.1" 2360 | } 2361 | }, 2362 | "tweetnacl": { 2363 | "version": "0.14.5", 2364 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", 2365 | "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", 2366 | "dev": true 2367 | }, 2368 | "type-check": { 2369 | "version": "0.3.2", 2370 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", 2371 | "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", 2372 | "dev": true, 2373 | "requires": { 2374 | "prelude-ls": "~1.1.2" 2375 | } 2376 | }, 2377 | "type-fest": { 2378 | "version": "0.8.1", 2379 | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", 2380 | "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", 2381 | "dev": true 2382 | }, 2383 | "uglify-js": { 2384 | "version": "3.7.0", 2385 | "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.7.0.tgz", 2386 | "integrity": "sha512-PC/ee458NEMITe1OufAjal65i6lB58R1HWMRcxwvdz1UopW0DYqlRL3xdu3IcTvTXsB02CRHykidkTRL+A3hQA==", 2387 | "dev": true, 2388 | "optional": true, 2389 | "requires": { 2390 | "commander": "~2.20.3", 2391 | "source-map": "~0.6.1" 2392 | }, 2393 | "dependencies": { 2394 | "commander": { 2395 | "version": "2.20.3", 2396 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", 2397 | "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", 2398 | "dev": true, 2399 | "optional": true 2400 | }, 2401 | "source-map": { 2402 | "version": "0.6.1", 2403 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 2404 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 2405 | "dev": true, 2406 | "optional": true 2407 | } 2408 | } 2409 | }, 2410 | "uri-js": { 2411 | "version": "4.2.2", 2412 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", 2413 | "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", 2414 | "dev": true, 2415 | "requires": { 2416 | "punycode": "^2.1.0" 2417 | } 2418 | }, 2419 | "uuid": { 2420 | "version": "3.3.3", 2421 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", 2422 | "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==", 2423 | "dev": true 2424 | }, 2425 | "v8-compile-cache": { 2426 | "version": "2.1.0", 2427 | "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", 2428 | "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", 2429 | "dev": true 2430 | }, 2431 | "validate-npm-package-license": { 2432 | "version": "3.0.4", 2433 | "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", 2434 | "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", 2435 | "dev": true, 2436 | "requires": { 2437 | "spdx-correct": "^3.0.0", 2438 | "spdx-expression-parse": "^3.0.0" 2439 | } 2440 | }, 2441 | "verror": { 2442 | "version": "1.10.0", 2443 | "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", 2444 | "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", 2445 | "dev": true, 2446 | "requires": { 2447 | "assert-plus": "^1.0.0", 2448 | "core-util-is": "1.0.2", 2449 | "extsprintf": "^1.2.0" 2450 | } 2451 | }, 2452 | "which": { 2453 | "version": "1.3.1", 2454 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", 2455 | "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", 2456 | "dev": true, 2457 | "requires": { 2458 | "isexe": "^2.0.0" 2459 | } 2460 | }, 2461 | "which-module": { 2462 | "version": "2.0.0", 2463 | "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", 2464 | "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", 2465 | "dev": true 2466 | }, 2467 | "word-wrap": { 2468 | "version": "1.2.3", 2469 | "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", 2470 | "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", 2471 | "dev": true 2472 | }, 2473 | "wordwrap": { 2474 | "version": "0.0.3", 2475 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", 2476 | "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", 2477 | "dev": true 2478 | }, 2479 | "wrap-ansi": { 2480 | "version": "5.1.0", 2481 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", 2482 | "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", 2483 | "dev": true, 2484 | "requires": { 2485 | "ansi-styles": "^3.2.0", 2486 | "string-width": "^3.0.0", 2487 | "strip-ansi": "^5.0.0" 2488 | }, 2489 | "dependencies": { 2490 | "emoji-regex": { 2491 | "version": "7.0.3", 2492 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", 2493 | "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", 2494 | "dev": true 2495 | }, 2496 | "is-fullwidth-code-point": { 2497 | "version": "2.0.0", 2498 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 2499 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", 2500 | "dev": true 2501 | }, 2502 | "string-width": { 2503 | "version": "3.1.0", 2504 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", 2505 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", 2506 | "dev": true, 2507 | "requires": { 2508 | "emoji-regex": "^7.0.1", 2509 | "is-fullwidth-code-point": "^2.0.0", 2510 | "strip-ansi": "^5.1.0" 2511 | } 2512 | } 2513 | } 2514 | }, 2515 | "wrappy": { 2516 | "version": "1.0.2", 2517 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 2518 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 2519 | "dev": true 2520 | }, 2521 | "write": { 2522 | "version": "1.0.3", 2523 | "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", 2524 | "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", 2525 | "dev": true, 2526 | "requires": { 2527 | "mkdirp": "^0.5.1" 2528 | } 2529 | }, 2530 | "write-file-atomic": { 2531 | "version": "2.4.3", 2532 | "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", 2533 | "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", 2534 | "dev": true, 2535 | "requires": { 2536 | "graceful-fs": "^4.1.11", 2537 | "imurmurhash": "^0.1.4", 2538 | "signal-exit": "^3.0.2" 2539 | } 2540 | }, 2541 | "xml2js": { 2542 | "version": "0.4.19", 2543 | "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", 2544 | "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", 2545 | "dev": true, 2546 | "requires": { 2547 | "sax": ">=0.6.0", 2548 | "xmlbuilder": "~9.0.1" 2549 | } 2550 | }, 2551 | "xmlbuilder": { 2552 | "version": "9.0.7", 2553 | "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", 2554 | "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", 2555 | "dev": true 2556 | }, 2557 | "y18n": { 2558 | "version": "4.0.0", 2559 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", 2560 | "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", 2561 | "dev": true 2562 | }, 2563 | "yallist": { 2564 | "version": "2.1.2", 2565 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", 2566 | "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", 2567 | "dev": true 2568 | }, 2569 | "yargs": { 2570 | "version": "13.3.0", 2571 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz", 2572 | "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==", 2573 | "dev": true, 2574 | "requires": { 2575 | "cliui": "^5.0.0", 2576 | "find-up": "^3.0.0", 2577 | "get-caller-file": "^2.0.1", 2578 | "require-directory": "^2.1.1", 2579 | "require-main-filename": "^2.0.0", 2580 | "set-blocking": "^2.0.0", 2581 | "string-width": "^3.0.0", 2582 | "which-module": "^2.0.0", 2583 | "y18n": "^4.0.0", 2584 | "yargs-parser": "^13.1.1" 2585 | }, 2586 | "dependencies": { 2587 | "emoji-regex": { 2588 | "version": "7.0.3", 2589 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", 2590 | "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", 2591 | "dev": true 2592 | }, 2593 | "is-fullwidth-code-point": { 2594 | "version": "2.0.0", 2595 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 2596 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", 2597 | "dev": true 2598 | }, 2599 | "string-width": { 2600 | "version": "3.1.0", 2601 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", 2602 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", 2603 | "dev": true, 2604 | "requires": { 2605 | "emoji-regex": "^7.0.1", 2606 | "is-fullwidth-code-point": "^2.0.0", 2607 | "strip-ansi": "^5.1.0" 2608 | } 2609 | } 2610 | } 2611 | }, 2612 | "yargs-parser": { 2613 | "version": "13.1.1", 2614 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", 2615 | "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", 2616 | "dev": true, 2617 | "requires": { 2618 | "camelcase": "^5.0.0", 2619 | "decamelize": "^1.2.0" 2620 | } 2621 | } 2622 | } 2623 | } 2624 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nesthydrationjs", 3 | "version": "2.0.0", 4 | "description": "Provides nested objects from tabular data.", 5 | "keywords": [ 6 | "Hydration", 7 | "Tabular Data", 8 | "Arrays", 9 | "Table", 10 | "Object", 11 | "Nested" 12 | ], 13 | "license": "ISC", 14 | "main": "NestHydrationJS.js", 15 | "scripts": { 16 | "coverage": "nyc jasmine", 17 | "coveralls": "nyc report --reporter=text-lcov | coveralls", 18 | "test": "jasmine", 19 | "lint": "eslint ." 20 | }, 21 | "repository": { 22 | "type": "git", 23 | "url": "git@github.com:CoursePark/NestHydrationJS.git" 24 | }, 25 | "dependencies": { 26 | "lodash.isarray": "^4.0.0", 27 | "lodash.isfunction": "^3.0.9", 28 | "lodash.keys": "^4.2.0", 29 | "lodash.values": "^4.3.0", 30 | "lodash.isplainobject": "^4.0.6" 31 | }, 32 | "devDependencies": { 33 | "coveralls": "^3.0.8", 34 | "eslint": "^6.7.1", 35 | "jasmine": "^3.1.0", 36 | "nyc": "^14.1.1" 37 | }, 38 | "author": "Bluedrop Peformance Learning" 39 | } 40 | -------------------------------------------------------------------------------- /spec/.eslintrc: -------------------------------------------------------------------------------- 1 | --- 2 | env: 3 | jasmine: true 4 | -------------------------------------------------------------------------------- /spec/NestHydrationJS/buildMeta.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var NestHydrationJS = require('../../NestHydrationJS')(); 4 | 5 | describe('NestHydrationJS', function () { 6 | describe('buildMeta method', function () { 7 | describe('simple mapping', function () { 8 | var result; 9 | beforeEach(function () { 10 | var mapping = { 11 | a: 'aColumnName' 12 | }; 13 | result = NestHydrationJS.buildMeta(mapping); 14 | }); 15 | 16 | it('should match expected structure', function () { 17 | var expected = { 18 | primeIdColumnList: ['aColumnName'], 19 | idMap: { 20 | aColumnName: { 21 | valueList: [ 22 | {prop: 'a', column: 'aColumnName', type: undefined, default: undefined} 23 | ], 24 | toOneList: [], 25 | toManyPropList: [], 26 | containingColumn: null, 27 | ownProp: null, 28 | isOneOfMany: false, 29 | cache: {}, 30 | containingIdUsage: null, 31 | default: null 32 | } 33 | } 34 | }; 35 | expect(result).toEqual(expected); 36 | }); 37 | }); 38 | 39 | describe('simple mapping with number type', function () { 40 | var result; 41 | beforeEach(function () { 42 | var mapping = { 43 | a: {column: 'a', type: 'NUMBER'} 44 | }; 45 | result = NestHydrationJS.buildMeta(mapping); 46 | }); 47 | 48 | it('should match expected structure', function () { 49 | var expected = { 50 | primeIdColumnList: ['a'], 51 | idMap: { 52 | a: { 53 | valueList: [ 54 | {prop: 'a', column: 'a', type: 'NUMBER', default: undefined} 55 | ], 56 | toOneList: [], 57 | toManyPropList: [], 58 | containingColumn: null, 59 | ownProp: null, 60 | isOneOfMany: false, 61 | cache: {}, 62 | containingIdUsage: null, 63 | default: null 64 | } 65 | } 66 | }; 67 | expect(result).toEqual(expected); 68 | }); 69 | }); 70 | 71 | describe('simple mapping with boolean type', function () { 72 | var result; 73 | beforeEach(function () { 74 | var mapping = { 75 | a: {column: 'a', type: 'BOOLEAN'} 76 | }; 77 | result = NestHydrationJS.buildMeta(mapping); 78 | }); 79 | 80 | it('should match expected structure', function () { 81 | var expected = { 82 | primeIdColumnList: ['a'], 83 | idMap: { 84 | a: { 85 | valueList: [ 86 | {prop: 'a', column: 'a', type: 'BOOLEAN', default: undefined} 87 | ], 88 | toOneList: [], 89 | toManyPropList: [], 90 | containingColumn: null, 91 | ownProp: null, 92 | isOneOfMany: false, 93 | cache: {}, 94 | containingIdUsage: null, 95 | default: null 96 | } 97 | } 98 | }; 99 | expect(result).toEqual(expected); 100 | }); 101 | }); 102 | 103 | describe('simple mapping with id default value', function () { 104 | var result; 105 | beforeEach(function () { 106 | var mapping = { 107 | a: {column: 'a', type: 'BOOLEAN', default: 'a_default'} 108 | }; 109 | result = NestHydrationJS.buildMeta(mapping); 110 | }); 111 | 112 | it('should match expected structure', function () { 113 | var expected = { 114 | primeIdColumnList: ['a'], 115 | idMap: { 116 | a: { 117 | valueList: [ 118 | {prop: 'a', column: 'a', type: 'BOOLEAN', default: 'a_default'} 119 | ], 120 | toOneList: [], 121 | toManyPropList: [], 122 | containingColumn: null, 123 | ownProp: null, 124 | isOneOfMany: false, 125 | cache: {}, 126 | containingIdUsage: null, 127 | default: 'a_default' 128 | } 129 | } 130 | }; 131 | expect(result).toEqual(expected); 132 | }); 133 | }); 134 | 135 | describe('multiple mapping', function () { 136 | var result; 137 | beforeEach(function () { 138 | var mapping = { 139 | a: 'a', 140 | b: 'b' 141 | }; 142 | result = NestHydrationJS.buildMeta(mapping); 143 | }); 144 | 145 | it('should match expected structure', function () { 146 | var expected = { 147 | primeIdColumnList: ['a'], 148 | idMap: { 149 | a: { 150 | valueList: [ 151 | {prop: 'a', column: 'a', type: undefined, default: undefined}, 152 | {prop: 'b', column: 'b', type: undefined, default: undefined} 153 | ], 154 | toOneList: [], 155 | toManyPropList: [], 156 | containingColumn: null, 157 | ownProp: null, 158 | isOneOfMany: false, 159 | cache: {}, 160 | containingIdUsage: null, 161 | default: null 162 | } 163 | } 164 | }; 165 | expect(result).toEqual(expected); 166 | }); 167 | }); 168 | 169 | describe('multiple mapping having id with default', function () { 170 | var result; 171 | beforeEach(function () { 172 | var mapping = { 173 | a: {column: 'a', default: 'a_default'}, 174 | b: 'b' 175 | }; 176 | result = NestHydrationJS.buildMeta(mapping); 177 | }); 178 | 179 | it('should match expected structure', function () { 180 | var expected = { 181 | primeIdColumnList: ['a'], 182 | idMap: { 183 | a: { 184 | valueList: [ 185 | {prop: 'a', column: 'a', type: undefined, default: 'a_default'}, 186 | {prop: 'b', column: 'b', type: undefined, default: undefined} 187 | ], 188 | toOneList: [], 189 | toManyPropList: [], 190 | containingColumn: null, 191 | ownProp: null, 192 | isOneOfMany: false, 193 | cache: {}, 194 | containingIdUsage: null, 195 | default: 'a_default' 196 | } 197 | } 198 | }; 199 | expect(result).toEqual(expected); 200 | }); 201 | }); 202 | 203 | describe('multiple mapping complex having default', function () { 204 | var result; 205 | beforeEach(function () { 206 | var mapping = { 207 | id: 'id', 208 | a: { 209 | c: {column: 'c', default: 'c_default'} 210 | }, 211 | b: 'b' 212 | }; 213 | result = NestHydrationJS.buildMeta(mapping); 214 | }); 215 | 216 | it('should match expected structure', function () { 217 | var expected = { 218 | primeIdColumnList: ['id'], 219 | idMap: { 220 | c: { 221 | valueList: [ 222 | {prop: 'c', column: 'c', type: undefined, default: 'c_default'} 223 | ], 224 | toOneList: [], 225 | toManyPropList: [], 226 | containingColumn: 'id', 227 | ownProp: 'a', 228 | isOneOfMany: false, 229 | cache: {}, 230 | containingIdUsage: {}, 231 | default: 'c_default' 232 | }, 233 | id: { 234 | valueList: [ 235 | {prop: 'id', column: 'id', type: undefined, default: undefined}, 236 | {prop: 'b', column: 'b', type: undefined, default: undefined} 237 | ], 238 | toOneList: [{prop: 'a', column: 'c'}], 239 | toManyPropList: [], 240 | containingColumn: null, 241 | ownProp: null, 242 | isOneOfMany: false, 243 | cache: {}, 244 | containingIdUsage: null, 245 | default: null 246 | } 247 | } 248 | }; 249 | expect(result).toEqual(expected); 250 | }); 251 | }); 252 | 253 | describe('multiple mapping array', function () { 254 | var result; 255 | beforeEach(function () { 256 | var mapping = [{ 257 | a: '_a', 258 | b: '_b' 259 | }]; 260 | result = NestHydrationJS.buildMeta(mapping); 261 | }); 262 | 263 | it('should match expected structure', function () { 264 | var expected = { 265 | primeIdColumnList: ['_a'], 266 | idMap: { 267 | _a: { 268 | valueList: [ 269 | {prop: 'a', column: '_a', type: undefined, default: undefined}, 270 | {prop: 'b', column: '_b', type: undefined, default: undefined} 271 | ], 272 | toOneList: [], 273 | toManyPropList: [], 274 | containingColumn: null, 275 | ownProp: null, 276 | isOneOfMany: true, 277 | cache: {}, 278 | containingIdUsage: null, 279 | default: null 280 | } 281 | } 282 | }; 283 | expect(result).toEqual(expected); 284 | }); 285 | }); 286 | 287 | describe('multiple mapping array, id being non first', function () { 288 | var result; 289 | beforeEach(function () { 290 | var mapping = [{ 291 | a: '_a', 292 | b: {column: '_b', id: true} 293 | }]; 294 | result = NestHydrationJS.buildMeta(mapping); 295 | }); 296 | 297 | it('should match expected structure', function () { 298 | var expected = { 299 | primeIdColumnList: ['_b'], 300 | idMap: { 301 | _b: { 302 | valueList: [ 303 | {prop: 'a', column: '_a', type: undefined, default: undefined}, 304 | {prop: 'b', column: '_b', type: undefined, default: undefined} 305 | ], 306 | toOneList: [], 307 | toManyPropList: [], 308 | containingColumn: null, 309 | ownProp: null, 310 | isOneOfMany: true, 311 | cache: {}, 312 | containingIdUsage: null, 313 | default: null 314 | } 315 | } 316 | }; 317 | expect(result).toEqual(expected); 318 | }); 319 | }); 320 | 321 | describe('multiple mapping array with id having type', function () { 322 | var result; 323 | beforeEach(function () { 324 | var mapping = [{ 325 | a: {column: '_a', type: 'NUMBER'}, 326 | b: '_b' 327 | }]; 328 | result = NestHydrationJS.buildMeta(mapping); 329 | }); 330 | 331 | it('should match expected structure', function () { 332 | var expected = { 333 | primeIdColumnList: ['_a'], 334 | idMap: { 335 | _a: { 336 | valueList: [ 337 | {prop: 'a', column: '_a', type: 'NUMBER', default: undefined}, 338 | {prop: 'b', column: '_b', type: undefined, default: undefined} 339 | ], 340 | toOneList: [], 341 | toManyPropList: [], 342 | containingColumn: null, 343 | ownProp: null, 344 | isOneOfMany: true, 345 | cache: {}, 346 | containingIdUsage: null, 347 | default: null 348 | } 349 | } 350 | }; 351 | expect(result).toEqual(expected); 352 | }); 353 | }); 354 | 355 | describe('multiple mapping array with id having default', function () { 356 | var result; 357 | beforeEach(function () { 358 | var mapping = [{ 359 | a: {column: '_a', default: 'a_default'}, 360 | b: '_b' 361 | }]; 362 | result = NestHydrationJS.buildMeta(mapping); 363 | }); 364 | 365 | it('should match expected structure', function () { 366 | var expected = { 367 | primeIdColumnList: ['_a'], 368 | idMap: { 369 | _a: { 370 | valueList: [ 371 | {prop: 'a', column: '_a', type: undefined, default: 'a_default'}, 372 | {prop: 'b', column: '_b', type: undefined, default: undefined} 373 | ], 374 | toOneList: [], 375 | toManyPropList: [], 376 | containingColumn: null, 377 | ownProp: null, 378 | isOneOfMany: true, 379 | cache: {}, 380 | containingIdUsage: null, 381 | default: 'a_default' 382 | } 383 | } 384 | }; 385 | expect(result).toEqual(expected); 386 | }); 387 | }); 388 | 389 | describe('multiple mapping complex', function () { 390 | var result; 391 | beforeEach(function () { 392 | var mapping = [{ 393 | a: '_a', 394 | b: '_b', 395 | c: { 396 | d: '_c_d' 397 | }, 398 | e: [{ 399 | f: '_e__f', 400 | g: '_e__g' 401 | }] 402 | }]; 403 | result = NestHydrationJS.buildMeta(mapping); 404 | }); 405 | 406 | it('should match expected structure', function () { 407 | var expected = { 408 | primeIdColumnList: ['_a', '_e__f'], 409 | idMap: { 410 | '_a': { 411 | valueList: [ 412 | {prop: 'a', column: '_a', type: undefined, default: undefined}, 413 | {prop: 'b', column: '_b', type: undefined, default: undefined} 414 | ], 415 | toOneList: [ 416 | {prop: 'c', column: '_c_d'} 417 | ], 418 | toManyPropList: [ 419 | 'e' 420 | ], 421 | containingColumn: null, 422 | ownProp: null, 423 | isOneOfMany: true, 424 | cache: {}, 425 | containingIdUsage: null, 426 | default: null 427 | }, 428 | '_c_d': { 429 | valueList: [ 430 | {prop: 'd', column: '_c_d', type: undefined, default: undefined} 431 | ], 432 | toOneList: [], 433 | toManyPropList: [], 434 | containingColumn: '_a', 435 | ownProp: 'c', 436 | isOneOfMany: false, 437 | cache: {}, 438 | containingIdUsage: {}, 439 | default: null 440 | }, 441 | '_e__f': { 442 | valueList: [ 443 | {prop: 'f', column: '_e__f', type: undefined, default: undefined}, 444 | {prop: 'g', column: '_e__g', type: undefined, default: undefined} 445 | ], 446 | toOneList: [], 447 | toManyPropList: [], 448 | containingColumn: '_a', 449 | ownProp: 'e', 450 | isOneOfMany: true, 451 | cache: {}, 452 | containingIdUsage: {}, 453 | default: null 454 | } 455 | } 456 | }; 457 | expect(result.primeIdColumnList).toEqual(expected.primeIdColumnList); 458 | expect(result.idMap['_a']).toEqual(expected.idMap['_a']); 459 | expect(result.idMap['_c_d']).toEqual(expected.idMap['_c_d']); 460 | expect(result.idMap['_e__f']).toEqual(expected.idMap['_e__f']); 461 | // expect(result).toEqual(expected); 462 | }); 463 | }); 464 | 465 | describe('malformed mapping, empty array in place as property', function () { 466 | var error; 467 | beforeEach(function () { 468 | var mapping = { 469 | a: [] 470 | }; 471 | 472 | try { 473 | NestHydrationJS.buildMeta(mapping); 474 | } catch (err) { 475 | error = err; 476 | } 477 | }); 478 | 479 | it('should match expected error', function () { 480 | expect(error.message).toEqual('invalid structPropToColumnMap format - property \'a\' can not be an empty array'); 481 | }); 482 | }); 483 | 484 | describe('malformed mapping, base array should not have a multiple items as there can only be one root to the datastructure', function () { 485 | var error; 486 | beforeEach(function () { 487 | // bad formatting, doesn't even make sense really 488 | var mapping = [ 489 | {a: 'rootA_'}, 490 | {b: 'rootB_'} 491 | ]; 492 | 493 | try { 494 | NestHydrationJS.buildMeta(mapping); 495 | } catch (err) { 496 | error = err; 497 | } 498 | }); 499 | 500 | it('should match expected error', function () { 501 | expect(error.message).toEqual('invalid structPropToColumnMap format - can not have multiple roots for structPropToColumnMap, if an array it must only have one item'); 502 | }); 503 | }); 504 | 505 | describe('malformed mapping, number as property', function () { 506 | var error; 507 | beforeEach(function () { 508 | var mapping = { 509 | a: 5 510 | }; 511 | 512 | try { 513 | NestHydrationJS.buildMeta(mapping); 514 | } catch (err) { 515 | error = err; 516 | } 517 | }); 518 | 519 | it('should match expected error', function () { 520 | expect(error.message).toEqual('invalid structPropToColumnMap format - property \'a\' must be either a string, a plain object or an array'); 521 | }); 522 | }); 523 | 524 | describe('malformed mapping, non plain object as property', function () { 525 | var error; 526 | beforeEach(function () { 527 | var mapping = { 528 | a: new Error() 529 | }; 530 | 531 | try { 532 | NestHydrationJS.buildMeta(mapping); 533 | } catch (err) { 534 | error = err; 535 | } 536 | }); 537 | 538 | it('should match expected error', function () { 539 | expect(error.message).toEqual('invalid structPropToColumnMap format - property \'a\' must be either a string, a plain object or an array'); 540 | }); 541 | }); 542 | 543 | describe('malformed mapping, empty object as property', function () { 544 | var error; 545 | beforeEach(function () { 546 | var mapping = { 547 | a: {} 548 | }; 549 | 550 | try { 551 | NestHydrationJS.buildMeta(mapping); 552 | } catch (err) { 553 | error = err; 554 | } 555 | }); 556 | 557 | it('should match expected error', function () { 558 | expect(error.message).toEqual('invalid structPropToColumnMap format - property \'a\' can not be an empty object'); 559 | }); 560 | }); 561 | 562 | describe('malformed mapping, empty object as property', function () { 563 | var error; 564 | beforeEach(function () { 565 | var mapping = {}; 566 | 567 | try { 568 | NestHydrationJS.buildMeta(mapping); 569 | } catch (err) { 570 | error = err; 571 | } 572 | }); 573 | 574 | it('should match expected error', function () { 575 | expect(error.message).toEqual('invalid structPropToColumnMap format - the base object can not be an empty object'); 576 | }); 577 | }); 578 | }); 579 | }); 580 | -------------------------------------------------------------------------------- /spec/NestHydrationJS/nest.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var NestHydrationJS = require('../../NestHydrationJS')(); 4 | 5 | describe('NestHydrationJS', function () { 6 | describe('nest method', function () { 7 | describe('invalid structPropToColumnMap param', function () { 8 | var error; 9 | beforeEach(function () { 10 | try { 11 | NestHydrationJS.nest([], false); 12 | } catch (err) { 13 | error = err; 14 | } 15 | }); 16 | 17 | it('should match expected error', function () { 18 | expect(error.message).toEqual('nest expects param structPropToColumnMap to be an array, plain object, null, or true'); 19 | }); 20 | }); 21 | 22 | describe('invalid structPropToColumnMap param, non simple object', function () { 23 | var error; 24 | beforeEach(function () { 25 | try { 26 | NestHydrationJS.nest([], new Error()); 27 | } catch (err) { 28 | error = err; 29 | } 30 | }); 31 | 32 | it('should match expected error', function () { 33 | expect(error.message).toEqual('nest expects param structPropToColumnMap to be an array, plain object, null, or true'); 34 | }); 35 | }); 36 | 37 | describe('invalid data param, string', function () { 38 | var error; 39 | beforeEach(function () { 40 | var mapping = { 41 | a: 'a' 42 | }; 43 | try { 44 | NestHydrationJS.nest('not valid', mapping); 45 | } catch (err) { 46 | error = err; 47 | } 48 | }); 49 | 50 | it('should match expected error', function () { 51 | expect(error.message).toEqual('nest expects param data to be in the form of a plain object or an array of plain objects (forming a table)'); 52 | }); 53 | }); 54 | 55 | describe('invalid data param, number', function () { 56 | var error; 57 | beforeEach(function () { 58 | var mapping = { 59 | a: 'a' 60 | }; 61 | try { 62 | NestHydrationJS.nest(5, mapping); 63 | } catch (err) { 64 | error = err; 65 | } 66 | }); 67 | 68 | it('should match expected error', function () { 69 | expect(error.message).toEqual('nest expects param data to be in the form of a plain object or an array of plain objects (forming a table)'); 70 | }); 71 | }); 72 | 73 | describe('null data', function () { 74 | var result; 75 | beforeEach(function () { 76 | var mapping = { 77 | a: 'a' 78 | }; 79 | var data = null; 80 | result = NestHydrationJS.nest(data, mapping); 81 | }); 82 | 83 | it('should match expected structure', function () { 84 | var expected = null; 85 | expect(result).toEqual(expected); 86 | }); 87 | }); 88 | 89 | describe('empty data', function () { 90 | var result; 91 | beforeEach(function () { 92 | var mapping = [{ 93 | a: 'a' 94 | }]; 95 | var data = []; 96 | result = NestHydrationJS.nest(data, mapping); 97 | }); 98 | 99 | it('should match expected structure', function () { 100 | var expected = []; 101 | expect(result).toEqual(expected); 102 | }); 103 | }); 104 | 105 | describe('simple mapping', function () { 106 | var result; 107 | beforeEach(function () { 108 | var mapping = { 109 | a: 'a' 110 | }; 111 | var data = {a: 'value 1'}; 112 | result = NestHydrationJS.nest(data, mapping); 113 | }); 114 | 115 | it('should match expected structure', function () { 116 | var expected = {a: 'value 1'}; 117 | expect(result).toEqual(expected); 118 | }); 119 | }); 120 | 121 | describe('simple mapping, number type', function () { 122 | var result; 123 | beforeEach(function () { 124 | var mapping = { 125 | a: {column: 'a', type: 'NUMBER'} 126 | }; 127 | var data = {a: '1'}; 128 | result = NestHydrationJS.nest(data, mapping); 129 | }); 130 | 131 | it('should match expected structure', function () { 132 | var expected = {a: 1}; 133 | expect(result).toEqual(expected); 134 | }); 135 | }); 136 | 137 | describe('simple mapping, number type, float', function () { 138 | var result; 139 | beforeEach(function () { 140 | var mapping = { 141 | a: {column: 'a', type: 'NUMBER'} 142 | }; 143 | var data = {a: '1.1'}; 144 | result = NestHydrationJS.nest(data, mapping); 145 | }); 146 | 147 | it('should match expected structure', function () { 148 | var expected = {a: 1.1}; 149 | expect(result).toEqual(expected); 150 | }); 151 | }); 152 | 153 | describe('simple mapping, boolean type', function () { 154 | var result; 155 | beforeEach(function () { 156 | var mapping = { 157 | a: {column: 'a', type: 'BOOLEAN'} 158 | }; 159 | var data = {a: '1'}; 160 | result = NestHydrationJS.nest(data, mapping); 161 | }); 162 | 163 | it('should match expected structure', function () { 164 | var expected = {a: true}; 165 | expect(result).toEqual(expected); 166 | }); 167 | }); 168 | 169 | describe('simple mapping, boolean type, false', function () { 170 | var result; 171 | beforeEach(function () { 172 | var mapping = { 173 | a: {column: 'a', type: 'BOOLEAN'} 174 | }; 175 | var data = {a: '0'}; 176 | result = NestHydrationJS.nest(data, mapping); 177 | }); 178 | 179 | it('should match expected structure', function () { 180 | var expected = {a: false}; 181 | expect(result).toEqual(expected); 182 | }); 183 | }); 184 | 185 | describe('simple mapping, custom type', function () { 186 | var result; 187 | beforeAll(function() { 188 | NestHydrationJS.registerType('CUSTOM_TYPE', function(value) { 189 | return '::' + value + '::'; 190 | }); 191 | }); 192 | beforeEach(function () { 193 | var mapping = { 194 | a: {column: 'a', type: 'CUSTOM_TYPE'} 195 | }; 196 | var data = {a: 'value'}; 197 | result = NestHydrationJS.nest(data, mapping); 198 | }); 199 | afterAll(function() { 200 | delete NestHydrationJS.typeHandlers.CUSTOM_TYPE; 201 | }); 202 | 203 | it('should match expected structure', function () { 204 | var expected = {a: '::value::'}; 205 | expect(result).toEqual(expected); 206 | }); 207 | }); 208 | 209 | describe('simple mapping, with default', function () { 210 | var result; 211 | beforeEach(function () { 212 | var mapping = { 213 | a: {column: 'a', default: 'a_default'} 214 | }; 215 | var data = {a: null}; 216 | result = NestHydrationJS.nest(data, mapping); 217 | }); 218 | 219 | it('should match expected structure', function () { 220 | var expected = {a: 'a_default'}; 221 | expect(result).toEqual(expected); 222 | }); 223 | }); 224 | 225 | describe('simple mapping, function type', function () { 226 | var result; 227 | beforeEach(function () { 228 | var mapping = { 229 | a: {column: 'a', type: function(value) { 230 | return '::' + value + '::'; 231 | }} 232 | }; 233 | var data = {a: 'value'}; 234 | result = NestHydrationJS.nest(data, mapping); 235 | }); 236 | 237 | it('should match expected structure', function () { 238 | var expected = {a: '::value::'}; 239 | expect(result).toEqual(expected); 240 | }); 241 | }); 242 | 243 | describe('simple mapping, redundant data', function () { 244 | var result; 245 | beforeEach(function () { 246 | var mapping = { 247 | a: 'a' 248 | }; 249 | var data = {a: 'value 1', b: 'value 2'}; 250 | result = NestHydrationJS.nest(data, mapping); 251 | }); 252 | 253 | it('should match expected structure', function () { 254 | var expected = {a: 'value 1'}; 255 | expect(result).toEqual(expected); 256 | }); 257 | }); 258 | 259 | describe('multiple mapping', function () { 260 | var result; 261 | beforeEach(function () { 262 | var mapping = { 263 | a: 'a', 264 | b: 'b' 265 | }; 266 | var data = {a: 'value 1', b: 'value 2'}; 267 | result = NestHydrationJS.nest(data, mapping); 268 | }); 269 | 270 | it('should match expected structure', function () { 271 | var expected = {a: 'value 1', b: 'value 2'}; 272 | expect(result).toEqual(expected); 273 | }); 274 | }); 275 | 276 | describe('multiple mapping, with default', function () { 277 | var result; 278 | beforeEach(function () { 279 | var mapping = { 280 | a: {column: 'a', type: 'NUMBER', default: 'a_default'}, 281 | b: {column: 'b', type: 'NUMBER', default: 'b_default'} 282 | }; 283 | var data = {a: null, b: null}; 284 | result = NestHydrationJS.nest(data, mapping); 285 | }); 286 | 287 | it('should match expected structure', function () { 288 | var expected = {a: 'a_default', b: 'b_default'}; 289 | expect(result).toEqual(expected); 290 | }); 291 | }); 292 | describe('multiple mapping, number type, null', function () { 293 | var result; 294 | beforeEach(function () { 295 | var mapping = { 296 | a: {column: 'a', type: 'NUMBER'}, 297 | b: {column: 'b', type: 'NUMBER'} 298 | }; 299 | var data = {a: 1, b: null}; 300 | result = NestHydrationJS.nest(data, mapping); 301 | }); 302 | 303 | it('should match expected structure', function () { 304 | var expected = {a: 1, b: null}; 305 | expect(result).toEqual(expected); 306 | }); 307 | }); 308 | 309 | describe('multiple mapping array', function () { 310 | var result; 311 | beforeEach(function () { 312 | var mapping = [{ 313 | a: 'a', 314 | b: 'b' 315 | }]; 316 | var data = [ 317 | {a: 'value 1', b: 'value 2'}, 318 | {a: 'value 3', b: 'value 4'}, 319 | {a: 'value 5', b: 'value 6'} 320 | ]; 321 | result = NestHydrationJS.nest(data, mapping); 322 | }); 323 | 324 | it('should match expected structure', function () { 325 | var expected = [ 326 | {a: 'value 1', b: 'value 2'}, 327 | {a: 'value 3', b: 'value 4'}, 328 | {a: 'value 5', b: 'value 6'} 329 | ]; 330 | expect(result).toEqual(expected); 331 | }); 332 | }); 333 | 334 | describe('multiple mapping array with id column', function () { 335 | var result; 336 | beforeEach(function () { 337 | var mapping = [{ 338 | a: {column: 'a', id: true}, 339 | b: 'b' 340 | }]; 341 | var data = [ 342 | {a: 'value a1', b: 'value b1'}, 343 | {a: 'value a1', b: 'value b2'}, 344 | {a: 'value a2', b: 'value b1'}, 345 | {a: 'value a2', b: 'value b2'} 346 | ]; 347 | result = NestHydrationJS.nest(data, mapping); 348 | }); 349 | 350 | it('should match expected structure', function () { 351 | var expected = [ 352 | {a: 'value a1', b: 'value b1'}, 353 | {a: 'value a2', b: 'value b1'} 354 | ]; 355 | expect(result).toEqual(expected); 356 | }); 357 | }); 358 | 359 | describe('multiple mapping array with id column not being the first', function () { 360 | var result; 361 | beforeEach(function () { 362 | var mapping = [{ 363 | a: 'a', 364 | b: {column: 'b', id: true} 365 | }]; 366 | var data = [ 367 | {a: 'value a1', b: 'value b1'}, 368 | {a: 'value a1', b: 'value b2'}, 369 | {a: 'value a2', b: 'value b1'}, 370 | {a: 'value a2', b: 'value b2'} 371 | ]; 372 | result = NestHydrationJS.nest(data, mapping); 373 | }); 374 | 375 | it('should match expected structure', function () { 376 | var expected = [ 377 | {a: 'value a1', b: 'value b1'}, 378 | {a: 'value a1', b: 'value b2'} 379 | ]; 380 | expect(result).toEqual(expected); 381 | }); 382 | }); 383 | 384 | describe('multiple mapping array, hinted mapping', function () { 385 | var result; 386 | beforeEach(function () { 387 | var data = [ 388 | {_a: 'value 1', _b: 'value 2'}, 389 | {_a: 'value 3', _b: 'value 4'}, 390 | {_a: 'value 5', _b: 'value 6'} 391 | ]; 392 | result = NestHydrationJS.nest(data); 393 | }); 394 | 395 | it('should match expected structure', function () { 396 | var expected = [ 397 | {a: 'value 1', b: 'value 2'}, 398 | {a: 'value 3', b: 'value 4'}, 399 | {a: 'value 5', b: 'value 6'} 400 | ]; 401 | expect(result).toEqual(expected); 402 | }); 403 | }); 404 | 405 | describe('hinted mapping, to one', function () { 406 | var result; 407 | beforeEach(function () { 408 | var data = [ 409 | {_id: '1', _a_id: 'a1'}, 410 | {_id: '2', _a_id: 'a2'}, 411 | {_id: '3', _a_id: 'a3'} 412 | ]; 413 | result = NestHydrationJS.nest(data); 414 | }); 415 | 416 | it('should match expected structure', function () { 417 | var expected = [ 418 | {id: '1', a: {id: 'a1'}}, 419 | {id: '2', a: {id: 'a2'}}, 420 | {id: '3', a: {id: 'a3'}} 421 | ]; 422 | expect(result).toEqual(expected); 423 | }); 424 | }); 425 | 426 | describe('hinted mapping, to one, non id property', function () { 427 | var result; 428 | beforeEach(function () { 429 | var data = [ 430 | {_id: '1', _a_someProp: 'same'}, 431 | {_id: '2', _a_someProp: 'different'}, 432 | {_id: '3', _a_someProp: 'more different'}, 433 | {_id: '4', _a_someProp: 'same'}, 434 | {_id: '5', _a_someProp: 'different'} 435 | ]; 436 | result = NestHydrationJS.nest(data); 437 | }); 438 | 439 | it('should match expected structure', function () { 440 | var expected = [ 441 | {id: '1', a: {someProp: 'same'}}, 442 | {id: '2', a: {someProp: 'different'}}, 443 | {id: '3', a: {someProp: 'more different'}}, 444 | {id: '4', a: {someProp: 'same'}}, 445 | {id: '5', a: {someProp: 'different'}} 446 | ]; 447 | expect(result).toEqual(expected); 448 | }); 449 | }); 450 | 451 | describe('hinted mapping, to one, number type', function () { 452 | var result; 453 | beforeEach(function () { 454 | var data = [ 455 | {_id: '1', _a_id___NUMBER: '1'}, 456 | {_id: '2', _a_id___NUMBER: '2'}, 457 | {_id: '3', _a_id___NUMBER: '3'} 458 | ]; 459 | result = NestHydrationJS.nest(data); 460 | }); 461 | 462 | it('should match expected structure', function () { 463 | var expected = [ 464 | {id: '1', a: {id: 1}}, 465 | {id: '2', a: {id: 2}}, 466 | {id: '3', a: {id: 3}} 467 | ]; 468 | expect(result).toEqual(expected); 469 | }); 470 | }); 471 | 472 | describe('hinted mapping, id type unspecified, first column should be used as id', function () { 473 | var result; 474 | beforeEach(function () { 475 | var data = [ 476 | {_a: 1, _b__c: 'c1'}, 477 | {_a: 1, _b__c: 'c2'}, 478 | {_a: 2, _b__c: 'c3'}, 479 | {_a: 2, _b__c: 'c4'} 480 | ]; 481 | result = NestHydrationJS.nest(data); 482 | }); 483 | 484 | it('should match expected structure', function () { 485 | var expected = [ 486 | {a: 1, b: [ 487 | {c: 'c1'}, 488 | {c: 'c2'} 489 | ]}, 490 | {a: 2, b: [ 491 | {c: 'c3'}, 492 | {c: 'c4'} 493 | ]} 494 | ]; 495 | expect(result).toEqual(expected); 496 | }); 497 | }); 498 | 499 | describe('hinted mapping, id type specified on first column, should be used', function () { 500 | var result; 501 | beforeEach(function () { 502 | var data = [ 503 | {_a___ID: 1, _b__c: 'c1'}, 504 | {_a___ID: 1, _b__c: 'c2'}, 505 | {_a___ID: 2, _b__c: 'c3'}, 506 | {_a___ID: 2, _b__c: 'c4'} 507 | ]; 508 | result = NestHydrationJS.nest(data); 509 | }); 510 | 511 | it('should match expected structure', function () { 512 | var expected = [ 513 | {a: 1, b: [ 514 | {c: 'c1'}, 515 | {c: 'c2'} 516 | ]}, 517 | {a: 2, b: [ 518 | {c: 'c3'}, 519 | {c: 'c4'} 520 | ]} 521 | ]; 522 | expect(result).toEqual(expected); 523 | }); 524 | }); 525 | 526 | describe('hinted mapping, id type specified on other column, should be used', function () { 527 | var result; 528 | beforeEach(function () { 529 | var data = [ 530 | {_a__c: 'c1', _b___ID: 1}, 531 | {_a__c: 'c2', _b___ID: 1}, 532 | {_a__c: 'c3', _b___ID: 2}, 533 | {_a__c: 'c4', _b___ID: 2} 534 | ]; 535 | result = NestHydrationJS.nest(data); 536 | }); 537 | 538 | it('should match expected structure', function () { 539 | var expected = [ 540 | {b: 1, a: [ 541 | {c: 'c1'}, 542 | {c: 'c2'} 543 | ]}, 544 | {b: 2, a: [ 545 | {c: 'c3'}, 546 | {c: 'c4'} 547 | ]} 548 | ]; 549 | expect(result).toEqual(expected); 550 | }); 551 | }); 552 | 553 | describe('hinted mapping, id type specified on other column, used with number type', function () { 554 | var result; 555 | beforeEach(function () { 556 | var data = [ 557 | {_a__c: 'c1', _b___NUMBER___ID: '1'}, 558 | {_a__c: 'c2', _b___NUMBER___ID: '1'}, 559 | {_a__c: 'c3', _b___NUMBER___ID: '2'}, 560 | {_a__c: 'c4', _b___NUMBER___ID: '2'} 561 | ]; 562 | result = NestHydrationJS.nest(data); 563 | }); 564 | 565 | it('should match expected structure', function () { 566 | var expected = [ 567 | {b: 1, a: [ 568 | {c: 'c1'}, 569 | {c: 'c2'} 570 | ]}, 571 | {b: 2, a: [ 572 | {c: 'c3'}, 573 | {c: 'c4'} 574 | ]} 575 | ]; 576 | expect(result).toEqual(expected); 577 | }); 578 | }); 579 | 580 | describe('hinted mapping, to one, custom type', function () { 581 | var result; 582 | beforeAll(function() { 583 | NestHydrationJS.registerType('CUSTOM_TYPE', function(value) { return value * value; }); 584 | }); 585 | beforeEach(function () { 586 | var data = [ 587 | {_id: '1', _a_id___CUSTOM_TYPE: '1'}, 588 | {_id: '2', _a_id___CUSTOM_TYPE: '2'}, 589 | {_id: '3', _a_id___CUSTOM_TYPE: '3'} 590 | ]; 591 | result = NestHydrationJS.nest(data); 592 | }); 593 | afterAll(function() { 594 | delete NestHydrationJS.typeHandlers.CUSTOM_TYPE; 595 | }); 596 | 597 | it('should match expected structure', function () { 598 | var expected = [ 599 | {id: '1', a: {id: 1}}, 600 | {id: '2', a: {id: 4}}, 601 | {id: '3', a: {id: 9}} 602 | ]; 603 | expect(result).toEqual(expected); 604 | }); 605 | }); 606 | 607 | describe('hinted mapping, to one, integer id', function () { 608 | var result; 609 | beforeEach(function () { 610 | var data = [ 611 | {_id: 1, _a_id: 1}, 612 | {_id: 2, _a_id: 2}, 613 | {_id: 3, _a_id: 3} 614 | ]; 615 | result = NestHydrationJS.nest(data); 616 | }); 617 | 618 | it('should match expected structure', function () { 619 | var expected = [ 620 | {id: 1, a: {id: 1}}, 621 | {id: 2, a: {id: 2}}, 622 | {id: 3, a: {id: 3}} 623 | ]; 624 | expect(result).toEqual(expected); 625 | }); 626 | }); 627 | 628 | describe('hinted mapping, to one, null', function () { 629 | var result; 630 | beforeEach(function () { 631 | var data = [ 632 | {_id: '1', _a_id: null} 633 | ]; 634 | result = NestHydrationJS.nest(data); 635 | }); 636 | 637 | it('should match expected structure', function () { 638 | var expected = [ 639 | {id: '1', a: null} 640 | ]; 641 | expect(result).toEqual(expected); 642 | }); 643 | }); 644 | 645 | describe('hinted mapping, to many', function () { 646 | var result; 647 | beforeEach(function () { 648 | var data = [ 649 | {_id: '1', _a__id: 'a1'}, 650 | {_id: '1', _a__id: 'a2'}, 651 | {_id: '2', _a__id: 'a3'} 652 | ]; 653 | result = NestHydrationJS.nest(data); 654 | }); 655 | 656 | it('should match expected structure', function () { 657 | var expected = [ 658 | {id: '1', a: [ 659 | {id: 'a1'}, 660 | {id: 'a2'} 661 | ]}, 662 | {id: '2', a: [ 663 | {id: 'a3'} 664 | ]} 665 | ]; 666 | expect(result).toEqual(expected); 667 | }); 668 | }); 669 | 670 | describe('hinted mapping, to many, integer id', function () { 671 | var result; 672 | beforeEach(function () { 673 | var data = [ 674 | {_id: 1, _a__id: 1}, 675 | {_id: 1, _a__id: 2}, 676 | {_id: 2, _a__id: 3} 677 | ]; 678 | result = NestHydrationJS.nest(data); 679 | }); 680 | 681 | it('should match expected structure', function () { 682 | var expected = [ 683 | {id: 1, a: [ 684 | {id: 1}, 685 | {id: 2} 686 | ]}, 687 | {id: 2, a: [ 688 | {id: 3} 689 | ]} 690 | ]; 691 | expect(result).toEqual(expected); 692 | }); 693 | }); 694 | 695 | describe('hinted mapping, to many, references previously used', function () { 696 | var result; 697 | beforeEach(function () { 698 | var data = [ 699 | {_id: '1', _a__id: 'a1'}, 700 | {_id: '1', _a__id: 'a2'}, 701 | {_id: '2', _a__id: 'a1'} 702 | ]; 703 | result = NestHydrationJS.nest(data); 704 | }); 705 | 706 | it('should match expected structure', function () { 707 | var expected = [ 708 | {id: '1', a: [ 709 | {id: 'a1'}, 710 | {id: 'a2'} 711 | ]}, 712 | {id: '2', a: [ 713 | {id: 'a1'} 714 | ]} 715 | ]; 716 | expect(result).toEqual(expected); 717 | }); 718 | }); 719 | 720 | describe('hinted mapping, to many, empty', function () { 721 | var result; 722 | beforeEach(function () { 723 | var data = [ 724 | {_id: '1', _a__id: null} 725 | ]; 726 | result = NestHydrationJS.nest(data); 727 | }); 728 | 729 | it('should match expected structure', function () { 730 | var expected = [ 731 | {id: '1', a: []} 732 | ]; 733 | expect(result).toEqual(expected); 734 | }); 735 | }); 736 | 737 | describe('hinted mapping, to many, double up', function () { 738 | var result; 739 | beforeEach(function () { 740 | var data = [ 741 | {_col1: '1a', _col2: '2a', _col3: '3a', _sub__col1: 'sub 1a', _sub__col2: 'sub 2a', _sub__col3: 'sub 3a'}, 742 | {_col1: '1a', _col2: '2a', _col3: '3a', _sub__col1: 'sub 1b', _sub__col2: 'sub 2b', _sub__col3: 'sub 3b'}, 743 | {_col1: '1b', _col2: '2b', _col3: '3b', _sub__col1: 'sub 1a', _sub__col2: 'sub 2a', _sub__col3: 'sub 3a'}, 744 | {_col1: '1b', _col2: '2b', _col3: '3b', _sub__col1: 'sub 1b', _sub__col2: 'sub 2b', _sub__col3: 'sub 3b'} 745 | ]; 746 | result = NestHydrationJS.nest(data); 747 | }); 748 | 749 | it('should match expected structure', function () { 750 | var expected = [ 751 | {col1: '1a', col2: '2a', col3: '3a', sub: [ 752 | {col1: 'sub 1a', col2: 'sub 2a', col3: 'sub 3a'}, 753 | {col1: 'sub 1b', col2: 'sub 2b', col3: 'sub 3b'} 754 | ]}, 755 | {col1: '1b', col2: '2b', col3: '3b', sub: [ 756 | {col1: 'sub 1a', col2: 'sub 2a', col3: 'sub 3a'}, 757 | {col1: 'sub 1b', col2: 'sub 2b', col3: 'sub 3b'} 758 | ]} 759 | ]; 760 | expect(result).toEqual(expected); 761 | }); 762 | }); 763 | 764 | describe('hinted mapping, to many, double up, capitalization', function () { 765 | var result; 766 | beforeEach(function () { 767 | var data = [ 768 | {_id___NUMBER: '1', _aItem__id___NUMBER: '10', _aItem__bValue: 'b10', _aItem__cItem__id___NUMBER: '100', _aItem__cItem__dItem_id___NUMBER: '1000', _aItem__cItem__dItem_eValue: 'e1000'} 769 | ]; 770 | result = NestHydrationJS.nest(data); 771 | }); 772 | 773 | it('should match expected structure', function () { 774 | var expected = [ 775 | {id: 1, aItem: [ 776 | {id: 10, bValue: 'b10', cItem: [ 777 | {id: 100, dItem: {id: 1000, eValue: 'e1000'}} 778 | ]} 779 | ]} 780 | ]; 781 | expect(result).toEqual(expected); 782 | }); 783 | }); 784 | 785 | describe('complex', function () { 786 | var result; 787 | beforeEach(function () { 788 | var data = [ 789 | {_id: '1', _a__id: null, _a__a: null, _a__b__id: null, _b_id: '1', _b_a: '1', _b_b__id: '1', _b_b__a: '1'}, 790 | {_id: '1', _a__id: null, _a__a: null, _a__b__id: null, _b_id: '1', _b_a: '1', _b_b__id: '2', _b_b__a: null}, 791 | {_id: '2', _a__id: '1', _a__a: '1', _a__b__id: null, _b_id: '1', _b_a: '1', _b_b__id: '1', _b_b__a: '1'}, 792 | {_id: '2', _a__id: '2', _a__a: '2', _a__b__id: '1', _b_id: '1', _b_a: '1', _b_b__id: '1', _b_b__a: '1'}, 793 | {_id: '2', _a__id: '2', _a__a: '2', _a__b__id: '2', _b_id: '1', _b_a: '1', _b_b__id: '1', _b_b__a: '1'}, 794 | {_id: '2', _a__id: '2', _a__a: '2', _a__b__id: '2', _b_id: '1', _b_a: '1', _b_b__id: '2', _b_b__a: null} 795 | ]; 796 | result = NestHydrationJS.nest(data); 797 | }); 798 | 799 | it('should match expected structure', function () { 800 | var expected = [ 801 | { 802 | id: '1', 803 | a: [], 804 | b: { 805 | id: '1', 806 | a: '1', 807 | b: [ 808 | { 809 | id: '1', 810 | a: '1' 811 | }, 812 | { 813 | id: '2', 814 | a: null 815 | } 816 | ] 817 | } 818 | }, 819 | { 820 | id: '2', 821 | a: [ 822 | { 823 | id: '1', 824 | a: '1', 825 | b: [] 826 | }, 827 | { 828 | id: '2', 829 | a: '2', 830 | b: [ 831 | { 832 | id: '1' 833 | }, 834 | { 835 | id: '2' 836 | } 837 | ] 838 | } 839 | ], 840 | b: { 841 | id: '1', 842 | a: '1', 843 | b: [ 844 | { 845 | id: '1', 846 | a: '1' 847 | }, 848 | { 849 | id: '2', 850 | a: null 851 | } 852 | ] 853 | } 854 | } 855 | ]; 856 | expect(result).toEqual(expected); 857 | }); 858 | }); 859 | describe('Documentation Example 1', function () { 860 | var result; 861 | beforeEach(function () { 862 | var table = [ 863 | {id: '1', title: 'Tabular to Objects', teacher_id: '1', teacher_name: 'David', lesson_id: '1', lesson_title: 'Definitions' }, 864 | {id: '1', title: 'Tabular to Objects', teacher_id: '1', teacher_name: 'David', lesson_id: '2', lesson_title: 'Table Data' }, 865 | {id: '1', title: 'Tabular to Objects', teacher_id: '1', teacher_name: 'David', lesson_id: '3', lesson_title: 'Objects' }, 866 | {id: '2', title: 'Column Names Define Structure', teacher_id: '2', teacher_name: 'Chris', lesson_id: '4', lesson_title: 'Column Names' }, 867 | {id: '2', title: 'Column Names Define Structure', teacher_id: '2', teacher_name: 'Chris', lesson_id: '2', lesson_title: 'Table Data' }, 868 | {id: '2', title: 'Column Names Define Structure', teacher_id: '2', teacher_name: 'Chris', lesson_id: '3', lesson_title: 'Objects' }, 869 | {id: '3', title: 'Object On Bottom', teacher_id: '1', teacher_name: 'David', lesson_id: '5', lesson_title: 'Non Array Input'} 870 | ]; 871 | var definition = [{ 872 | id: 'id', 873 | title: 'title', 874 | teacher: { 875 | id: 'teacher_id', 876 | name: 'teacher_name' 877 | }, 878 | lesson: [{ 879 | id: 'lesson_id', 880 | title: 'lesson_title' 881 | }] 882 | }]; 883 | result = NestHydrationJS.nest(table, definition); 884 | }); 885 | it('should match expected structure', function () { 886 | var expected = [ 887 | {id: '1', title: 'Tabular to Objects', teacher: {id: '1', name: 'David'}, lesson: [ 888 | {id: '1', title: 'Definitions'}, 889 | {id: '2', title: 'Table Data'}, 890 | {id: '3', title: 'Objects'} 891 | ]}, 892 | {id: '2', title: 'Column Names Define Structure', teacher: {id: '2', name: 'Chris'}, lesson: [ 893 | {id: '4', title: 'Column Names'}, 894 | {id: '2', title: 'Table Data'}, 895 | {id: '3', title: 'Objects'} 896 | ]}, 897 | {id: '3', title: 'Object On Bottom', teacher: {id: '1', name: 'David'}, lesson: [ 898 | {id: '5', title: 'Non Array Input'} 899 | ]} 900 | ]; 901 | expect(result).toEqual(expected); 902 | }); 903 | }); 904 | describe('Flatish with reused structure and some not', function () { 905 | var result; 906 | beforeEach(function () { 907 | var table = [ 908 | {_uniqueId: '403_10', _gradeComponent_id___NUMBER: 403, _gradeComponent_name: 'gradeComponent4', _gradeComponent_weight: 0.5, _gradeComponent_type: 'participation', _workspace_id___NUMBER: 200, _workspace_name: 'Learning More Every Day Workspace', _user_id___NUMBER: '10', _user_avatar_gravatar: '1f06a000a42796be652e66d6c078aae3', _user_firstname: 'Bob', _user_lastname: 'Brown', _grade_uniqueId: '403_10', _grade_given___NUMBER: '0.00000000000000000000', _grade_calculated___NUMBER: '0.00000000000000000000', _grade_manual___BOOLEAN: false, _grade_attendance_id___NUMBER: 8, _grade_attendance_presents___NUMBER: null, _grade_attendance_absents___NUMBER: null, _grade_attendance_total___NUMBER: null, _grade_participation_id___NUMBER: 8, _grade_participation_positive___NUMBER: 0, _grade_participation_negative___NUMBER: 1}, 909 | {_uniqueId: '402_10', _gradeComponent_id___NUMBER: 402, _gradeComponent_name: 'gradeComponent3', _gradeComponent_weight: 0.2, _gradeComponent_type: 'participation', _workspace_id___NUMBER: 201, _workspace_name: 'Bluedrop learning', _user_id___NUMBER: '10', _user_avatar_gravatar: '1f06a000a42796be652e66d6c078aae3', _user_firstname: 'Bob', _user_lastname: 'Brown', _grade_uniqueId: '402_10', _grade_given___NUMBER: '0.50', _grade_calculated___NUMBER: null, _grade_manual___BOOLEAN: true, _grade_attendance_id___NUMBER: 7, _grade_attendance_presents___NUMBER: null, _grade_attendance_absents___NUMBER: null, _grade_attendance_total___NUMBER: null, _grade_participation_id___NUMBER: 7, _grade_participation_positive___NUMBER: null, _grade_participation_negative___NUMBER: null}, 910 | {_uniqueId: '401_10', _gradeComponent_id___NUMBER: 401, _gradeComponent_name: 'gradeComponent2', _gradeComponent_weight: 0.2, _gradeComponent_type: 'assignments', _workspace_id___NUMBER: 201, _workspace_name: 'Bluedrop learning', _user_id___NUMBER: '10', _user_avatar_gravatar: '1f06a000a42796be652e66d6c078aae3', _user_firstname: 'Bob', _user_lastname: 'Brown', _grade_uniqueId: '401_10', _grade_given___NUMBER: '0.00', _grade_calculated___NUMBER: '0.70000000000000000000', _grade_manual___BOOLEAN: true, _grade_attendance_id___NUMBER: 5, _grade_attendance_presents___NUMBER: null, _grade_attendance_absents___NUMBER: null, _grade_attendance_total___NUMBER: null, _grade_participation_id___NUMBER: 5, _grade_participation_positive___NUMBER: null, _grade_participation_negative___NUMBER: null}, 911 | {_uniqueId: '400_10', _gradeComponent_id___NUMBER: 400, _gradeComponent_name: 'gradeComponent1', _gradeComponent_weight: 0.5, _gradeComponent_type: 'assignments', _workspace_id___NUMBER: 200, _workspace_name: 'Learning More Every Day Workspace', _user_id___NUMBER: '10', _user_avatar_gravatar: '1f06a000a42796be652e66d6c078aae3', _user_firstname: 'Bob', _user_lastname: 'Brown', _grade_uniqueId: '400_10', _grade_given___NUMBER: '0.80', _grade_calculated___NUMBER: '0.70000000000000000000', _grade_manual___BOOLEAN: true, _grade_attendance_id___NUMBER: 1, _grade_attendance_presents___NUMBER: null, _grade_attendance_absents___NUMBER: null, _grade_attendance_total___NUMBER: null, _grade_participation_id___NUMBER: 1, _grade_participation_positive___NUMBER: 0, _grade_participation_negative___NUMBER: 1} 912 | ]; 913 | result = NestHydrationJS.nest(table); 914 | }); 915 | it('should match expected structure', function () { 916 | var expected = [ 917 | { 918 | uniqueId: '403_10', 919 | gradeComponent: { 920 | id: 403, 921 | name: 'gradeComponent4', 922 | weight: 0.5, 923 | type: 'participation' 924 | }, 925 | workspace: { 926 | id: 200, 927 | name: 'Learning More Every Day Workspace' 928 | }, 929 | user: { 930 | id: 10, 931 | firstname: 'Bob', 932 | lastname: 'Brown', 933 | avatar: { 934 | gravatar: '1f06a000a42796be652e66d6c078aae3' 935 | } 936 | }, 937 | grade: { 938 | uniqueId: '403_10', 939 | given: 0, 940 | calculated: 0, 941 | manual: false, 942 | attendance: { 943 | id: 8, 944 | presents: null, 945 | absents: null, 946 | total : null 947 | }, 948 | participation: { 949 | id: 8, 950 | positive: 0, 951 | negative: 1 952 | } 953 | } 954 | }, 955 | { 956 | uniqueId: '402_10', 957 | gradeComponent: { 958 | id: 402, 959 | name: 'gradeComponent3', 960 | weight: 0.2, 961 | type: 'participation' 962 | }, 963 | workspace: { 964 | id: 201, 965 | name: 'Bluedrop learning' 966 | }, 967 | user: { 968 | id: 10, 969 | firstname: 'Bob', 970 | lastname: 'Brown', 971 | avatar: { 972 | gravatar: '1f06a000a42796be652e66d6c078aae3' 973 | } 974 | }, 975 | grade: { 976 | uniqueId: '402_10', 977 | given: 0.5, 978 | calculated: null, 979 | manual: true, 980 | attendance: { 981 | id: 7, 982 | presents: null, 983 | absents: null, 984 | total : null 985 | }, 986 | participation: { 987 | id: 7, 988 | positive: null, 989 | negative: null 990 | } 991 | } 992 | }, 993 | { 994 | uniqueId: '401_10', 995 | gradeComponent: { 996 | id: 401, 997 | name: 'gradeComponent2', 998 | weight: 0.2, 999 | type: 'assignments' 1000 | }, 1001 | workspace: { 1002 | id: 201, 1003 | name: 'Bluedrop learning' 1004 | }, 1005 | user: { 1006 | id: 10, 1007 | firstname: 'Bob', 1008 | lastname: 'Brown', 1009 | avatar: 1010 | { 1011 | gravatar: '1f06a000a42796be652e66d6c078aae3' 1012 | } 1013 | }, 1014 | grade: { 1015 | uniqueId: '401_10', 1016 | given: 0, 1017 | calculated: 0.7, 1018 | manual: true, 1019 | attendance: { 1020 | id: 5, 1021 | presents: null, 1022 | absents: null, 1023 | total : null 1024 | }, 1025 | participation: { 1026 | id: 5, 1027 | positive: null, 1028 | negative: null 1029 | } 1030 | } 1031 | }, 1032 | { 1033 | uniqueId: '400_10', 1034 | gradeComponent: { 1035 | id: 400, 1036 | name: 'gradeComponent1', 1037 | weight: 0.5, 1038 | type: 'assignments' 1039 | }, 1040 | workspace: { 1041 | id: 200, 1042 | name: 'Learning More Every Day Workspace' 1043 | }, 1044 | user: { 1045 | id: 10, 1046 | firstname: 'Bob', 1047 | lastname: 'Brown', 1048 | avatar: { 1049 | gravatar: '1f06a000a42796be652e66d6c078aae3' 1050 | } 1051 | }, 1052 | grade: { 1053 | uniqueId: '400_10', 1054 | given: 0.8, 1055 | calculated: 0.7, 1056 | manual: true, 1057 | attendance: { 1058 | id: 1, 1059 | presents: null, 1060 | absents: null, 1061 | total : null 1062 | }, 1063 | participation: { 1064 | id: 1, 1065 | positive: 0, 1066 | negative: 1 1067 | } 1068 | } 1069 | } 1070 | ]; 1071 | expect(result).toEqual(expected); 1072 | }); 1073 | }); 1074 | }); 1075 | 1076 | it('Should not break on null data with complex nesting', function () { 1077 | var rows = [ 1078 | { 1079 | 'id': 1, 1080 | 'nested__id': 3 1081 | }, 1082 | { 1083 | 'id': 2, 1084 | 'nested__id': null 1085 | } 1086 | ]; 1087 | var shapeDefinition = [ 1088 | { 1089 | 'id': 'id', 1090 | 'nested': { 1091 | 'id': 'nested__id', 1092 | 'subArray': [{ 1093 | 'id': 'does_not_exist' 1094 | }] 1095 | } 1096 | } 1097 | ]; 1098 | var result = NestHydrationJS.nest(rows, shapeDefinition); 1099 | expect(result).toEqual([ 1100 | { 1101 | id: 1, 1102 | nested: { 1103 | id: 3, 1104 | subArray: [ 1105 | { 1106 | id: undefined 1107 | } 1108 | ] 1109 | } 1110 | }, 1111 | { 1112 | id: 2, 1113 | nested: null 1114 | } 1115 | ]); 1116 | }); 1117 | }); 1118 | -------------------------------------------------------------------------------- /spec/NestHydrationJS/registerType.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var NestHydrationJS = require('../../NestHydrationJS')(); 4 | 5 | describe('NestHydrationJS', function () { 6 | describe('registerType function', function () { 7 | it('should register new type register', function() { 8 | var handler = function(){}; 9 | NestHydrationJS.registerType('FOO', handler); 10 | expect(NestHydrationJS.typeHandlers.FOO).toBe(handler); 11 | }); 12 | it('should error on overwrite of existing type handler', function() { 13 | var handler = function(){}; 14 | expect(NestHydrationJS.registerType.bind(NestHydrationJS, 'NUMBER', handler)).toThrowError(/Handler with type, NUMBER, already exists/); 15 | }); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /spec/NestHydrationJS/structPropToColumnMapFromColumnHints.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var NestHydrationJS = require('../../NestHydrationJS')(); 4 | 5 | describe('NestHydrationJS', function () { 6 | describe('structPropToColumnMapFromColumnHints method', function () { 7 | describe('passed empty as columnList', function () { 8 | var result; 9 | beforeEach(function () { 10 | var columnList = []; 11 | result = NestHydrationJS.structPropToColumnMapFromColumnHints(columnList); 12 | }); 13 | 14 | it('should match expected structure', function () { 15 | expect(result).toBeNull(); 16 | }); 17 | }); 18 | 19 | describe('passed single direct property as columnList', function () { 20 | var result; 21 | beforeEach(function () { 22 | var columnList = [ 23 | 'a' 24 | ]; 25 | result = NestHydrationJS.structPropToColumnMapFromColumnHints(columnList); 26 | }); 27 | 28 | it('should match expected structure', function () { 29 | var expected = { 30 | a: 'a' 31 | }; 32 | expect(result).toEqual(expected); 33 | }); 34 | }); 35 | 36 | describe('passed single direct property as columnList, number type', function () { 37 | var result; 38 | beforeEach(function () { 39 | var columnList = [ 40 | 'a___NUMBER' 41 | ]; 42 | result = NestHydrationJS.structPropToColumnMapFromColumnHints(columnList); 43 | }); 44 | 45 | it('should match expected structure', function () { 46 | var expected = { 47 | a: {column: 'a___NUMBER', type: 'NUMBER'} 48 | }; 49 | expect(result).toEqual(expected); 50 | }); 51 | }); 52 | 53 | describe('passed single direct property as columnList, boolean type', function () { 54 | var result; 55 | beforeEach(function () { 56 | var columnList = [ 57 | 'a___BOOLEAN' 58 | ]; 59 | result = NestHydrationJS.structPropToColumnMapFromColumnHints(columnList); 60 | }); 61 | 62 | it('should match expected structure', function () { 63 | var expected = { 64 | a: {column: 'a___BOOLEAN', type: 'BOOLEAN'} 65 | }; 66 | expect(result).toEqual(expected); 67 | }); 68 | }); 69 | 70 | describe('passed single direct property as columnList, id column', function () { 71 | var result; 72 | beforeEach(function () { 73 | var columnList = [ 74 | 'a___ID' 75 | ]; 76 | result = NestHydrationJS.structPropToColumnMapFromColumnHints(columnList); 77 | }); 78 | 79 | it('should match expected structure', function () { 80 | var expected = { 81 | a: {column: 'a___ID', id: true} 82 | }; 83 | expect(result).toEqual(expected); 84 | }); 85 | }); 86 | 87 | describe('passed single direct property as columnList, multiple id columns', function () { 88 | var result; 89 | beforeEach(function () { 90 | var columnList = [ 91 | 'a___ID', 92 | 'b___ID' 93 | ]; 94 | result = NestHydrationJS.structPropToColumnMapFromColumnHints(columnList); 95 | }); 96 | 97 | it('should match expected structure', function () { 98 | var expected = 'invalid - multiple id - a___ID and b___ID conflict'; 99 | expect(result).toEqual(expected); 100 | }); 101 | }); 102 | 103 | describe('passed single direct property as columnList, id column and typed', function () { 104 | var result; 105 | beforeEach(function () { 106 | var columnList = [ 107 | 'a___ID___NUMBER' 108 | ]; 109 | result = NestHydrationJS.structPropToColumnMapFromColumnHints(columnList); 110 | }); 111 | 112 | it('should match expected structure', function () { 113 | var expected = { 114 | a: {column: 'a___ID___NUMBER', type: 'NUMBER', id: true} 115 | }; 116 | expect(result).toEqual(expected); 117 | }); 118 | }); 119 | 120 | describe('passed single direct property as columnList, id column and typed, reverse order', function () { 121 | var result; 122 | beforeEach(function () { 123 | var columnList = [ 124 | 'a___NUMBER___ID' 125 | ]; 126 | result = NestHydrationJS.structPropToColumnMapFromColumnHints(columnList); 127 | }); 128 | 129 | it('should match expected structure', function () { 130 | var expected = { 131 | a: {column: 'a___NUMBER___ID', type: 'NUMBER', id: true} 132 | }; 133 | expect(result).toEqual(expected); 134 | }); 135 | }); 136 | 137 | describe('passed single direct property as columnList, renamed', function () { 138 | var result; 139 | beforeEach(function () { 140 | var columnList = [ 141 | 'a' 142 | ]; 143 | var renameMap = { 144 | 'a': 'col_1' 145 | }; 146 | result = NestHydrationJS.structPropToColumnMapFromColumnHints(columnList, renameMap); 147 | }); 148 | 149 | it('should match expected structure', function () { 150 | var expected = { 151 | a: 'col_1' 152 | }; 153 | expect(result).toEqual(expected); 154 | }); 155 | }); 156 | 157 | describe('passed multiple direct properties as columnList', function () { 158 | var result; 159 | beforeEach(function () { 160 | var columnList = [ 161 | 'a', 162 | 'b' 163 | ]; 164 | result = NestHydrationJS.structPropToColumnMapFromColumnHints(columnList); 165 | }); 166 | 167 | it('should match expected structure', function () { 168 | var expected = { 169 | a: 'a', 170 | b: 'b' 171 | }; 172 | expect(result).toEqual(expected); 173 | }); 174 | }); 175 | 176 | describe('passed single many relation property as columnList', function () { 177 | var result; 178 | beforeEach(function () { 179 | var columnList = [ 180 | '_a' 181 | ]; 182 | result = NestHydrationJS.structPropToColumnMapFromColumnHints(columnList); 183 | }); 184 | 185 | it('should match expected structure', function () { 186 | var expected = [{ 187 | a: '_a' 188 | }]; 189 | expect(result).toEqual(expected); 190 | }); 191 | }); 192 | 193 | describe('passed multiple many relation properties as columnList', function () { 194 | var result; 195 | beforeEach(function () { 196 | var columnList = [ 197 | '_a', 198 | '_b' 199 | ]; 200 | result = NestHydrationJS.structPropToColumnMapFromColumnHints(columnList); 201 | }); 202 | 203 | it('should match expected structure', function () { 204 | var expected = [{ 205 | a: '_a', 206 | b: '_b' 207 | }]; 208 | expect(result).toEqual(expected); 209 | }); 210 | }); 211 | 212 | describe('passed 2nd level depth on simple properties as columnList', function () { 213 | var result; 214 | beforeEach(function () { 215 | var columnList = [ 216 | 'a', 217 | 'b_c' 218 | ]; 219 | result = NestHydrationJS.structPropToColumnMapFromColumnHints(columnList); 220 | }); 221 | 222 | it('should match expected structure', function () { 223 | var expected = { 224 | a: 'a', 225 | b: { 226 | c: 'b_c' 227 | } 228 | }; 229 | expect(result).toEqual(expected); 230 | }); 231 | }); 232 | 233 | describe('passed complex single base scenaro as columnList', function () { 234 | var result; 235 | beforeEach(function () { 236 | var columnList = [ 237 | 'id', 238 | 'a_id', 239 | 'a_b', 240 | 'a_c__id', 241 | 'a_c__d', 242 | 'a_e_id', 243 | 'a_e_f' 244 | ]; 245 | result = NestHydrationJS.structPropToColumnMapFromColumnHints(columnList); 246 | }); 247 | 248 | it('should match expected structure', function () { 249 | var expected = { 250 | id: 'id', 251 | a: { 252 | id: 'a_id', 253 | b: 'a_b', 254 | c: [{ 255 | id: 'a_c__id', 256 | d: 'a_c__d' 257 | }], 258 | e: { 259 | id: 'a_e_id', 260 | f: 'a_e_f' 261 | } 262 | } 263 | }; 264 | expect(result).toEqual(expected); 265 | }); 266 | }); 267 | 268 | describe('passed complex single base scenaro as columnList with capitializations', function () { 269 | var result; 270 | beforeEach(function () { 271 | var columnList = [ 272 | 'id', 273 | 'aItem__id', 274 | 'aItem__bValue', 275 | 'aItem__cItem__id', 276 | 'aItem__cItem__dValue', 277 | 'aItem__cItem__eItem_id', 278 | 'aItem__cItem__eItem_fValue' 279 | ]; 280 | result = NestHydrationJS.structPropToColumnMapFromColumnHints(columnList); 281 | }); 282 | 283 | it('should match expected structure', function () { 284 | var expected = { 285 | id: 'id', 286 | aItem: [{ 287 | id: 'aItem__id', 288 | bValue: 'aItem__bValue', 289 | cItem: [{ 290 | id: 'aItem__cItem__id', 291 | dValue: 'aItem__cItem__dValue', 292 | eItem: { 293 | id: 'aItem__cItem__eItem_id', 294 | fValue: 'aItem__cItem__eItem_fValue' 295 | } 296 | }] 297 | }] 298 | }; 299 | expect(result).toEqual(expected); 300 | }); 301 | }); 302 | 303 | describe('passed complex single base scenaro as columnList with number specifiers', function () { 304 | var result; 305 | beforeEach(function () { 306 | var columnList = [ 307 | 'id___NUMBER', 308 | 'a_id___NUMBER', 309 | 'a_b', 310 | 'a_c__id___NUMBER', 311 | 'a_c__d', 312 | 'a_e_id___NUMBER', 313 | 'a_e_f' 314 | ]; 315 | result = NestHydrationJS.structPropToColumnMapFromColumnHints(columnList); 316 | }); 317 | 318 | it('should match expected structure', function () { 319 | var expected = { 320 | id: { 321 | column: 'id___NUMBER', 322 | type: 'NUMBER' 323 | }, 324 | a: { 325 | id: { 326 | column: 'a_id___NUMBER', 327 | type: 'NUMBER' 328 | }, 329 | b: 'a_b', 330 | c: [{ 331 | id: { 332 | column: 'a_c__id___NUMBER', 333 | type: 'NUMBER' 334 | }, 335 | d: 'a_c__d' 336 | }], 337 | e: { 338 | id: { 339 | column: 'a_e_id___NUMBER', 340 | type: 'NUMBER' 341 | }, 342 | f: 'a_e_f' 343 | } 344 | } 345 | }; 346 | expect(result).toEqual(expected); 347 | }); 348 | }); 349 | 350 | describe('passed complex array base scenaro as columnList', function () { 351 | var result; 352 | beforeEach(function () { 353 | var columnList = [ 354 | '_id', 355 | '_a_id', 356 | '_a_b', 357 | '_a_c__id', 358 | '_a_c__d', 359 | '_a_e_id', 360 | '_a_e_f' 361 | ]; 362 | result = NestHydrationJS.structPropToColumnMapFromColumnHints(columnList); 363 | }); 364 | 365 | it('should match expected structure', function () { 366 | var expected = [{ 367 | id: '_id', 368 | a: { 369 | id: '_a_id', 370 | b: '_a_b', 371 | c: [{ 372 | id: '_a_c__id', 373 | d: '_a_c__d' 374 | }], 375 | e: { 376 | id: '_a_e_id', 377 | f: '_a_e_f' 378 | } 379 | } 380 | }]; 381 | expect(result).toEqual(expected); 382 | }); 383 | }); 384 | 385 | describe('passed complex scenaro as columnList, rename', function () { 386 | var result; 387 | beforeEach(function () { 388 | var columnList = [ 389 | '_id', 390 | '_a_id', 391 | '_a_b', 392 | '_a_c__id', 393 | '_a_c__d' 394 | ]; 395 | var renameMap = { 396 | '_a_c__id': 'col_0', 397 | '_a_c__d': 'col_1' 398 | }; 399 | result = NestHydrationJS.structPropToColumnMapFromColumnHints(columnList, renameMap); 400 | }); 401 | 402 | it('should match expected structure', function () { 403 | var expected = [{ 404 | id: '_id', 405 | a: { 406 | id: '_a_id', 407 | b: '_a_b', 408 | c: [{ 409 | id: 'col_0', 410 | d: 'col_1' 411 | }] 412 | } 413 | }]; 414 | expect(result).toEqual(expected); 415 | }); 416 | }); 417 | }); 418 | }); 419 | -------------------------------------------------------------------------------- /spec/NestHydrationJS/typeHandlers.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var NestHydrationJS = require('../../NestHydrationJS')(); 4 | 5 | describe('NestHydrationJS', function () { 6 | describe('typeHandlers', function () { 7 | describe('NUMBER function', function () { 8 | it('should convert string to float', function() { 9 | expect(NestHydrationJS.typeHandlers.NUMBER('1.234')).toBeCloseTo(1.234); 10 | }); 11 | it('should convert number to float', function() { 12 | expect(NestHydrationJS.typeHandlers.NUMBER(1.234)).toBeCloseTo(1.234); 13 | }); 14 | }); 15 | 16 | describe('BOOLEAN function', function () { 17 | it('should convert numeric 1 to true', function() { 18 | expect(NestHydrationJS.typeHandlers.BOOLEAN(1)).toBe(true); 19 | }); 20 | it('should convert numeric 0 to false', function() { 21 | expect(NestHydrationJS.typeHandlers.BOOLEAN(0)).toBe(false); 22 | }); 23 | it('should convert string 1 to true', function() { 24 | expect(NestHydrationJS.typeHandlers.BOOLEAN('1')).toBe(true); 25 | }); 26 | it('should convert string 0 to false', function() { 27 | expect(NestHydrationJS.typeHandlers.BOOLEAN('0')).toBe(false); 28 | }); 29 | }); 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /spec/support/jasmine.json: -------------------------------------------------------------------------------- 1 | { 2 | "spec_dir": "spec", 3 | "spec_files": [ 4 | "**/*[sS]pec.js" 5 | ], 6 | "helpers": [ 7 | "helpers/**/*.js" 8 | ] 9 | } 10 | --------------------------------------------------------------------------------