├── .gitignore ├── README.md ├── index.js ├── lib ├── create.js ├── delete.js ├── endpoint.js ├── isURL.js ├── read.js ├── update.js └── validAddress.js ├── package-lock.json ├── package.json └── test ├── create.spec.js ├── delete.spec.js ├── endpoint.spec.js ├── read.spec.js ├── test.js └── update.spec.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Installation 2 | 3 | ``` 4 | npm install sheetdb-node --save 5 | ``` 6 | 7 | ## Usage 8 | 9 | ### Generating a Client 10 | 11 | You need to create a new sheetdb function, and populate it with your SheetDB API URL. You can find this URL on [SheetDB Dashboard](https://sheetdb.io/login). 12 | 13 | ```js 14 | var sheetdb = require('sheetdb-node'); 15 | 16 | // create a config file 17 | var config = { 18 | address: '58f61be4dda40', 19 | }; 20 | 21 | // Create new client 22 | var client = sheetdb(config); 23 | 24 | ``` 25 | for ES6 26 | ```js 27 | import sheetdb from 'sheetdb-node'; 28 | 29 | // create a config file 30 | var config = { 31 | address: '58f61be4dda40', 32 | }; 33 | 34 | // Create new client 35 | var client = sheetdb(config); 36 | ``` 37 | 38 | If you have HTTP Basic Authentication turned on for your API, you should pass `auth_login` and `auth_password` here, like: 39 | ```js 40 | // create a config file 41 | var config = { 42 | address: '58f61be4dda40', 43 | auth_login: 'BASIC_AUTH_login', 44 | auth_password: 'BASIC_AUTH_password', 45 | }; 46 | 47 | // Create new client 48 | var client = sheetdb(config); 49 | ``` 50 | 51 | ### CRUD 52 | 53 | SheetDB gives you the ability to use full CRUD on your Google Spreadsheet. Remember to populate the first row of every sheet with column names. You can look at [example spreadsheet](https://docs.google.com/spreadsheets/d/1mrsgBk4IAdSs8Ask5H1z3bWYDlPTKplDIU_FzyktrGk/edit). 54 | 55 | ### Create 56 | [Link to docs](https://docs.sheetdb.io/#post-create-row) 57 | 58 | To add data to Google Spreadsheets, send an object or an array of objects. 59 | ```js 60 | // Adds single row 61 | client.create({ name: "William", age: 25 }).then(function(data) { 62 | console.log(data); 63 | }, function(err){ 64 | console.log(err); 65 | }); 66 | 67 | /// Adds bunch of rows 68 | rows = [ 69 | { name: "William", age: 25 }, 70 | { name: "Jayden", age: 25 } 71 | ] 72 | client.create(rows).then(function(data) { 73 | console.log(data); 74 | }, function(err){ 75 | console.log(err); 76 | }); 77 | 78 | ``` 79 | 80 | By default, all writes are performed on the first sheet (worksheet). Pass name of a sheet as a 2nd param to add data to other worksheet. 81 | ```js 82 | // Adds single row to worksheet named "Sheet3" 83 | client.create({ player: "William", score: 75 }, "Sheet2").then(function(data) { 84 | console.log(data); 85 | }, function(err){ 86 | console.log(err); 87 | }); 88 | 89 | ``` 90 | 91 | On success returns a number of created rows. 92 | 93 | ### Read 94 | [Link to docs](https://docs.sheetdb.io/#get-all-data) 95 | 96 | Read the whole sheet 97 | ```js 98 | client.read({ limit, offset, search, sheet }).then(function(data) { 99 | console.log(data); 100 | }, function(err){ 101 | console.log(err); 102 | }); 103 | ``` 104 | 105 | You can pass attributes with options 106 | - `limit` - limit number of results 107 | - `offset` - start from N first record 108 | - `search` - object with search params [(more below)](#search) 109 | - `sheet` - get data from named worksheet 110 | 111 | ```js 112 | // Get first two rows from worksheet named "Sheet2" 113 | client.read({ limit: 2, sheet: "Sheet2" }).then(function(data) { 114 | console.log(data); 115 | }, function(err){ 116 | console.log(err); 117 | }); 118 | 119 | // Get 3rd and 4th record from worksheet named "Sheet2" 120 | client.read({ limit: 2, offset: 2, sheet: 'Sheet2' }).then(function(data) { 121 | console.log(data); 122 | }, function(err){ 123 | console.log(err); 124 | }); 125 | ``` 126 | 127 | #### search 128 | [Link to docs](https://docs.sheetdb.io/#get-search-in-document) 129 | 130 | To get rows that match search criteria, pass an object with search params 131 | 132 | ```js 133 | // Get all rows where column 'id' is 'foo' and column 'value' is 'bar' 134 | client.read({ search: { id: "foo", value: "bar" } }).then(function(data) { 135 | console.log(data); 136 | }, function(err){ 137 | console.log(err); 138 | }); 139 | 140 | // Get all rows where column 'First name' is 'Smith' and column 'Score' is '42' 141 | client.read({ search: { 'first name': 'Smith', 'Score': 42 } }).then(function(data) { 142 | console.log(data); 143 | }, function(err){ 144 | console.log(err); 145 | }); 146 | 147 | 148 | // Get first two rows where column 'player' is 'Smith', 149 | // column 'score' is '41' from sheet named "Sheet2" 150 | client.read({ 151 | limit: 2, 152 | search: { 'player': 'Smith', 'score': 41 }, 153 | sheet: 'Sheet2' 154 | }).then(function(data) { 155 | console.log(data); 156 | }, function(err){ 157 | console.log(err); 158 | }); 159 | 160 | ``` 161 | 162 | On success returns an array of objects. 163 | 164 | ### Update 165 | [Link to docs](https://docs.sheetdb.io/#patch-put-update) 166 | 167 | To update row(s), pass column name and its value which is used to find row(s). 168 | 169 | ``` js 170 | client.update(columnName, value, newRow, sheet).then(function(data) { 171 | console.log(data); 172 | }, function(err){ 173 | console.log(err); 174 | }); 175 | ``` 176 | 177 | ```js 178 | // Update all columns where 'name' is 'Smith' to have 'score' = 99 and 'comment' = 'Griffin' 179 | client.update( 180 | 'name', // column name 181 | 'Smith', // value to search for 182 | { 'score': 99, 'comment': 'Griffin' } // object with updates 183 | ).then(function(data) { 184 | console.log(data); 185 | }, function(err){ 186 | console.log(err); 187 | }); 188 | ``` 189 | 190 | To perform `#update` on different than the first sheet, pass sheet name as a 4th argument. 191 | ```js 192 | // Update all columns where 'name' is 'Smith' to have 'score' = 99 and 'comment' = 'Griffin' 193 | // In sheet named 'Sheet2' 194 | client.update( 195 | 'name', // column name 196 | 'Smith', // value to search for 197 | { 'score': 99, 'comment': 'Griffin' }, // object with updates 198 | 'Sheet2' 199 | ).then(function(data) { 200 | console.log(data); 201 | }, function(err){ 202 | console.log(err); 203 | }); 204 | ``` 205 | 206 | On success returns a number of updated rows. 207 | 208 | ### Delete 209 | [Link to docs](https://docs.sheetdb.io/#delete) 210 | 211 | To delete row(s), pass column name and its value which is used to find row(s). 212 | 213 | ```js 214 | // Delete all rows where 'name' equals 'Smith' 215 | client.delete( 216 | 'id', // column name 217 | '1' // value to search for 218 | ).then(function(data) { 219 | console.log(data); 220 | }, function(err){ 221 | console.log(err); 222 | }); 223 | ``` 224 | 225 | You can pass sheet name as a 3rd argument. All operations are performed on the first sheet, by default. 226 | ```js 227 | // Delete all rows where 'foo' equals 'bar' in sheet 'Sheet3' 228 | client.delete( 229 | player, // column name 230 | 'Smith', // value to search for 231 | 'Sheet2' 232 | ).then(function(data) { 233 | console.log(data); 234 | }, function(err){ 235 | console.log(err); 236 | }); 237 | ``` 238 | 239 | ## Development 240 | 241 | Run all tests: 242 | ``` 243 | npm test 244 | ``` 245 | 246 | Run a nyan version test: 247 | ``` 248 | npm run nyan-test 249 | ``` 250 | 251 | ## Contributing 252 | 253 | Bug reports and pull requests are welcome on GitHub at https://github.com/sheetdb/sheetdb-node. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct. 254 | 255 | ### Pull Requests 256 | 257 | - **Add tests!** Your patch won't be accepted if it doesn't have tests. 258 | 259 | - **Create topic branches**. Please, always create a branch with meaningful name. Don't ask us to pull from your master branch. 260 | 261 | - **One pull request per feature**. If you want to do more than one thing, please send multiple pull requests. 262 | 263 | - **Send coherent history**. Make sure each individual commit in your pull 264 | request is meaningful. If you had to make multiple intermediate commits while 265 | developing, please squash them before sending them to us. 266 | 267 | ### Docs 268 | 269 | [SheetDB documentation sits on GitHub](https://github.com/sheetdb/docs). We would love your contributions! We want to make these docs accessible and easy to understand for everyone. Please send us Pull Requests or open issues on GitHub. 270 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | // sheetdb = require(sheetdb-node); 2 | // (ES6+) import sheetdb from 'sheetdb-node'; 3 | // 4 | // sheetdb.create(newRow, sheet); 5 | // sheetdb.read(limit, offset, search, sheet); 6 | // sheetdb.update(columnName, value, newRow, updateWhole, sheet); 7 | // sheetdb.delete(columnName, value, sheet); 8 | 9 | var readFunc = require('./lib/read.js'); 10 | var createFunc = require('./lib/create.js'); 11 | var updateFunc = require('./lib/update.js'); 12 | var deleteFunc = require('./lib/delete.js'); 13 | var endpointFunc = require('./lib/endpoint.js'); 14 | var validAddress = require('./lib/validAddress.js'); 15 | var isURL = require('./lib/isURL.js'); 16 | 17 | 18 | var sheetdbNode = function(config) { 19 | var configParam = config || {}; 20 | 21 | configParam.version = configParam.version || '1'; 22 | configParam.auth_login = configParam.auth_login || ''; 23 | configParam.auth_password = configParam.auth_password || ''; 24 | 25 | if(!configParam.address) { 26 | throw Error('address param needed'); 27 | } 28 | 29 | if(!validAddress(configParam.address)) { 30 | throw Error('wrong address param.'); 31 | } 32 | 33 | if(!isURL(configParam.address)) { 34 | configParam.address = 'https://sheetdb.io/api/v' + 35 | configParam.version + '/' + 36 | configParam.address; 37 | } 38 | 39 | var address = configParam.address; 40 | 41 | return { 42 | config: configParam, 43 | create: createFunc, 44 | read: readFunc, 45 | update: updateFunc, 46 | delete: deleteFunc, 47 | endpoint: endpointFunc, 48 | } 49 | } 50 | 51 | module.exports = sheetdbNode; 52 | -------------------------------------------------------------------------------- /lib/create.js: -------------------------------------------------------------------------------- 1 | var btoa = require('btoa'); 2 | if(typeof window != 'undefined') { 3 | XMLHttpRequest = require('xhr2'); 4 | } 5 | 6 | module.exports = function(newRow, sheet) { 7 | var config = this.config; 8 | 9 | return new Promise(function(resolve, reject) { 10 | var xhr = new XMLHttpRequest(); 11 | var sheetParam = (!sheet) ? '' : '?sheet=' + sheet; 12 | var data; 13 | 14 | data = JSON.stringify({ 15 | data: newRow, 16 | }); 17 | 18 | var url = config.address + sheetParam; 19 | 20 | xhr.open('POST', url, true); 21 | xhr.setRequestHeader("Accept", "application/vnd.sheetdb.3+json"); 22 | xhr.setRequestHeader("Content-Type", "application/json"); 23 | xhr.setRequestHeader("X-User-Agent", "SheetDB-Node/"+config.version); 24 | 25 | if (config.auth_login && config.auth_password) { 26 | xhr.setRequestHeader("Authorization", "Basic " + btoa(config.auth_login+":"+config.auth_password)); 27 | } 28 | 29 | xhr.onload = function (e) { 30 | if (xhr.readyState === 4) { 31 | resolve(xhr.response); 32 | } 33 | }; 34 | 35 | xhr.onerror = function (e) { 36 | reject(e); 37 | }; 38 | xhr.send(data); 39 | }); 40 | } 41 | -------------------------------------------------------------------------------- /lib/delete.js: -------------------------------------------------------------------------------- 1 | var btoa = require('btoa'); 2 | if(typeof window != 'undefined') { 3 | XMLHttpRequest = require('xhr2'); 4 | } 5 | 6 | module.exports = function(columnName, value, sheet) { 7 | var config = this.config; 8 | 9 | return new Promise(function(resolve, reject) { 10 | var xhr = new XMLHttpRequest(); 11 | 12 | var sheetParam = (!sheet) ? '' : '?sheet=' + sheet; 13 | 14 | if(!columnName) { 15 | reject('no column name'); 16 | } 17 | 18 | var url = config.address + '/' + columnName + '/' + value + sheetParam; 19 | 20 | xhr.open('DELETE', url, true); 21 | 22 | xhr.setRequestHeader("Accept", "application/vnd.sheetdb.3+json"); 23 | xhr.setRequestHeader("Content-Type", "application/json"); 24 | xhr.setRequestHeader("X-User-Agent", "SheetDB-Node/"+config.version); 25 | 26 | if (config.auth_login && config.auth_password) { 27 | xhr.setRequestHeader("Authorization", "Basic " + btoa(config.auth_login+":"+config.auth_password)); 28 | } 29 | 30 | xhr.onload = function (e) { 31 | if (xhr.readyState === 4) { 32 | resolve(xhr.response); 33 | } 34 | }; 35 | 36 | xhr.onerror = function (e) { 37 | reject(e); 38 | }; 39 | 40 | xhr.send(); 41 | }); 42 | } 43 | -------------------------------------------------------------------------------- /lib/endpoint.js: -------------------------------------------------------------------------------- 1 | var btoa = require('btoa'); 2 | if(typeof window != 'undefined') { 3 | XMLHttpRequest = require('xhr2'); 4 | } 5 | 6 | module.exports = function(endpoint, sheet) { 7 | var config = this.config; 8 | 9 | return new Promise(function(resolve, reject) { 10 | var xhr = new XMLHttpRequest(); 11 | var sheetParam = (!sheet) ? '' : '?sheet=' + sheet; 12 | 13 | var url = config.address + '/' + endpoint + sheetParam; 14 | 15 | xhr.open('GET', url, true); 16 | xhr.setRequestHeader("Accept", "application/vnd.sheetdb.3+json"); 17 | xhr.setRequestHeader("Content-Type", "application/json"); 18 | xhr.setRequestHeader("X-User-Agent", "SheetDB-Node/"+config.version); 19 | 20 | if (config.auth_login && config.auth_password) { 21 | xhr.setRequestHeader("Authorization", "Basic " + btoa(config.auth_login+":"+config.auth_password)); 22 | } 23 | 24 | xhr.onload = function (e) { 25 | if (xhr.readyState === 4) { 26 | resolve(xhr.response); 27 | } 28 | }; 29 | 30 | xhr.onerror = function (e) { 31 | reject(e); 32 | }; 33 | xhr.send(); 34 | }); 35 | } 36 | -------------------------------------------------------------------------------- /lib/isURL.js: -------------------------------------------------------------------------------- 1 | module.exports = function(address) { 2 | var pattern = new RegExp("^https:\/\/"); 3 | var res = pattern.test(address); 4 | 5 | return res; 6 | } 7 | -------------------------------------------------------------------------------- /lib/read.js: -------------------------------------------------------------------------------- 1 | var btoa = require('btoa'); 2 | if(typeof window === 'undefined') { 3 | XMLHttpRequest = require('xhr2'); 4 | } 5 | 6 | module.exports = function(params) { 7 | var config = this.config, 8 | params = params ? params : {}; 9 | 10 | return new Promise(function(resolve, reject) { 11 | 12 | var limit = params.limit, 13 | offset = params.offset, 14 | search = params.search, 15 | sheet = params.sheet, 16 | xhr = new XMLHttpRequest(), 17 | limitSign = (search) ? '&' : '?', 18 | offsetSign = (search || limit) ? '&' : '?', 19 | limitParam = (!limit) ? '' : limitSign + 'limit=' + limit, 20 | offsetParam = (!offset) ? '' : offsetSign + 'offset=' + offset, 21 | sheetParam = (!sheet) ? '' : offsetSign + 'sheet=' + sheet, 22 | searchParam = (!search) ? '' : '/search', 23 | searchKeys = (!search) ? [] : Object.keys(search); 24 | 25 | for (var i = 0; i < searchKeys.length; i++) { 26 | var searchValue = search[searchKeys[i]]; 27 | 28 | if(i === 0){ 29 | searchParam += '?' + searchKeys[i] + '=' + searchValue; 30 | } else { 31 | searchParam += '&' + searchKeys[i] + '=' + searchValue; 32 | } 33 | } 34 | 35 | var url = config.address + searchParam + limitParam + offsetParam + sheetParam; 36 | 37 | xhr.open('GET', url, true); 38 | 39 | xhr.setRequestHeader("Accept", "application/vnd.sheetdb.3+json"); 40 | xhr.setRequestHeader("Content-Type", "application/json"); 41 | xhr.setRequestHeader("X-User-Agent", "SheetDB-Node/"+config.version); 42 | 43 | if (config.auth_login && config.auth_password) { 44 | xhr.setRequestHeader("Authorization", "Basic " + btoa(config.auth_login+":"+config.auth_password)); 45 | } 46 | 47 | xhr.onload = function (e) { 48 | if (xhr.readyState === 4) { 49 | resolve(xhr.response); 50 | } 51 | }; 52 | 53 | xhr.onerror = function (e) { 54 | reject(e); 55 | }; 56 | 57 | xhr.send(); 58 | }); 59 | } 60 | -------------------------------------------------------------------------------- /lib/update.js: -------------------------------------------------------------------------------- 1 | var btoa = require('btoa'); 2 | if(typeof window != 'undefined') { 3 | XMLHttpRequest = require('xhr2'); 4 | } 5 | 6 | module.exports = function(columnName, value, newRow, sheet) { 7 | var config = this.config; 8 | 9 | return new Promise(function(resolve, reject) { 10 | var xhr = new XMLHttpRequest(); 11 | var sheetParam = (!sheet) ? '' : '?sheet=' + sheet; 12 | var data = JSON.stringify({data:newRow}); 13 | 14 | if(!columnName) { 15 | reject('no column name'); 16 | } 17 | 18 | var url = config.address + '/' + columnName + '/' + value + sheetParam; 19 | 20 | xhr.open('PATCH', url, true); 21 | 22 | xhr.setRequestHeader("Accept", "application/vnd.sheetdb.3+json"); 23 | xhr.setRequestHeader("Content-Type", "application/json"); 24 | xhr.setRequestHeader("X-User-Agent", "SheetDB-Node/"+config.version); 25 | 26 | if (config.auth_login && config.auth_password) { 27 | xhr.setRequestHeader("Authorization", "Basic " + btoa(config.auth_login+":"+config.auth_password)); 28 | } 29 | 30 | xhr.onload = function (e) { 31 | if (xhr.readyState === 4) { 32 | resolve(xhr.response); 33 | } 34 | }; 35 | 36 | xhr.onerror = function (e) { 37 | reject(e); 38 | }; 39 | 40 | xhr.send(data); 41 | }); 42 | } 43 | -------------------------------------------------------------------------------- /lib/validAddress.js: -------------------------------------------------------------------------------- 1 | module.exports = function(address) { 2 | var pattern = new RegExp("^https:\/\/sheetdb.io"); 3 | var res = pattern.test(address); 4 | 5 | return res || address.indexOf('http') === -1 ; 6 | } 7 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sheetdb-node", 3 | "version": "0.0.12", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "version": "0.0.12", 9 | "license": "ISC", 10 | "dependencies": { 11 | "btoa": "^1.1.2", 12 | "xhr2": "^0.1.4", 13 | "xmlhttprequest": "^1.8.0" 14 | }, 15 | "devDependencies": { 16 | "mocha": "^8.3.2", 17 | "xhr-mock": "^1.7.0" 18 | }, 19 | "engines": { 20 | "node": "*" 21 | } 22 | }, 23 | "node_modules/@ungap/promise-all-settled": { 24 | "version": "1.1.2", 25 | "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", 26 | "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", 27 | "dev": true 28 | }, 29 | "node_modules/ansi-colors": { 30 | "version": "4.1.1", 31 | "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", 32 | "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", 33 | "dev": true, 34 | "engines": { 35 | "node": ">=6" 36 | } 37 | }, 38 | "node_modules/ansi-regex": { 39 | "version": "3.0.0", 40 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", 41 | "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", 42 | "dev": true, 43 | "engines": { 44 | "node": ">=4" 45 | } 46 | }, 47 | "node_modules/ansi-styles": { 48 | "version": "4.3.0", 49 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 50 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 51 | "dev": true, 52 | "dependencies": { 53 | "color-convert": "^2.0.1" 54 | }, 55 | "engines": { 56 | "node": ">=8" 57 | }, 58 | "funding": { 59 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 60 | } 61 | }, 62 | "node_modules/anymatch": { 63 | "version": "3.1.1", 64 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", 65 | "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", 66 | "dev": true, 67 | "dependencies": { 68 | "normalize-path": "^3.0.0", 69 | "picomatch": "^2.0.4" 70 | }, 71 | "engines": { 72 | "node": ">= 8" 73 | } 74 | }, 75 | "node_modules/argparse": { 76 | "version": "2.0.1", 77 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", 78 | "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", 79 | "dev": true 80 | }, 81 | "node_modules/balanced-match": { 82 | "version": "1.0.0", 83 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 84 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", 85 | "dev": true 86 | }, 87 | "node_modules/binary-extensions": { 88 | "version": "2.2.0", 89 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", 90 | "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", 91 | "dev": true, 92 | "engines": { 93 | "node": ">=8" 94 | } 95 | }, 96 | "node_modules/brace-expansion": { 97 | "version": "1.1.11", 98 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 99 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 100 | "dev": true, 101 | "dependencies": { 102 | "balanced-match": "^1.0.0", 103 | "concat-map": "0.0.1" 104 | } 105 | }, 106 | "node_modules/braces": { 107 | "version": "3.0.2", 108 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", 109 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", 110 | "dev": true, 111 | "dependencies": { 112 | "fill-range": "^7.0.1" 113 | }, 114 | "engines": { 115 | "node": ">=8" 116 | } 117 | }, 118 | "node_modules/browser-stdout": { 119 | "version": "1.3.1", 120 | "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", 121 | "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", 122 | "dev": true 123 | }, 124 | "node_modules/btoa": { 125 | "version": "1.2.1", 126 | "resolved": "https://registry.npmjs.org/btoa/-/btoa-1.2.1.tgz", 127 | "integrity": "sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g==", 128 | "bin": { 129 | "btoa": "bin/btoa.js" 130 | }, 131 | "engines": { 132 | "node": ">= 0.4.0" 133 | } 134 | }, 135 | "node_modules/camelcase": { 136 | "version": "6.2.0", 137 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", 138 | "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", 139 | "dev": true, 140 | "engines": { 141 | "node": ">=10" 142 | }, 143 | "funding": { 144 | "url": "https://github.com/sponsors/sindresorhus" 145 | } 146 | }, 147 | "node_modules/chalk": { 148 | "version": "4.1.0", 149 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", 150 | "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", 151 | "dev": true, 152 | "dependencies": { 153 | "ansi-styles": "^4.1.0", 154 | "supports-color": "^7.1.0" 155 | }, 156 | "engines": { 157 | "node": ">=10" 158 | }, 159 | "funding": { 160 | "url": "https://github.com/chalk/chalk?sponsor=1" 161 | } 162 | }, 163 | "node_modules/chalk/node_modules/supports-color": { 164 | "version": "7.2.0", 165 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 166 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 167 | "dev": true, 168 | "dependencies": { 169 | "has-flag": "^4.0.0" 170 | }, 171 | "engines": { 172 | "node": ">=8" 173 | } 174 | }, 175 | "node_modules/chokidar": { 176 | "version": "3.5.1", 177 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", 178 | "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", 179 | "dev": true, 180 | "dependencies": { 181 | "anymatch": "~3.1.1", 182 | "braces": "~3.0.2", 183 | "fsevents": "~2.3.1", 184 | "glob-parent": "~5.1.0", 185 | "is-binary-path": "~2.1.0", 186 | "is-glob": "~4.0.1", 187 | "normalize-path": "~3.0.0", 188 | "readdirp": "~3.5.0" 189 | }, 190 | "engines": { 191 | "node": ">= 8.10.0" 192 | }, 193 | "optionalDependencies": { 194 | "fsevents": "~2.3.1" 195 | } 196 | }, 197 | "node_modules/cliui": { 198 | "version": "7.0.4", 199 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", 200 | "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", 201 | "dev": true, 202 | "dependencies": { 203 | "string-width": "^4.2.0", 204 | "strip-ansi": "^6.0.0", 205 | "wrap-ansi": "^7.0.0" 206 | } 207 | }, 208 | "node_modules/cliui/node_modules/ansi-regex": { 209 | "version": "5.0.0", 210 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", 211 | "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", 212 | "dev": true, 213 | "engines": { 214 | "node": ">=8" 215 | } 216 | }, 217 | "node_modules/cliui/node_modules/is-fullwidth-code-point": { 218 | "version": "3.0.0", 219 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 220 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", 221 | "dev": true, 222 | "engines": { 223 | "node": ">=8" 224 | } 225 | }, 226 | "node_modules/cliui/node_modules/string-width": { 227 | "version": "4.2.2", 228 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", 229 | "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", 230 | "dev": true, 231 | "dependencies": { 232 | "emoji-regex": "^8.0.0", 233 | "is-fullwidth-code-point": "^3.0.0", 234 | "strip-ansi": "^6.0.0" 235 | }, 236 | "engines": { 237 | "node": ">=8" 238 | } 239 | }, 240 | "node_modules/cliui/node_modules/strip-ansi": { 241 | "version": "6.0.0", 242 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", 243 | "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", 244 | "dev": true, 245 | "dependencies": { 246 | "ansi-regex": "^5.0.0" 247 | }, 248 | "engines": { 249 | "node": ">=8" 250 | } 251 | }, 252 | "node_modules/color-convert": { 253 | "version": "2.0.1", 254 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 255 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 256 | "dev": true, 257 | "dependencies": { 258 | "color-name": "~1.1.4" 259 | }, 260 | "engines": { 261 | "node": ">=7.0.0" 262 | } 263 | }, 264 | "node_modules/color-name": { 265 | "version": "1.1.4", 266 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 267 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 268 | "dev": true 269 | }, 270 | "node_modules/concat-map": { 271 | "version": "0.0.1", 272 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 273 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 274 | "dev": true 275 | }, 276 | "node_modules/debug": { 277 | "version": "4.3.1", 278 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", 279 | "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", 280 | "dev": true, 281 | "dependencies": { 282 | "ms": "2.1.2" 283 | }, 284 | "engines": { 285 | "node": ">=6.0" 286 | }, 287 | "peerDependenciesMeta": { 288 | "supports-color": { 289 | "optional": true 290 | } 291 | } 292 | }, 293 | "node_modules/debug/node_modules/ms": { 294 | "version": "2.1.2", 295 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 296 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 297 | "dev": true 298 | }, 299 | "node_modules/decamelize": { 300 | "version": "4.0.0", 301 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", 302 | "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", 303 | "dev": true, 304 | "engines": { 305 | "node": ">=10" 306 | }, 307 | "funding": { 308 | "url": "https://github.com/sponsors/sindresorhus" 309 | } 310 | }, 311 | "node_modules/diff": { 312 | "version": "5.0.0", 313 | "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", 314 | "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", 315 | "dev": true, 316 | "engines": { 317 | "node": ">=0.3.1" 318 | } 319 | }, 320 | "node_modules/dom-walk": { 321 | "version": "0.1.2", 322 | "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", 323 | "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==", 324 | "dev": true 325 | }, 326 | "node_modules/emoji-regex": { 327 | "version": "8.0.0", 328 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 329 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 330 | "dev": true 331 | }, 332 | "node_modules/escalade": { 333 | "version": "3.1.1", 334 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", 335 | "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", 336 | "dev": true, 337 | "engines": { 338 | "node": ">=6" 339 | } 340 | }, 341 | "node_modules/escape-string-regexp": { 342 | "version": "4.0.0", 343 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", 344 | "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", 345 | "dev": true, 346 | "engines": { 347 | "node": ">=10" 348 | }, 349 | "funding": { 350 | "url": "https://github.com/sponsors/sindresorhus" 351 | } 352 | }, 353 | "node_modules/fill-range": { 354 | "version": "7.0.1", 355 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", 356 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", 357 | "dev": true, 358 | "dependencies": { 359 | "to-regex-range": "^5.0.1" 360 | }, 361 | "engines": { 362 | "node": ">=8" 363 | } 364 | }, 365 | "node_modules/find-up": { 366 | "version": "5.0.0", 367 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", 368 | "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", 369 | "dev": true, 370 | "dependencies": { 371 | "locate-path": "^6.0.0", 372 | "path-exists": "^4.0.0" 373 | }, 374 | "engines": { 375 | "node": ">=10" 376 | }, 377 | "funding": { 378 | "url": "https://github.com/sponsors/sindresorhus" 379 | } 380 | }, 381 | "node_modules/flat": { 382 | "version": "5.0.2", 383 | "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", 384 | "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", 385 | "dev": true, 386 | "bin": { 387 | "flat": "cli.js" 388 | } 389 | }, 390 | "node_modules/fs.realpath": { 391 | "version": "1.0.0", 392 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 393 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 394 | "dev": true 395 | }, 396 | "node_modules/fsevents": { 397 | "version": "2.3.2", 398 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 399 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 400 | "dev": true, 401 | "hasInstallScript": true, 402 | "optional": true, 403 | "os": [ 404 | "darwin" 405 | ], 406 | "engines": { 407 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 408 | } 409 | }, 410 | "node_modules/get-caller-file": { 411 | "version": "2.0.5", 412 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", 413 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", 414 | "dev": true, 415 | "engines": { 416 | "node": "6.* || 8.* || >= 10.*" 417 | } 418 | }, 419 | "node_modules/glob": { 420 | "version": "7.1.6", 421 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", 422 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", 423 | "dev": true, 424 | "dependencies": { 425 | "fs.realpath": "^1.0.0", 426 | "inflight": "^1.0.4", 427 | "inherits": "2", 428 | "minimatch": "^3.0.4", 429 | "once": "^1.3.0", 430 | "path-is-absolute": "^1.0.0" 431 | }, 432 | "engines": { 433 | "node": "*" 434 | }, 435 | "funding": { 436 | "url": "https://github.com/sponsors/isaacs" 437 | } 438 | }, 439 | "node_modules/glob-parent": { 440 | "version": "5.1.2", 441 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 442 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 443 | "dev": true, 444 | "dependencies": { 445 | "is-glob": "^4.0.1" 446 | }, 447 | "engines": { 448 | "node": ">= 6" 449 | } 450 | }, 451 | "node_modules/global": { 452 | "version": "4.4.0", 453 | "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", 454 | "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", 455 | "dev": true, 456 | "dependencies": { 457 | "min-document": "^2.19.0", 458 | "process": "^0.11.10" 459 | } 460 | }, 461 | "node_modules/growl": { 462 | "version": "1.10.5", 463 | "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", 464 | "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", 465 | "dev": true, 466 | "engines": { 467 | "node": ">=4.x" 468 | } 469 | }, 470 | "node_modules/has-flag": { 471 | "version": "4.0.0", 472 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 473 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 474 | "dev": true, 475 | "engines": { 476 | "node": ">=8" 477 | } 478 | }, 479 | "node_modules/he": { 480 | "version": "1.2.0", 481 | "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", 482 | "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", 483 | "dev": true, 484 | "bin": { 485 | "he": "bin/he" 486 | } 487 | }, 488 | "node_modules/inflight": { 489 | "version": "1.0.6", 490 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 491 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 492 | "dev": true, 493 | "dependencies": { 494 | "once": "^1.3.0", 495 | "wrappy": "1" 496 | } 497 | }, 498 | "node_modules/inherits": { 499 | "version": "2.0.4", 500 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 501 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 502 | "dev": true 503 | }, 504 | "node_modules/is-binary-path": { 505 | "version": "2.1.0", 506 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", 507 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", 508 | "dev": true, 509 | "dependencies": { 510 | "binary-extensions": "^2.0.0" 511 | }, 512 | "engines": { 513 | "node": ">=8" 514 | } 515 | }, 516 | "node_modules/is-extglob": { 517 | "version": "2.1.1", 518 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 519 | "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", 520 | "dev": true, 521 | "engines": { 522 | "node": ">=0.10.0" 523 | } 524 | }, 525 | "node_modules/is-fullwidth-code-point": { 526 | "version": "2.0.0", 527 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 528 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", 529 | "dev": true, 530 | "engines": { 531 | "node": ">=4" 532 | } 533 | }, 534 | "node_modules/is-glob": { 535 | "version": "4.0.1", 536 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", 537 | "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", 538 | "dev": true, 539 | "dependencies": { 540 | "is-extglob": "^2.1.1" 541 | }, 542 | "engines": { 543 | "node": ">=0.10.0" 544 | } 545 | }, 546 | "node_modules/is-number": { 547 | "version": "7.0.0", 548 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 549 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 550 | "dev": true, 551 | "engines": { 552 | "node": ">=0.12.0" 553 | } 554 | }, 555 | "node_modules/is-plain-obj": { 556 | "version": "2.1.0", 557 | "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", 558 | "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", 559 | "dev": true, 560 | "engines": { 561 | "node": ">=8" 562 | } 563 | }, 564 | "node_modules/isexe": { 565 | "version": "2.0.0", 566 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 567 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", 568 | "dev": true 569 | }, 570 | "node_modules/js-yaml": { 571 | "version": "4.0.0", 572 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", 573 | "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", 574 | "dev": true, 575 | "dependencies": { 576 | "argparse": "^2.0.1" 577 | }, 578 | "bin": { 579 | "js-yaml": "bin/js-yaml.js" 580 | } 581 | }, 582 | "node_modules/locate-path": { 583 | "version": "6.0.0", 584 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", 585 | "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", 586 | "dev": true, 587 | "dependencies": { 588 | "p-locate": "^5.0.0" 589 | }, 590 | "engines": { 591 | "node": ">=10" 592 | }, 593 | "funding": { 594 | "url": "https://github.com/sponsors/sindresorhus" 595 | } 596 | }, 597 | "node_modules/log-symbols": { 598 | "version": "4.0.0", 599 | "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", 600 | "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", 601 | "dev": true, 602 | "dependencies": { 603 | "chalk": "^4.0.0" 604 | }, 605 | "engines": { 606 | "node": ">=10" 607 | } 608 | }, 609 | "node_modules/min-document": { 610 | "version": "2.19.0", 611 | "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", 612 | "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", 613 | "dev": true, 614 | "dependencies": { 615 | "dom-walk": "^0.1.0" 616 | } 617 | }, 618 | "node_modules/minimatch": { 619 | "version": "3.0.4", 620 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 621 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 622 | "dev": true, 623 | "dependencies": { 624 | "brace-expansion": "^1.1.7" 625 | }, 626 | "engines": { 627 | "node": "*" 628 | } 629 | }, 630 | "node_modules/mocha": { 631 | "version": "8.3.2", 632 | "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.3.2.tgz", 633 | "integrity": "sha512-UdmISwr/5w+uXLPKspgoV7/RXZwKRTiTjJ2/AC5ZiEztIoOYdfKb19+9jNmEInzx5pBsCyJQzarAxqIGBNYJhg==", 634 | "dev": true, 635 | "dependencies": { 636 | "@ungap/promise-all-settled": "1.1.2", 637 | "ansi-colors": "4.1.1", 638 | "browser-stdout": "1.3.1", 639 | "chokidar": "3.5.1", 640 | "debug": "4.3.1", 641 | "diff": "5.0.0", 642 | "escape-string-regexp": "4.0.0", 643 | "find-up": "5.0.0", 644 | "glob": "7.1.6", 645 | "growl": "1.10.5", 646 | "he": "1.2.0", 647 | "js-yaml": "4.0.0", 648 | "log-symbols": "4.0.0", 649 | "minimatch": "3.0.4", 650 | "ms": "2.1.3", 651 | "nanoid": "3.1.20", 652 | "serialize-javascript": "5.0.1", 653 | "strip-json-comments": "3.1.1", 654 | "supports-color": "8.1.1", 655 | "which": "2.0.2", 656 | "wide-align": "1.1.3", 657 | "workerpool": "6.1.0", 658 | "yargs": "16.2.0", 659 | "yargs-parser": "20.2.4", 660 | "yargs-unparser": "2.0.0" 661 | }, 662 | "bin": { 663 | "_mocha": "bin/_mocha", 664 | "mocha": "bin/mocha" 665 | }, 666 | "engines": { 667 | "node": ">= 10.12.0" 668 | }, 669 | "funding": { 670 | "type": "opencollective", 671 | "url": "https://opencollective.com/mochajs" 672 | } 673 | }, 674 | "node_modules/ms": { 675 | "version": "2.1.3", 676 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 677 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 678 | "dev": true 679 | }, 680 | "node_modules/nanoid": { 681 | "version": "3.1.20", 682 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", 683 | "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==", 684 | "dev": true, 685 | "bin": { 686 | "nanoid": "bin/nanoid.cjs" 687 | }, 688 | "engines": { 689 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" 690 | } 691 | }, 692 | "node_modules/normalize-path": { 693 | "version": "3.0.0", 694 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", 695 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", 696 | "dev": true, 697 | "engines": { 698 | "node": ">=0.10.0" 699 | } 700 | }, 701 | "node_modules/once": { 702 | "version": "1.4.0", 703 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 704 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 705 | "dev": true, 706 | "dependencies": { 707 | "wrappy": "1" 708 | } 709 | }, 710 | "node_modules/p-limit": { 711 | "version": "3.1.0", 712 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", 713 | "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", 714 | "dev": true, 715 | "dependencies": { 716 | "yocto-queue": "^0.1.0" 717 | }, 718 | "engines": { 719 | "node": ">=10" 720 | }, 721 | "funding": { 722 | "url": "https://github.com/sponsors/sindresorhus" 723 | } 724 | }, 725 | "node_modules/p-locate": { 726 | "version": "5.0.0", 727 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", 728 | "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", 729 | "dev": true, 730 | "dependencies": { 731 | "p-limit": "^3.0.2" 732 | }, 733 | "engines": { 734 | "node": ">=10" 735 | }, 736 | "funding": { 737 | "url": "https://github.com/sponsors/sindresorhus" 738 | } 739 | }, 740 | "node_modules/path-exists": { 741 | "version": "4.0.0", 742 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", 743 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", 744 | "dev": true, 745 | "engines": { 746 | "node": ">=8" 747 | } 748 | }, 749 | "node_modules/path-is-absolute": { 750 | "version": "1.0.1", 751 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 752 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 753 | "dev": true, 754 | "engines": { 755 | "node": ">=0.10.0" 756 | } 757 | }, 758 | "node_modules/picomatch": { 759 | "version": "2.2.2", 760 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", 761 | "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", 762 | "dev": true, 763 | "engines": { 764 | "node": ">=8.6" 765 | }, 766 | "funding": { 767 | "url": "https://github.com/sponsors/jonschlinkert" 768 | } 769 | }, 770 | "node_modules/process": { 771 | "version": "0.11.10", 772 | "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", 773 | "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", 774 | "dev": true, 775 | "engines": { 776 | "node": ">= 0.6.0" 777 | } 778 | }, 779 | "node_modules/querystringify": { 780 | "version": "2.2.0", 781 | "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", 782 | "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", 783 | "dev": true 784 | }, 785 | "node_modules/randombytes": { 786 | "version": "2.1.0", 787 | "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", 788 | "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", 789 | "dev": true, 790 | "dependencies": { 791 | "safe-buffer": "^5.1.0" 792 | } 793 | }, 794 | "node_modules/readdirp": { 795 | "version": "3.5.0", 796 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", 797 | "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", 798 | "dev": true, 799 | "dependencies": { 800 | "picomatch": "^2.2.1" 801 | }, 802 | "engines": { 803 | "node": ">=8.10.0" 804 | } 805 | }, 806 | "node_modules/require-directory": { 807 | "version": "2.1.1", 808 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", 809 | "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", 810 | "dev": true, 811 | "engines": { 812 | "node": ">=0.10.0" 813 | } 814 | }, 815 | "node_modules/requires-port": { 816 | "version": "1.0.0", 817 | "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", 818 | "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", 819 | "dev": true 820 | }, 821 | "node_modules/safe-buffer": { 822 | "version": "5.2.1", 823 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 824 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 825 | "dev": true, 826 | "funding": [ 827 | { 828 | "type": "github", 829 | "url": "https://github.com/sponsors/feross" 830 | }, 831 | { 832 | "type": "patreon", 833 | "url": "https://www.patreon.com/feross" 834 | }, 835 | { 836 | "type": "consulting", 837 | "url": "https://feross.org/support" 838 | } 839 | ] 840 | }, 841 | "node_modules/serialize-javascript": { 842 | "version": "5.0.1", 843 | "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", 844 | "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", 845 | "dev": true, 846 | "dependencies": { 847 | "randombytes": "^2.1.0" 848 | } 849 | }, 850 | "node_modules/string-width": { 851 | "version": "2.1.1", 852 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", 853 | "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", 854 | "dev": true, 855 | "dependencies": { 856 | "is-fullwidth-code-point": "^2.0.0", 857 | "strip-ansi": "^4.0.0" 858 | }, 859 | "engines": { 860 | "node": ">=4" 861 | } 862 | }, 863 | "node_modules/strip-ansi": { 864 | "version": "4.0.0", 865 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", 866 | "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", 867 | "dev": true, 868 | "dependencies": { 869 | "ansi-regex": "^3.0.0" 870 | }, 871 | "engines": { 872 | "node": ">=4" 873 | } 874 | }, 875 | "node_modules/strip-json-comments": { 876 | "version": "3.1.1", 877 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", 878 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", 879 | "dev": true, 880 | "engines": { 881 | "node": ">=8" 882 | }, 883 | "funding": { 884 | "url": "https://github.com/sponsors/sindresorhus" 885 | } 886 | }, 887 | "node_modules/supports-color": { 888 | "version": "8.1.1", 889 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", 890 | "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", 891 | "dev": true, 892 | "dependencies": { 893 | "has-flag": "^4.0.0" 894 | }, 895 | "engines": { 896 | "node": ">=10" 897 | }, 898 | "funding": { 899 | "url": "https://github.com/chalk/supports-color?sponsor=1" 900 | } 901 | }, 902 | "node_modules/to-regex-range": { 903 | "version": "5.0.1", 904 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 905 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 906 | "dev": true, 907 | "dependencies": { 908 | "is-number": "^7.0.0" 909 | }, 910 | "engines": { 911 | "node": ">=8.0" 912 | } 913 | }, 914 | "node_modules/url-parse": { 915 | "version": "1.5.1", 916 | "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.1.tgz", 917 | "integrity": "sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q==", 918 | "dev": true, 919 | "dependencies": { 920 | "querystringify": "^2.1.1", 921 | "requires-port": "^1.0.0" 922 | } 923 | }, 924 | "node_modules/which": { 925 | "version": "2.0.2", 926 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 927 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 928 | "dev": true, 929 | "dependencies": { 930 | "isexe": "^2.0.0" 931 | }, 932 | "bin": { 933 | "node-which": "bin/node-which" 934 | }, 935 | "engines": { 936 | "node": ">= 8" 937 | } 938 | }, 939 | "node_modules/wide-align": { 940 | "version": "1.1.3", 941 | "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", 942 | "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", 943 | "dev": true, 944 | "dependencies": { 945 | "string-width": "^1.0.2 || 2" 946 | } 947 | }, 948 | "node_modules/workerpool": { 949 | "version": "6.1.0", 950 | "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz", 951 | "integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==", 952 | "dev": true 953 | }, 954 | "node_modules/wrap-ansi": { 955 | "version": "7.0.0", 956 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", 957 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", 958 | "dev": true, 959 | "dependencies": { 960 | "ansi-styles": "^4.0.0", 961 | "string-width": "^4.1.0", 962 | "strip-ansi": "^6.0.0" 963 | }, 964 | "engines": { 965 | "node": ">=10" 966 | }, 967 | "funding": { 968 | "url": "https://github.com/chalk/wrap-ansi?sponsor=1" 969 | } 970 | }, 971 | "node_modules/wrap-ansi/node_modules/ansi-regex": { 972 | "version": "5.0.0", 973 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", 974 | "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", 975 | "dev": true, 976 | "engines": { 977 | "node": ">=8" 978 | } 979 | }, 980 | "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { 981 | "version": "3.0.0", 982 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 983 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", 984 | "dev": true, 985 | "engines": { 986 | "node": ">=8" 987 | } 988 | }, 989 | "node_modules/wrap-ansi/node_modules/string-width": { 990 | "version": "4.2.2", 991 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", 992 | "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", 993 | "dev": true, 994 | "dependencies": { 995 | "emoji-regex": "^8.0.0", 996 | "is-fullwidth-code-point": "^3.0.0", 997 | "strip-ansi": "^6.0.0" 998 | }, 999 | "engines": { 1000 | "node": ">=8" 1001 | } 1002 | }, 1003 | "node_modules/wrap-ansi/node_modules/strip-ansi": { 1004 | "version": "6.0.0", 1005 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", 1006 | "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", 1007 | "dev": true, 1008 | "dependencies": { 1009 | "ansi-regex": "^5.0.0" 1010 | }, 1011 | "engines": { 1012 | "node": ">=8" 1013 | } 1014 | }, 1015 | "node_modules/wrappy": { 1016 | "version": "1.0.2", 1017 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1018 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 1019 | "dev": true 1020 | }, 1021 | "node_modules/xhr-mock": { 1022 | "version": "1.9.1", 1023 | "resolved": "https://registry.npmjs.org/xhr-mock/-/xhr-mock-1.9.1.tgz", 1024 | "integrity": "sha1-UmMpC+UvAvUrwcVqis+mh58ocUA=", 1025 | "dev": true, 1026 | "dependencies": { 1027 | "global": "^4.3.0", 1028 | "url-parse": "^1.1.7" 1029 | } 1030 | }, 1031 | "node_modules/xhr2": { 1032 | "version": "0.1.4", 1033 | "resolved": "https://registry.npmjs.org/xhr2/-/xhr2-0.1.4.tgz", 1034 | "integrity": "sha1-f4dliEdxbbUCYyOBL4GMras4el8=", 1035 | "engines": { 1036 | "node": ">= 0.6" 1037 | } 1038 | }, 1039 | "node_modules/xmlhttprequest": { 1040 | "version": "1.8.0", 1041 | "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", 1042 | "integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=", 1043 | "engines": { 1044 | "node": ">=0.4.0" 1045 | } 1046 | }, 1047 | "node_modules/y18n": { 1048 | "version": "5.0.5", 1049 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz", 1050 | "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==", 1051 | "dev": true, 1052 | "engines": { 1053 | "node": ">=10" 1054 | } 1055 | }, 1056 | "node_modules/yargs": { 1057 | "version": "16.2.0", 1058 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", 1059 | "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", 1060 | "dev": true, 1061 | "dependencies": { 1062 | "cliui": "^7.0.2", 1063 | "escalade": "^3.1.1", 1064 | "get-caller-file": "^2.0.5", 1065 | "require-directory": "^2.1.1", 1066 | "string-width": "^4.2.0", 1067 | "y18n": "^5.0.5", 1068 | "yargs-parser": "^20.2.2" 1069 | }, 1070 | "engines": { 1071 | "node": ">=10" 1072 | } 1073 | }, 1074 | "node_modules/yargs-parser": { 1075 | "version": "20.2.4", 1076 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", 1077 | "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", 1078 | "dev": true, 1079 | "engines": { 1080 | "node": ">=10" 1081 | } 1082 | }, 1083 | "node_modules/yargs-unparser": { 1084 | "version": "2.0.0", 1085 | "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", 1086 | "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", 1087 | "dev": true, 1088 | "dependencies": { 1089 | "camelcase": "^6.0.0", 1090 | "decamelize": "^4.0.0", 1091 | "flat": "^5.0.2", 1092 | "is-plain-obj": "^2.1.0" 1093 | }, 1094 | "engines": { 1095 | "node": ">=10" 1096 | } 1097 | }, 1098 | "node_modules/yargs/node_modules/ansi-regex": { 1099 | "version": "5.0.0", 1100 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", 1101 | "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", 1102 | "dev": true, 1103 | "engines": { 1104 | "node": ">=8" 1105 | } 1106 | }, 1107 | "node_modules/yargs/node_modules/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 | "engines": { 1113 | "node": ">=8" 1114 | } 1115 | }, 1116 | "node_modules/yargs/node_modules/string-width": { 1117 | "version": "4.2.2", 1118 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", 1119 | "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", 1120 | "dev": true, 1121 | "dependencies": { 1122 | "emoji-regex": "^8.0.0", 1123 | "is-fullwidth-code-point": "^3.0.0", 1124 | "strip-ansi": "^6.0.0" 1125 | }, 1126 | "engines": { 1127 | "node": ">=8" 1128 | } 1129 | }, 1130 | "node_modules/yargs/node_modules/strip-ansi": { 1131 | "version": "6.0.0", 1132 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", 1133 | "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", 1134 | "dev": true, 1135 | "dependencies": { 1136 | "ansi-regex": "^5.0.0" 1137 | }, 1138 | "engines": { 1139 | "node": ">=8" 1140 | } 1141 | }, 1142 | "node_modules/yocto-queue": { 1143 | "version": "0.1.0", 1144 | "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", 1145 | "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", 1146 | "dev": true, 1147 | "engines": { 1148 | "node": ">=10" 1149 | }, 1150 | "funding": { 1151 | "url": "https://github.com/sponsors/sindresorhus" 1152 | } 1153 | } 1154 | }, 1155 | "dependencies": { 1156 | "@ungap/promise-all-settled": { 1157 | "version": "1.1.2", 1158 | "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", 1159 | "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", 1160 | "dev": true 1161 | }, 1162 | "ansi-colors": { 1163 | "version": "4.1.1", 1164 | "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", 1165 | "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", 1166 | "dev": true 1167 | }, 1168 | "ansi-regex": { 1169 | "version": "3.0.0", 1170 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", 1171 | "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", 1172 | "dev": true 1173 | }, 1174 | "ansi-styles": { 1175 | "version": "4.3.0", 1176 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 1177 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 1178 | "dev": true, 1179 | "requires": { 1180 | "color-convert": "^2.0.1" 1181 | } 1182 | }, 1183 | "anymatch": { 1184 | "version": "3.1.1", 1185 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", 1186 | "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", 1187 | "dev": true, 1188 | "requires": { 1189 | "normalize-path": "^3.0.0", 1190 | "picomatch": "^2.0.4" 1191 | } 1192 | }, 1193 | "argparse": { 1194 | "version": "2.0.1", 1195 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", 1196 | "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", 1197 | "dev": true 1198 | }, 1199 | "balanced-match": { 1200 | "version": "1.0.0", 1201 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 1202 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", 1203 | "dev": true 1204 | }, 1205 | "binary-extensions": { 1206 | "version": "2.2.0", 1207 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", 1208 | "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", 1209 | "dev": true 1210 | }, 1211 | "brace-expansion": { 1212 | "version": "1.1.11", 1213 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 1214 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 1215 | "dev": true, 1216 | "requires": { 1217 | "balanced-match": "^1.0.0", 1218 | "concat-map": "0.0.1" 1219 | } 1220 | }, 1221 | "braces": { 1222 | "version": "3.0.2", 1223 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", 1224 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", 1225 | "dev": true, 1226 | "requires": { 1227 | "fill-range": "^7.0.1" 1228 | } 1229 | }, 1230 | "browser-stdout": { 1231 | "version": "1.3.1", 1232 | "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", 1233 | "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", 1234 | "dev": true 1235 | }, 1236 | "btoa": { 1237 | "version": "1.2.1", 1238 | "resolved": "https://registry.npmjs.org/btoa/-/btoa-1.2.1.tgz", 1239 | "integrity": "sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g==" 1240 | }, 1241 | "camelcase": { 1242 | "version": "6.2.0", 1243 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", 1244 | "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", 1245 | "dev": true 1246 | }, 1247 | "chalk": { 1248 | "version": "4.1.0", 1249 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", 1250 | "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", 1251 | "dev": true, 1252 | "requires": { 1253 | "ansi-styles": "^4.1.0", 1254 | "supports-color": "^7.1.0" 1255 | }, 1256 | "dependencies": { 1257 | "supports-color": { 1258 | "version": "7.2.0", 1259 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 1260 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 1261 | "dev": true, 1262 | "requires": { 1263 | "has-flag": "^4.0.0" 1264 | } 1265 | } 1266 | } 1267 | }, 1268 | "chokidar": { 1269 | "version": "3.5.1", 1270 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", 1271 | "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", 1272 | "dev": true, 1273 | "requires": { 1274 | "anymatch": "~3.1.1", 1275 | "braces": "~3.0.2", 1276 | "fsevents": "~2.3.1", 1277 | "glob-parent": "~5.1.0", 1278 | "is-binary-path": "~2.1.0", 1279 | "is-glob": "~4.0.1", 1280 | "normalize-path": "~3.0.0", 1281 | "readdirp": "~3.5.0" 1282 | } 1283 | }, 1284 | "cliui": { 1285 | "version": "7.0.4", 1286 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", 1287 | "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", 1288 | "dev": true, 1289 | "requires": { 1290 | "string-width": "^4.2.0", 1291 | "strip-ansi": "^6.0.0", 1292 | "wrap-ansi": "^7.0.0" 1293 | }, 1294 | "dependencies": { 1295 | "ansi-regex": { 1296 | "version": "5.0.0", 1297 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", 1298 | "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", 1299 | "dev": true 1300 | }, 1301 | "is-fullwidth-code-point": { 1302 | "version": "3.0.0", 1303 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 1304 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", 1305 | "dev": true 1306 | }, 1307 | "string-width": { 1308 | "version": "4.2.2", 1309 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", 1310 | "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", 1311 | "dev": true, 1312 | "requires": { 1313 | "emoji-regex": "^8.0.0", 1314 | "is-fullwidth-code-point": "^3.0.0", 1315 | "strip-ansi": "^6.0.0" 1316 | } 1317 | }, 1318 | "strip-ansi": { 1319 | "version": "6.0.0", 1320 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", 1321 | "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", 1322 | "dev": true, 1323 | "requires": { 1324 | "ansi-regex": "^5.0.0" 1325 | } 1326 | } 1327 | } 1328 | }, 1329 | "color-convert": { 1330 | "version": "2.0.1", 1331 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 1332 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 1333 | "dev": true, 1334 | "requires": { 1335 | "color-name": "~1.1.4" 1336 | } 1337 | }, 1338 | "color-name": { 1339 | "version": "1.1.4", 1340 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 1341 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 1342 | "dev": true 1343 | }, 1344 | "concat-map": { 1345 | "version": "0.0.1", 1346 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 1347 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 1348 | "dev": true 1349 | }, 1350 | "debug": { 1351 | "version": "4.3.1", 1352 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", 1353 | "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", 1354 | "dev": true, 1355 | "requires": { 1356 | "ms": "2.1.2" 1357 | }, 1358 | "dependencies": { 1359 | "ms": { 1360 | "version": "2.1.2", 1361 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 1362 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 1363 | "dev": true 1364 | } 1365 | } 1366 | }, 1367 | "decamelize": { 1368 | "version": "4.0.0", 1369 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", 1370 | "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", 1371 | "dev": true 1372 | }, 1373 | "diff": { 1374 | "version": "5.0.0", 1375 | "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", 1376 | "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", 1377 | "dev": true 1378 | }, 1379 | "dom-walk": { 1380 | "version": "0.1.2", 1381 | "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", 1382 | "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==", 1383 | "dev": true 1384 | }, 1385 | "emoji-regex": { 1386 | "version": "8.0.0", 1387 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 1388 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 1389 | "dev": true 1390 | }, 1391 | "escalade": { 1392 | "version": "3.1.1", 1393 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", 1394 | "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", 1395 | "dev": true 1396 | }, 1397 | "escape-string-regexp": { 1398 | "version": "4.0.0", 1399 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", 1400 | "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", 1401 | "dev": true 1402 | }, 1403 | "fill-range": { 1404 | "version": "7.0.1", 1405 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", 1406 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", 1407 | "dev": true, 1408 | "requires": { 1409 | "to-regex-range": "^5.0.1" 1410 | } 1411 | }, 1412 | "find-up": { 1413 | "version": "5.0.0", 1414 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", 1415 | "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", 1416 | "dev": true, 1417 | "requires": { 1418 | "locate-path": "^6.0.0", 1419 | "path-exists": "^4.0.0" 1420 | } 1421 | }, 1422 | "flat": { 1423 | "version": "5.0.2", 1424 | "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", 1425 | "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", 1426 | "dev": true 1427 | }, 1428 | "fs.realpath": { 1429 | "version": "1.0.0", 1430 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 1431 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 1432 | "dev": true 1433 | }, 1434 | "fsevents": { 1435 | "version": "2.3.2", 1436 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 1437 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 1438 | "dev": true, 1439 | "optional": true 1440 | }, 1441 | "get-caller-file": { 1442 | "version": "2.0.5", 1443 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", 1444 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", 1445 | "dev": true 1446 | }, 1447 | "glob": { 1448 | "version": "7.1.6", 1449 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", 1450 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", 1451 | "dev": true, 1452 | "requires": { 1453 | "fs.realpath": "^1.0.0", 1454 | "inflight": "^1.0.4", 1455 | "inherits": "2", 1456 | "minimatch": "^3.0.4", 1457 | "once": "^1.3.0", 1458 | "path-is-absolute": "^1.0.0" 1459 | } 1460 | }, 1461 | "glob-parent": { 1462 | "version": "5.1.2", 1463 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 1464 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 1465 | "dev": true, 1466 | "requires": { 1467 | "is-glob": "^4.0.1" 1468 | } 1469 | }, 1470 | "global": { 1471 | "version": "4.4.0", 1472 | "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", 1473 | "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", 1474 | "dev": true, 1475 | "requires": { 1476 | "min-document": "^2.19.0", 1477 | "process": "^0.11.10" 1478 | } 1479 | }, 1480 | "growl": { 1481 | "version": "1.10.5", 1482 | "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", 1483 | "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", 1484 | "dev": true 1485 | }, 1486 | "has-flag": { 1487 | "version": "4.0.0", 1488 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 1489 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 1490 | "dev": true 1491 | }, 1492 | "he": { 1493 | "version": "1.2.0", 1494 | "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", 1495 | "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", 1496 | "dev": true 1497 | }, 1498 | "inflight": { 1499 | "version": "1.0.6", 1500 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 1501 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 1502 | "dev": true, 1503 | "requires": { 1504 | "once": "^1.3.0", 1505 | "wrappy": "1" 1506 | } 1507 | }, 1508 | "inherits": { 1509 | "version": "2.0.4", 1510 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 1511 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 1512 | "dev": true 1513 | }, 1514 | "is-binary-path": { 1515 | "version": "2.1.0", 1516 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", 1517 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", 1518 | "dev": true, 1519 | "requires": { 1520 | "binary-extensions": "^2.0.0" 1521 | } 1522 | }, 1523 | "is-extglob": { 1524 | "version": "2.1.1", 1525 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 1526 | "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", 1527 | "dev": true 1528 | }, 1529 | "is-fullwidth-code-point": { 1530 | "version": "2.0.0", 1531 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 1532 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", 1533 | "dev": true 1534 | }, 1535 | "is-glob": { 1536 | "version": "4.0.1", 1537 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", 1538 | "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", 1539 | "dev": true, 1540 | "requires": { 1541 | "is-extglob": "^2.1.1" 1542 | } 1543 | }, 1544 | "is-number": { 1545 | "version": "7.0.0", 1546 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 1547 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 1548 | "dev": true 1549 | }, 1550 | "is-plain-obj": { 1551 | "version": "2.1.0", 1552 | "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", 1553 | "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", 1554 | "dev": true 1555 | }, 1556 | "isexe": { 1557 | "version": "2.0.0", 1558 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 1559 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", 1560 | "dev": true 1561 | }, 1562 | "js-yaml": { 1563 | "version": "4.0.0", 1564 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", 1565 | "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", 1566 | "dev": true, 1567 | "requires": { 1568 | "argparse": "^2.0.1" 1569 | } 1570 | }, 1571 | "locate-path": { 1572 | "version": "6.0.0", 1573 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", 1574 | "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", 1575 | "dev": true, 1576 | "requires": { 1577 | "p-locate": "^5.0.0" 1578 | } 1579 | }, 1580 | "log-symbols": { 1581 | "version": "4.0.0", 1582 | "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", 1583 | "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", 1584 | "dev": true, 1585 | "requires": { 1586 | "chalk": "^4.0.0" 1587 | } 1588 | }, 1589 | "min-document": { 1590 | "version": "2.19.0", 1591 | "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", 1592 | "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", 1593 | "dev": true, 1594 | "requires": { 1595 | "dom-walk": "^0.1.0" 1596 | } 1597 | }, 1598 | "minimatch": { 1599 | "version": "3.0.4", 1600 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 1601 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 1602 | "dev": true, 1603 | "requires": { 1604 | "brace-expansion": "^1.1.7" 1605 | } 1606 | }, 1607 | "mocha": { 1608 | "version": "8.3.2", 1609 | "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.3.2.tgz", 1610 | "integrity": "sha512-UdmISwr/5w+uXLPKspgoV7/RXZwKRTiTjJ2/AC5ZiEztIoOYdfKb19+9jNmEInzx5pBsCyJQzarAxqIGBNYJhg==", 1611 | "dev": true, 1612 | "requires": { 1613 | "@ungap/promise-all-settled": "1.1.2", 1614 | "ansi-colors": "4.1.1", 1615 | "browser-stdout": "1.3.1", 1616 | "chokidar": "3.5.1", 1617 | "debug": "4.3.1", 1618 | "diff": "5.0.0", 1619 | "escape-string-regexp": "4.0.0", 1620 | "find-up": "5.0.0", 1621 | "glob": "7.1.6", 1622 | "growl": "1.10.5", 1623 | "he": "1.2.0", 1624 | "js-yaml": "4.0.0", 1625 | "log-symbols": "4.0.0", 1626 | "minimatch": "3.0.4", 1627 | "ms": "2.1.3", 1628 | "nanoid": "3.1.20", 1629 | "serialize-javascript": "5.0.1", 1630 | "strip-json-comments": "3.1.1", 1631 | "supports-color": "8.1.1", 1632 | "which": "2.0.2", 1633 | "wide-align": "1.1.3", 1634 | "workerpool": "6.1.0", 1635 | "yargs": "16.2.0", 1636 | "yargs-parser": "20.2.4", 1637 | "yargs-unparser": "2.0.0" 1638 | } 1639 | }, 1640 | "ms": { 1641 | "version": "2.1.3", 1642 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 1643 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 1644 | "dev": true 1645 | }, 1646 | "nanoid": { 1647 | "version": "3.1.20", 1648 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", 1649 | "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==", 1650 | "dev": true 1651 | }, 1652 | "normalize-path": { 1653 | "version": "3.0.0", 1654 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", 1655 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", 1656 | "dev": true 1657 | }, 1658 | "once": { 1659 | "version": "1.4.0", 1660 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1661 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 1662 | "dev": true, 1663 | "requires": { 1664 | "wrappy": "1" 1665 | } 1666 | }, 1667 | "p-limit": { 1668 | "version": "3.1.0", 1669 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", 1670 | "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", 1671 | "dev": true, 1672 | "requires": { 1673 | "yocto-queue": "^0.1.0" 1674 | } 1675 | }, 1676 | "p-locate": { 1677 | "version": "5.0.0", 1678 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", 1679 | "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", 1680 | "dev": true, 1681 | "requires": { 1682 | "p-limit": "^3.0.2" 1683 | } 1684 | }, 1685 | "path-exists": { 1686 | "version": "4.0.0", 1687 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", 1688 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", 1689 | "dev": true 1690 | }, 1691 | "path-is-absolute": { 1692 | "version": "1.0.1", 1693 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 1694 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 1695 | "dev": true 1696 | }, 1697 | "picomatch": { 1698 | "version": "2.2.2", 1699 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", 1700 | "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", 1701 | "dev": true 1702 | }, 1703 | "process": { 1704 | "version": "0.11.10", 1705 | "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", 1706 | "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", 1707 | "dev": true 1708 | }, 1709 | "querystringify": { 1710 | "version": "2.2.0", 1711 | "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", 1712 | "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", 1713 | "dev": true 1714 | }, 1715 | "randombytes": { 1716 | "version": "2.1.0", 1717 | "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", 1718 | "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", 1719 | "dev": true, 1720 | "requires": { 1721 | "safe-buffer": "^5.1.0" 1722 | } 1723 | }, 1724 | "readdirp": { 1725 | "version": "3.5.0", 1726 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", 1727 | "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", 1728 | "dev": true, 1729 | "requires": { 1730 | "picomatch": "^2.2.1" 1731 | } 1732 | }, 1733 | "require-directory": { 1734 | "version": "2.1.1", 1735 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", 1736 | "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", 1737 | "dev": true 1738 | }, 1739 | "requires-port": { 1740 | "version": "1.0.0", 1741 | "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", 1742 | "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", 1743 | "dev": true 1744 | }, 1745 | "safe-buffer": { 1746 | "version": "5.2.1", 1747 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 1748 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 1749 | "dev": true 1750 | }, 1751 | "serialize-javascript": { 1752 | "version": "5.0.1", 1753 | "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", 1754 | "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", 1755 | "dev": true, 1756 | "requires": { 1757 | "randombytes": "^2.1.0" 1758 | } 1759 | }, 1760 | "string-width": { 1761 | "version": "2.1.1", 1762 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", 1763 | "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", 1764 | "dev": true, 1765 | "requires": { 1766 | "is-fullwidth-code-point": "^2.0.0", 1767 | "strip-ansi": "^4.0.0" 1768 | } 1769 | }, 1770 | "strip-ansi": { 1771 | "version": "4.0.0", 1772 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", 1773 | "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", 1774 | "dev": true, 1775 | "requires": { 1776 | "ansi-regex": "^3.0.0" 1777 | } 1778 | }, 1779 | "strip-json-comments": { 1780 | "version": "3.1.1", 1781 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", 1782 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", 1783 | "dev": true 1784 | }, 1785 | "supports-color": { 1786 | "version": "8.1.1", 1787 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", 1788 | "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", 1789 | "dev": true, 1790 | "requires": { 1791 | "has-flag": "^4.0.0" 1792 | } 1793 | }, 1794 | "to-regex-range": { 1795 | "version": "5.0.1", 1796 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 1797 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 1798 | "dev": true, 1799 | "requires": { 1800 | "is-number": "^7.0.0" 1801 | } 1802 | }, 1803 | "url-parse": { 1804 | "version": "1.5.1", 1805 | "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.1.tgz", 1806 | "integrity": "sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q==", 1807 | "dev": true, 1808 | "requires": { 1809 | "querystringify": "^2.1.1", 1810 | "requires-port": "^1.0.0" 1811 | } 1812 | }, 1813 | "which": { 1814 | "version": "2.0.2", 1815 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 1816 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 1817 | "dev": true, 1818 | "requires": { 1819 | "isexe": "^2.0.0" 1820 | } 1821 | }, 1822 | "wide-align": { 1823 | "version": "1.1.3", 1824 | "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", 1825 | "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", 1826 | "dev": true, 1827 | "requires": { 1828 | "string-width": "^1.0.2 || 2" 1829 | } 1830 | }, 1831 | "workerpool": { 1832 | "version": "6.1.0", 1833 | "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz", 1834 | "integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==", 1835 | "dev": true 1836 | }, 1837 | "wrap-ansi": { 1838 | "version": "7.0.0", 1839 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", 1840 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", 1841 | "dev": true, 1842 | "requires": { 1843 | "ansi-styles": "^4.0.0", 1844 | "string-width": "^4.1.0", 1845 | "strip-ansi": "^6.0.0" 1846 | }, 1847 | "dependencies": { 1848 | "ansi-regex": { 1849 | "version": "5.0.0", 1850 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", 1851 | "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", 1852 | "dev": true 1853 | }, 1854 | "is-fullwidth-code-point": { 1855 | "version": "3.0.0", 1856 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 1857 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", 1858 | "dev": true 1859 | }, 1860 | "string-width": { 1861 | "version": "4.2.2", 1862 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", 1863 | "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", 1864 | "dev": true, 1865 | "requires": { 1866 | "emoji-regex": "^8.0.0", 1867 | "is-fullwidth-code-point": "^3.0.0", 1868 | "strip-ansi": "^6.0.0" 1869 | } 1870 | }, 1871 | "strip-ansi": { 1872 | "version": "6.0.0", 1873 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", 1874 | "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", 1875 | "dev": true, 1876 | "requires": { 1877 | "ansi-regex": "^5.0.0" 1878 | } 1879 | } 1880 | } 1881 | }, 1882 | "wrappy": { 1883 | "version": "1.0.2", 1884 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1885 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 1886 | "dev": true 1887 | }, 1888 | "xhr-mock": { 1889 | "version": "1.9.1", 1890 | "resolved": "https://registry.npmjs.org/xhr-mock/-/xhr-mock-1.9.1.tgz", 1891 | "integrity": "sha1-UmMpC+UvAvUrwcVqis+mh58ocUA=", 1892 | "dev": true, 1893 | "requires": { 1894 | "global": "^4.3.0", 1895 | "url-parse": "^1.1.7" 1896 | } 1897 | }, 1898 | "xhr2": { 1899 | "version": "0.1.4", 1900 | "resolved": "https://registry.npmjs.org/xhr2/-/xhr2-0.1.4.tgz", 1901 | "integrity": "sha1-f4dliEdxbbUCYyOBL4GMras4el8=" 1902 | }, 1903 | "xmlhttprequest": { 1904 | "version": "1.8.0", 1905 | "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", 1906 | "integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=" 1907 | }, 1908 | "y18n": { 1909 | "version": "5.0.5", 1910 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz", 1911 | "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==", 1912 | "dev": true 1913 | }, 1914 | "yargs": { 1915 | "version": "16.2.0", 1916 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", 1917 | "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", 1918 | "dev": true, 1919 | "requires": { 1920 | "cliui": "^7.0.2", 1921 | "escalade": "^3.1.1", 1922 | "get-caller-file": "^2.0.5", 1923 | "require-directory": "^2.1.1", 1924 | "string-width": "^4.2.0", 1925 | "y18n": "^5.0.5", 1926 | "yargs-parser": "^20.2.2" 1927 | }, 1928 | "dependencies": { 1929 | "ansi-regex": { 1930 | "version": "5.0.0", 1931 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", 1932 | "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", 1933 | "dev": true 1934 | }, 1935 | "is-fullwidth-code-point": { 1936 | "version": "3.0.0", 1937 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 1938 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", 1939 | "dev": true 1940 | }, 1941 | "string-width": { 1942 | "version": "4.2.2", 1943 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", 1944 | "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", 1945 | "dev": true, 1946 | "requires": { 1947 | "emoji-regex": "^8.0.0", 1948 | "is-fullwidth-code-point": "^3.0.0", 1949 | "strip-ansi": "^6.0.0" 1950 | } 1951 | }, 1952 | "strip-ansi": { 1953 | "version": "6.0.0", 1954 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", 1955 | "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", 1956 | "dev": true, 1957 | "requires": { 1958 | "ansi-regex": "^5.0.0" 1959 | } 1960 | } 1961 | } 1962 | }, 1963 | "yargs-parser": { 1964 | "version": "20.2.4", 1965 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", 1966 | "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", 1967 | "dev": true 1968 | }, 1969 | "yargs-unparser": { 1970 | "version": "2.0.0", 1971 | "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", 1972 | "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", 1973 | "dev": true, 1974 | "requires": { 1975 | "camelcase": "^6.0.0", 1976 | "decamelize": "^4.0.0", 1977 | "flat": "^5.0.2", 1978 | "is-plain-obj": "^2.1.0" 1979 | } 1980 | }, 1981 | "yocto-queue": { 1982 | "version": "0.1.0", 1983 | "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", 1984 | "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", 1985 | "dev": true 1986 | } 1987 | } 1988 | } 1989 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": "Piotr Borysowski", 3 | "contributors": [ 4 | { 5 | "name": "Michael Oblak", 6 | "email": "m@sheetsu.com" 7 | }, 8 | { 9 | "name": "Chris Switalski", 10 | "email": "chris@sheetdb.io" 11 | } 12 | ], 13 | "name": "sheetdb-node", 14 | "description": "Official SheetDB API bindings for Node.js", 15 | "version": "0.0.12", 16 | "homepage": "https://github.com/sheetdb/sheetdb-node", 17 | "repository": { 18 | "type": "git", 19 | "url": "git://github.com/sheetdb/sheetdb-node.git" 20 | }, 21 | "keywords": [ 22 | "sheetdb", 23 | "api", 24 | "google spreadsheets", 25 | "google spreadsheets api", 26 | "spreadsheets", 27 | "spreadsheets api" 28 | ], 29 | "scripts": { 30 | "test": "mocha test/", 31 | "nyan-test": "mocha test/ --reporter nyan" 32 | }, 33 | "dependencies": { 34 | "btoa": "^1.1.2", 35 | "xhr2": "^0.1.4", 36 | "xmlhttprequest": "^1.8.0" 37 | }, 38 | "devDependencies": { 39 | "mocha": "^8.3.2", 40 | "xhr-mock": "^1.7.0" 41 | }, 42 | "main": "index", 43 | "engines": { 44 | "node": "*" 45 | }, 46 | "bugs": { 47 | "url": "https://github.com/sheetdb/sheetdb-node/issues" 48 | }, 49 | "license": "ISC" 50 | } 51 | -------------------------------------------------------------------------------- /test/create.spec.js: -------------------------------------------------------------------------------- 1 | var sheetdbAPI = require('../'); 2 | var assert = require('assert'); 3 | 4 | var mock = require('xhr-mock'); 5 | 6 | describe('sheetdb', function() { 7 | describe('create()', function() { 8 | var sheetdb = sheetdbAPI({ 9 | address: '58f61be4dda40', 10 | }); 11 | 12 | it('should run with POST method', function() { 13 | mock.setup(); 14 | mock.post('https://sheetdb.io/api/v1/58f61be4dda40', function(req, res) { 15 | return res.status(201).body('test'); 16 | }); 17 | 18 | return sheetdb.create({}).then(function(data) { 19 | assert.equal(data, 'test'); 20 | }, function(err) { 21 | console.log(err) 22 | assert.fail('sheetdb throw error'); 23 | }).then(function() { 24 | mock.teardown(); 25 | }); 26 | }); 27 | 28 | it('should run with Http Basic Auth', function() { 29 | mock.setup(); 30 | mock.post('https://sheetdb.io/api/v1/58f61be4dda40', function(req, res) { 31 | return res.status(201).body(req._headers); 32 | }); 33 | 34 | sheetdbLocal = sheetdbAPI({ 35 | address: '58f61be4dda40', 36 | auth_login: 'somekey', 37 | auth_password: 'somesecret', 38 | }); 39 | 40 | return sheetdbLocal.create({}).then(function(data) { 41 | assert.equal(data.authorization, "Basic c29tZWtleTpzb21lc2VjcmV0"); 42 | }, function(err) { 43 | assert.fail('sheetdb throw error'); 44 | }).then(function(){ 45 | mock.teardown(); 46 | }); 47 | }); 48 | 49 | it('should run with correct headers', function() { 50 | mock.setup(); 51 | mock.post('https://sheetdb.io/api/v1/58f61be4dda40', function(req, res) { 52 | return res.status(201).body(req._headers); 53 | }); 54 | 55 | return sheetdb.create({}).then(function(data) { 56 | assert.equal(data["accept"], "application/vnd.sheetdb.3+json"); 57 | assert.equal(data["content-type"], "application/json"); 58 | assert.equal(data["x-user-agent"], "SheetDB-Node/1"); 59 | }, function(err) { 60 | assert.fail('sheetdb throw error'); 61 | }).then(function(){ 62 | mock.teardown(); 63 | }); 64 | }); 65 | 66 | it('should run with object data', function() { 67 | mock.setup(); 68 | mock.post('https://sheetdb.io/api/v1/58f61be4dda40', function(req, res) { 69 | return res.status(201).body('{"some":5}'); 70 | }); 71 | 72 | return sheetdb.create({some: 5}).then(function(data){ 73 | assert.equal(data, '{"some":5}'); 74 | }, function(err) { 75 | assert.fail('sheetdb throw error'); 76 | }).then(function(){ 77 | mock.teardown(); 78 | }); 79 | }); 80 | 81 | it('should run with array data', function() { 82 | mock.setup(); 83 | mock.post('https://sheetdb.io/api/v1/58f61be4dda40', function(req, res) { 84 | return res.status(201).body('{"rows":[{},{"test":3}]}'); 85 | }); 86 | 87 | return sheetdb.create([{}, {test: 3}]).then(function(data){ 88 | assert.equal(data, '{"rows":[{},{"test":3}]}'); 89 | }, function(err) { 90 | assert.fail('sheetdb throw error'); 91 | }).then(function(){ 92 | mock.teardown(); 93 | }); 94 | }); 95 | 96 | it('should return correct url', function() { 97 | mock.setup(); 98 | mock.post('https://sheetdb.io/api/v1/58f61be4dda40', function(req, res) { 99 | return res.status(201).body(req); 100 | }); 101 | 102 | return sheetdb.create({}).then(function(data){ 103 | assert.equal(data._url, 'https://sheetdb.io/api/v1/58f61be4dda40'); 104 | }, function(err) { 105 | assert.fail('sheetdb throw error'); 106 | }).then(function(){ 107 | mock.teardown(); 108 | }); 109 | }); 110 | 111 | it('should return url different Sheet', function() { 112 | mock.setup(); 113 | mock.post('https://sheetdb.io/api/v1/58f61be4dda40?sheet=Sheet2', function(req, res) { 114 | return res.status(201).body(req); 115 | }); 116 | 117 | return sheetdb.create({}, 'Sheet2').then(function(data){ 118 | assert.equal(data._url, 'https://sheetdb.io/api/v1/58f61be4dda40?sheet=Sheet2'); 119 | }, function(err) { 120 | assert.fail('sheetdb throw error'); 121 | }); 122 | }); 123 | 124 | it('should return error when 404', function() { 125 | mock.setup(); 126 | mock.post('https://sheetdb.io/api/v1/58f61be4dda40/sheets/Sheet3?limit=6', function(req, res) { 127 | return res.status(404).body(req); 128 | }); 129 | 130 | return sheetdb.create({}).then(function(data) { 131 | assert.fail('sheetdb does not throw any error'); 132 | }, function(err) { 133 | }).then(function(){ 134 | mock.teardown(); 135 | }); 136 | }); 137 | 138 | it('should return error when 429', function() { 139 | mock.setup(); 140 | mock.post('https://sheetdb.io/api/v1/58f61be4dda40/sheets/Sheet3?limit=6', function(req, res) { 141 | return res.status(429).body(req); 142 | }); 143 | 144 | return sheetdb.create({}).then(function(data) { 145 | assert.fail('sheetdb does not throw any error'); 146 | }, function(err) { 147 | }).then(function(){ 148 | mock.teardown(); 149 | }); 150 | }); 151 | 152 | it('should return error when 403', function() { 153 | mock.setup(); 154 | mock.post('https://sheetdb.io/api/v1/58f61be4dda40/sheets/Sheet3?limit=6', function(req, res) { 155 | return res.status(403).body(req); 156 | }); 157 | 158 | return sheetdb.create({}).then(function(data) { 159 | assert.fail('sheetdb does not throw any error'); 160 | }, function(err) { 161 | }).then(function(){ 162 | mock.teardown(); 163 | }); 164 | }); 165 | 166 | it('should return error when 401', function() { 167 | mock.setup(); 168 | mock.post('https://sheetdb.io/api/v1/58f61be4dda40/sheets/Sheet3?limit=6', function(req, res) { 169 | return res.status(401).body(req); 170 | }); 171 | 172 | return sheetdb.create({}).then(function(data) { 173 | assert.fail('sheetdb does not throw any error'); 174 | }, function(err) { 175 | }).then(function(){ 176 | mock.teardown(); 177 | }); 178 | }); 179 | 180 | it('should return error when 500', function() { 181 | mock.setup(); 182 | mock.post('https://sheetdb.io/api/v1/58f61be4dda40/sheets/Sheet3?limit=6', function(req, res) { 183 | return res.status(500).body(req); 184 | }); 185 | 186 | return sheetdb.create({}).then(function(data) { 187 | assert.fail('sheetdb does not throw any error'); 188 | }, function(err) { 189 | }).then(function(){ 190 | mock.teardown(); 191 | }); 192 | }); 193 | 194 | }); 195 | }); 196 | -------------------------------------------------------------------------------- /test/delete.spec.js: -------------------------------------------------------------------------------- 1 | var sheetdbAPI = require('../'); 2 | var assert = require('assert'); 3 | 4 | var mock = require('xhr-mock'); 5 | 6 | describe('sheetdb', function() { 7 | describe('delete() function', function() { 8 | var sheetdb = sheetdbAPI({ 9 | address: '58f61be4dda40', 10 | }); 11 | 12 | it('should run with DELETE method', function() { 13 | mock.setup(); 14 | mock.delete('https://sheetdb.io/api/v1/58f61be4dda40/column/test', function(req, res) { 15 | return res.status(200).body('test'); 16 | }); 17 | 18 | return sheetdb.delete('column', 'test').then(function(data) { 19 | assert.equal(data, 'test'); 20 | }, function(err) { 21 | assert.fail('sheetdb throw error'); 22 | }).then(function() { 23 | mock.teardown(); 24 | }); 25 | }); 26 | 27 | it('should run with Http Basic Auth', function() { 28 | mock.setup(); 29 | mock.delete('https://sheetdb.io/api/v1/58f61be4dda40/column/test', function(req, res) { 30 | return res.status(201).body(req._headers); 31 | }); 32 | 33 | sheetdbLocal = sheetdbAPI({ 34 | address: '58f61be4dda40', 35 | auth_login: 'somekey', 36 | auth_password: 'somesecret', 37 | }); 38 | 39 | return sheetdbLocal.delete('column', 'test').then(function(data) { 40 | assert.equal(data.authorization, "Basic c29tZWtleTpzb21lc2VjcmV0"); 41 | }, function(err) { 42 | assert.fail('sheetdb throw error'); 43 | }).then(function(){ 44 | mock.teardown(); 45 | }); 46 | }); 47 | 48 | it('should run with correct headers', function() { 49 | mock.setup(); 50 | mock.delete('https://sheetdb.io/api/v1/58f61be4dda40/column/test', function(req, res) { 51 | return res.status(201).body(req._headers); 52 | }); 53 | 54 | return sheetdb.delete('column', 'test').then(function(data) { 55 | assert.equal(data["accept"], "application/vnd.sheetdb.3+json"); 56 | assert.equal(data["content-type"], "application/json"); 57 | assert.equal(data["x-user-agent"], "SheetDB-Node/1"); 58 | }, function(err) { 59 | assert.fail('sheetdb throw error'); 60 | }).then(function(){ 61 | mock.teardown(); 62 | }); 63 | }); 64 | 65 | it('should run with column name and value', function() { 66 | mock.setup(); 67 | mock.delete('https://sheetdb.io/api/v1/58f61be4dda40/column/test', function(req, res) { 68 | return res.status(200).body(req); 69 | }) 70 | 71 | return sheetdb.delete('column', 'test').then(function(data){ 72 | assert.equal(data._url, 'https://sheetdb.io/api/v1/58f61be4dda40/column/test'); 73 | }, function(err) { 74 | assert.fail('sheetdb throw error'); 75 | }).then(function() { 76 | mock.teardown(); 77 | }); 78 | }); 79 | 80 | it('should throw error when no column param', function() { 81 | mock.setup(); 82 | mock.delete('https://sheetdb.io/api/v1/58f61be4dda40/column/test', function(req, res) { 83 | return res.status(200).body(req); 84 | }); 85 | 86 | return sheetdb.delete().then(function(data){ 87 | assert.fail('sheetdb do not throw error'); 88 | }, function(err) { 89 | assert.equal(err, 'no column name'); 90 | }).then(function() { 91 | mock.teardown(); 92 | }); 93 | }); 94 | 95 | it('should return url different Sheet', function() { 96 | mock.setup(); 97 | mock.delete('https://sheetdb.io/api/v1/58f61be4dda40/column/test?sheet=Sheet2', function(req, res) { 98 | return res.status(200).body(req); 99 | }); 100 | 101 | return sheetdb.delete('column', 'test', 'Sheet2').then(function(data){ 102 | assert.equal(data._url, 'https://sheetdb.io/api/v1/58f61be4dda40/column/test?sheet=Sheet2'); 103 | }, function(err) { 104 | assert.fail('sheetdb throw error'); 105 | }).then(function() { 106 | mock.teardown(); 107 | }); 108 | }); 109 | 110 | it('should return error when 404', function() { 111 | mock.setup(); 112 | mock.delete('https://sheetdb.io/api/v1/58f61be4dda40/column/test', function(req, res) { 113 | return res.status(404).body(req._xhr); 114 | }); 115 | 116 | return sheetdb.delete('column', 'test').then(function(data) { 117 | assert.equal(data.status, 404); 118 | }, function(err) { 119 | }).then(function(){ 120 | mock.teardown(); 121 | }); 122 | }); 123 | 124 | it('should return error when 429', function() { 125 | mock.setup(); 126 | mock.delete('https://sheetdb.io/api/v1/58f61be4dda40/column/test', function(req, res) { 127 | return res.status(429).body(req._xhr); 128 | }); 129 | 130 | return sheetdb.delete('column', 'test').then(function(data) { 131 | assert.equal(data.status, 429); 132 | }, function(err) { 133 | }).then(function(){ 134 | mock.teardown(); 135 | }); 136 | }); 137 | 138 | it('should return error when 403', function() { 139 | mock.setup(); 140 | mock.delete('https://sheetdb.io/api/v1/58f61be4dda40/column/test', function(req, res) { 141 | return res.status(403).body(req._xhr); 142 | }); 143 | 144 | return sheetdb.delete('column', 'test').then(function(data) { 145 | assert.equal(data.status, 403); 146 | }, function(err) { 147 | }).then(function(){ 148 | mock.teardown(); 149 | }); 150 | }); 151 | 152 | it('should return error when 401', function() { 153 | mock.setup(); 154 | mock.delete('https://sheetdb.io/api/v1/58f61be4dda40/column/test', function(req, res) { 155 | return res.status(401).body(req._xhr); 156 | }); 157 | 158 | return sheetdb.delete('column', 'test').then(function(data) { 159 | assert.equal(data.status, 401); 160 | }, function(err) { 161 | }).then(function(){ 162 | mock.teardown(); 163 | }); 164 | }); 165 | 166 | it('should return error when 500', function() { 167 | mock.setup(); 168 | mock.delete('https://sheetdb.io/api/v1/58f61be4dda40/column/test', function(req, res) { 169 | return res.status(500).body(req._xhr); 170 | }); 171 | 172 | return sheetdb.delete('column', 'test').then(function(data) { 173 | assert.equal(data.status, 500); 174 | }, function(err) { 175 | }).then(function(){ 176 | mock.teardown(); 177 | }); 178 | }); 179 | 180 | }); 181 | }); 182 | -------------------------------------------------------------------------------- /test/endpoint.spec.js: -------------------------------------------------------------------------------- 1 | var sheetdbAPI = require('../'); 2 | var assert = require('assert'); 3 | 4 | var mock = require('xhr-mock'); 5 | 6 | describe('sheetdb', function() { 7 | describe('endpoint() function', function() { 8 | var sheetdb = sheetdbAPI({ 9 | address: '58f61be4dda40', 10 | }); 11 | 12 | it('should run with GET method', function() { 13 | mock.setup(); 14 | mock.get('https://sheetdb.io/api/v1/58f61be4dda40/keys', function(req, res) { 15 | return res.status(200).body('test'); 16 | }); 17 | 18 | return sheetdb.endpoint('keys').then(function(data) { 19 | assert.equal(data, 'test'); 20 | }, function(err) { 21 | assert.fail('sheetdb throw error'); 22 | }).then(function() { 23 | mock.teardown(); 24 | }); 25 | }); 26 | 27 | it('should run with Http Basic Auth', function() { 28 | mock.setup(); 29 | mock.get('https://sheetdb.io/api/v1/58f61be4dda40/keys', function(req, res) { 30 | return res.status(200).body(req._headers); 31 | }); 32 | 33 | sheetdbLocal = sheetdbAPI({ 34 | address: '58f61be4dda40', 35 | auth_login: 'somekey', 36 | auth_password: 'somesecret', 37 | }); 38 | 39 | return sheetdbLocal.endpoint('keys').then(function(data) { 40 | assert.equal(data.authorization, "Basic c29tZWtleTpzb21lc2VjcmV0"); 41 | }, function(err) { 42 | assert.fail('sheetdb throw error'); 43 | }).then(function(){ 44 | mock.teardown(); 45 | }); 46 | }); 47 | 48 | }); 49 | }); 50 | -------------------------------------------------------------------------------- /test/read.spec.js: -------------------------------------------------------------------------------- 1 | var sheetdbAPI = require('../'); 2 | var assert = require('assert'); 3 | 4 | var mock = require('xhr-mock'); 5 | 6 | describe('sheetdb', function() { 7 | describe('read() function', function() { 8 | var sheetdb = sheetdbAPI({ 9 | address: '58f61be4dda40', 10 | }); 11 | 12 | it('should run with GET method', function() { 13 | mock.setup(); 14 | mock.get('https://sheetdb.io/api/v1/58f61be4dda40', function(req, res) { 15 | return res.status(200).body('test'); 16 | }); 17 | 18 | return sheetdb.read({}).then(function(data) { 19 | assert.equal(data, 'test'); 20 | }, function(err) { 21 | assert.fail('sheetdb throw error'); 22 | }).then(function() { 23 | mock.teardown(); 24 | }); 25 | }); 26 | 27 | it('should run with Http Basic Auth', function() { 28 | mock.setup(); 29 | mock.get('https://sheetdb.io/api/v1/58f61be4dda40', function(req, res) { 30 | return res.status(200).body(req._headers); 31 | }); 32 | 33 | sheetdbLocal = sheetdbAPI({ 34 | address: '58f61be4dda40', 35 | auth_login: 'somekey', 36 | auth_password: 'somesecret', 37 | }); 38 | 39 | return sheetdbLocal.read().then(function(data) { 40 | assert.equal(data.authorization, "Basic c29tZWtleTpzb21lc2VjcmV0"); 41 | }, function(err) { 42 | assert.fail('sheetdb throw error'); 43 | }).then(function(){ 44 | mock.teardown(); 45 | }); 46 | }); 47 | 48 | it('should run with correct headers', function() { 49 | mock.setup(); 50 | mock.get('https://sheetdb.io/api/v1/58f61be4dda40', function(req, res) { 51 | return res.status(200).body(req._headers); 52 | }); 53 | 54 | return sheetdb.read().then(function(data) { 55 | assert.equal(data["accept"], "application/vnd.sheetdb.3+json"); 56 | assert.equal(data["content-type"], "application/json"); 57 | assert.equal(data["x-user-agent"], "SheetDB-Node/1"); 58 | }, function(err) { 59 | assert.fail('sheetdb throw error'); 60 | }).then(function(){ 61 | mock.teardown(); 62 | }); 63 | }); 64 | 65 | it('should return url without limit and offset', function() { 66 | mock.setup(); 67 | mock.get('https://sheetdb.io/api/v1/58f61be4dda40', function(req, res) { 68 | return res.status(200).body(req); 69 | }); 70 | return sheetdb.read().then(function(data){ 71 | assert.equal(data._url, 'https://sheetdb.io/api/v1/58f61be4dda40'); 72 | }, function(err) { 73 | assert.fail('sheetdb throw error'); 74 | }).then(function(){ 75 | mock.teardown(); 76 | }); 77 | }); 78 | 79 | it('should return url with limit', function() { 80 | mock.setup(); 81 | mock.get('https://sheetdb.io/api/v1/58f61be4dda40?limit=5', function(req, res) { 82 | return res.status(200).body(req); 83 | }); 84 | 85 | return sheetdb.read({ limit: 5 }).then(function(data){ 86 | assert.equal(data._url, 'https://sheetdb.io/api/v1/58f61be4dda40?limit=5'); 87 | }, function(err) { 88 | assert.fail('sheetdb throw error'); 89 | }).then(function(){ 90 | mock.teardown(); 91 | }); 92 | }); 93 | 94 | it('should return url with offset', function() { 95 | mock.setup(); 96 | mock.get('https://sheetdb.io/api/v1/58f61be4dda40?offset=10', function(req, res) { 97 | return res.status(200).body(req); 98 | }); 99 | 100 | return sheetdb.read({ offset: 10 }).then(function(data) { 101 | assert.equal(data._url, 'https://sheetdb.io/api/v1/58f61be4dda40?offset=10'); 102 | }, function(err) { 103 | assert.fail('sheetdb throw error'); 104 | }).then(function(){ 105 | mock.teardown(); 106 | }); 107 | }); 108 | 109 | it('should return url with offset and limit', function() { 110 | mock.setup(); 111 | mock.get('https://sheetdb.io/api/v1/58f61be4dda40?limit=5&offset=10', function(req, res) { 112 | return res.status(200).body(req); 113 | }); 114 | 115 | return sheetdb.read({ limit: 5, offset: 10 }).then(function(data){ 116 | assert.equal(data._url, 'https://sheetdb.io/api/v1/58f61be4dda40?limit=5&offset=10'); 117 | }, function(err) { 118 | assert.fail('sheetdb throw error'); 119 | }).then(function(){ 120 | mock.teardown(); 121 | }); 122 | }); 123 | 124 | it('should be able to search', function() { 125 | mock.setup(); 126 | mock.get('https://sheetdb.io/api/v1/58f61be4dda40/search?name=test&foo=bar', function(req, res) { 127 | return res.status(200).body(req); 128 | }); 129 | 130 | return sheetdb.read({ search: {name: 'test', foo: 'bar'} }).then(function(data) { 131 | assert.equal(data._url, 'https://sheetdb.io/api/v1/58f61be4dda40/search?name=test&foo=bar'); 132 | }, function(err) { 133 | assert.fail('sheetdb throw error'); 134 | }).then(function(){ 135 | mock.teardown(); 136 | }); 137 | }); 138 | 139 | it('should be able to search with limit', function() { 140 | mock.setup(); 141 | mock.get('https://sheetdb.io/api/v1/58f61be4dda40/search?name=test&foo=bar&limit=5', function(req, res) { 142 | return res.status(200).body(req); 143 | }); 144 | 145 | return sheetdb.read({ limit: 5, search: {name: 'test', foo: 'bar'} }).then(function(data) { 146 | assert.equal(data._url, 'https://sheetdb.io/api/v1/58f61be4dda40/search?name=test&foo=bar&limit=5'); 147 | }, function(err) { 148 | assert.fail('sheetdb throw error'); 149 | }).then(function(){ 150 | mock.teardown(); 151 | }); 152 | }); 153 | 154 | it('should be able to use different sheet', function() { 155 | mock.setup(); 156 | mock.get('https://sheetdb.io/api/v1/58f61be4dda40?sheet=Sheet2', function(req, res) { 157 | return res.status(200).body(req); 158 | }); 159 | 160 | return sheetdb.read({ sheet: 'Sheet2' }).then(function(data) { 161 | assert.equal(data._url, 'https://sheetdb.io/api/v1/58f61be4dda40?sheet=Sheet2'); 162 | }, function(err) { 163 | assert.fail('sheetdb throw error'); 164 | }).then(function(){ 165 | mock.teardown(); 166 | }); 167 | }); 168 | 169 | it('should be able to use different sheet when limit set', function() { 170 | mock.setup(); 171 | mock.get('https://sheetdb.io/api/v1/58f61be4dda40?limit=6&sheet=Sheet2', function(req, res) { 172 | return res.status(200).body(req); 173 | }); 174 | 175 | return sheetdb.read({ limit: 6, sheet: 'Sheet2' }).then(function(data) { 176 | assert.equal(data._url, 'https://sheetdb.io/api/v1/58f61be4dda40?limit=6&sheet=Sheet2'); 177 | }, function(err) { 178 | assert.fail('sheetdb throw error'); 179 | }).then(function(){ 180 | mock.teardown(); 181 | }); 182 | }); 183 | 184 | it('should be able to use all attributes together', function() { 185 | mock.setup(); 186 | mock.get('https://sheetdb.io/api/v1/58f61be4dda40/search?id=1&limit=1&offset=1&sheet=Sheet2', function(req, res) { 187 | return res.status(200).body(req); 188 | }); 189 | 190 | return sheetdb.read({ search: {id: 1}, limit: 1, offset: 1, sheet: 'Sheet2' }).then(function(data) { 191 | assert.equal(data._url, 'https://sheetdb.io/api/v1/58f61be4dda40/search?id=1&limit=1&offset=1&sheet=Sheet2'); 192 | }, function(err) { 193 | assert.fail('sheetdb throw error'); 194 | }).then(function(){ 195 | mock.teardown(); 196 | }); 197 | }); 198 | 199 | it('should return error when 404', function() { 200 | mock.setup(); 201 | mock.get('https://sheetdb.io/api/v1/58f61be4dda40/sheets/Sheet3?limit=6', function(req, res) { 202 | return res.status(404).body(req); 203 | }); 204 | 205 | return sheetdb.read().then(function(data) { 206 | assert.fail('sheetdb does not throw any error'); 207 | }, function(err) { 208 | }).then(function(){ 209 | mock.teardown(); 210 | }); 211 | }); 212 | 213 | it('should return error when 429', function() { 214 | mock.setup(); 215 | mock.get('https://sheetdb.io/api/v1/58f61be4dda40/sheets/Sheet3?limit=6', function(req, res) { 216 | return res.status(429).body(req); 217 | }); 218 | 219 | return sheetdb.read().then(function(data) { 220 | assert.fail('sheetdb does not throw any error'); 221 | }, function(err) { 222 | }).then(function(){ 223 | mock.teardown(); 224 | }); 225 | }); 226 | 227 | it('should return error when 403', function() { 228 | mock.setup(); 229 | mock.get('https://sheetdb.io/api/v1/58f61be4dda40/sheets/Sheet3?limit=6', function(req, res) { 230 | return res.status(403).body(req); 231 | }); 232 | 233 | return sheetdb.read().then(function(data) { 234 | assert.fail('sheetdb does not throw any error'); 235 | }, function(err) { 236 | }).then(function(){ 237 | mock.teardown(); 238 | }); 239 | }); 240 | 241 | it('should return error when 401', function() { 242 | mock.setup(); 243 | mock.get('https://sheetdb.io/api/v1/58f61be4dda40/sheets/Sheet3?limit=6', function(req, res) { 244 | return res.status(401).body(req); 245 | }); 246 | 247 | return sheetdb.read().then(function(data) { 248 | assert.fail('sheetdb does not throw any error'); 249 | }, function(err) { 250 | }).then(function(){ 251 | mock.teardown(); 252 | }); 253 | }); 254 | 255 | it('should return error when 500', function() { 256 | mock.setup(); 257 | mock.get('https://sheetdb.io/api/v1/58f61be4dda40/sheets/Sheet3?limit=6', function(req, res) { 258 | return res.status(500).body(req); 259 | }); 260 | 261 | return sheetdb.read().then(function(data) { 262 | assert.fail('sheetdb does not throw any error'); 263 | }, function(err) { 264 | }).then(function(){ 265 | mock.teardown(); 266 | }); 267 | }); 268 | }); 269 | }); 270 | -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | var sheetdbAPI = require('../'); 2 | var assert = require('assert'); 3 | var mock = require('xhr-mock'); 4 | describe('sheetdb', function() { 5 | describe('contructor', function() { 6 | it('should throw error when param has no address', function() { 7 | assert.throws(function() { 8 | sheetdbAPI(); 9 | }, Error); 10 | }); 11 | 12 | it('should not throw error when param has valid address', function() { 13 | mock.get('https://sheetdb.io', function(req, res) { 14 | return res.status(200).body('