├── .editorconfig ├── .github └── workflows │ ├── release.yml │ └── tests.yml ├── .gitignore ├── LICENSE ├── README.md ├── index.js ├── package-lock.json ├── package.json ├── src └── pal.js └── tests ├── cli.bats ├── test-run.yml └── test-timeout.yml /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 4 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Create a release 2 | 3 | on: 4 | push: 5 | tags: 6 | - 'v*' 7 | 8 | jobs: 9 | 10 | sanity: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v2 14 | - uses: actions/setup-node@v1 15 | with: 16 | node-version: 14 17 | - run: npm ci 18 | - run: npm test 19 | 20 | release: 21 | needs: sanity 22 | runs-on: ubuntu-latest 23 | outputs: 24 | release_url: ${{ steps.create_release.outputs.upload_url }} 25 | steps: 26 | - uses: actions/checkout@v2 27 | - name: Create a release 28 | uses: actions/create-release@v1 29 | id: create_release 30 | env: 31 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 32 | with: 33 | tag_name: ${{ github.ref }} 34 | release_name: ${{ github.ref }} 35 | draft: false 36 | prerelease: false 37 | 38 | publish: 39 | needs: release 40 | runs-on: ubuntu-latest 41 | steps: 42 | - uses: actions/checkout@v2 43 | - uses: actions/setup-node@v1 44 | with: 45 | node-version: 14 46 | registry-url: https://registry.npmjs.org/ 47 | - run: npm ci 48 | - run: npm publish --access public 49 | env: 50 | NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} 51 | 52 | build: 53 | needs: release 54 | runs-on: ubuntu-latest 55 | strategy: 56 | matrix: 57 | platform: [linux-x64, windows-x64, macos-x64] 58 | steps: 59 | - name: Get the version 60 | id: get_version 61 | run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\//} 62 | - uses: actions/checkout@v2 63 | - uses: actions/setup-node@v1 64 | with: 65 | node-version: 14.x 66 | - run: npm ci 67 | - name: Build the binary 68 | run: npm run build -- -t node14-${{ matrix.platform }} 69 | - name: Check the binary 70 | run: file ./dist/* 71 | - name: Package the binary 72 | run: | 73 | mv dist berkala-${{ steps.get_version.outputs.VERSION }}-${{ matrix.platform }} 74 | zip -r9 berkala-${{ steps.get_version.outputs.VERSION }}-${{ matrix.platform }}.zip berkala-${{ steps.get_version.outputs.VERSION }}-${{ matrix.platform }}/ 75 | - name: Upload the binary 76 | uses: actions/upload-release-asset@v1 77 | env: 78 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 79 | with: 80 | upload_url: ${{ needs.release.outputs.release_url }} 81 | asset_path: berkala-${{ steps.get_version.outputs.VERSION }}-${{ matrix.platform }}.zip 82 | asset_name: berkala-${{ steps.get_version.outputs.VERSION }}-${{ matrix.platform }}.zip 83 | asset_content_type: application/zip 84 | -------------------------------------------------------------------------------- /.github/workflows/tests.yml: -------------------------------------------------------------------------------- 1 | name: Tests 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | test: 7 | runs-on: ubuntu-latest 8 | strategy: 9 | matrix: 10 | node-version: [14.x] 11 | 12 | steps: 13 | - uses: actions/checkout@v2 14 | - name: Use Node.js ${{ matrix.node-version }} 15 | uses: actions/setup-node@v1 16 | with: 17 | node-version: ${{ matrix.node-version }} 18 | 19 | - run: npm ci 20 | - run: npm test 21 | 22 | build: 23 | runs-on: ubuntu-latest 24 | needs: test 25 | strategy: 26 | matrix: 27 | platform: [linux-x64, windows-x64, macos-x64] 28 | steps: 29 | - uses: actions/checkout@v2 30 | - uses: actions/setup-node@v1 31 | with: 32 | node-version: 14.x 33 | - run: npm ci 34 | - name: Build the binary 35 | run: npm run build -- -t node14-${{ matrix.platform }} 36 | - name: Check the binary 37 | run: file ./dist/* 38 | 39 | cli-tests: 40 | runs-on: ubuntu-latest 41 | needs: build 42 | strategy: 43 | matrix: 44 | platform: [linux-x64] 45 | steps: 46 | - uses: actions/checkout@v2 47 | - uses: actions/setup-node@v1 48 | with: 49 | node-version: 14.x 50 | - run: npm ci 51 | - name: Build the binary 52 | run: npm run build -- -t node14-${{ matrix.platform }} 53 | - name: Run CLI tests with the binary 54 | run: npm run cli-tests -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # TypeScript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # next.js build output 61 | .next 62 | 63 | # berkala output 64 | berkala.yml 65 | 66 | # build output 67 | dist 68 | 69 | # DS_Store 70 | .DS_Store 71 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Ariya Hidayat 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Berkala 2 | 3 | [![GitHub license](https://img.shields.io/github/license/ariya/berkala)](https://github.com/ariya/berkala/blob/main/LICENSE) 4 | [![Tests](https://github.com/ariya/berkala/workflows/Tests/badge.svg)](https://github.com/ariya/berkala/actions) 5 | 6 | Berkala runs scheduled tasks specified in a YAML-based configuration. 7 | 8 | To get started, first download the binary for your operating system from the [Releases page](https://github.com/ariya/berkala/releases). Unpack the ZIP file and run the executable. 9 | 10 | Since a config file does not exist yet, you will be offered to create one. 11 | Simply accept it and `berkala.yml` will be created, which may look like the following: 12 | 13 | ```yml 14 | tasks: 15 | 16 | # Without an explicit interval, the task runs immediately 17 | boot: 18 | steps: 19 | - notify: Berkala starts now 20 | 21 | stay-hydrated: 22 | interval: every 1 hour 23 | steps: 24 | - notify: Drink some water! # TODO: how much? 25 | - print: Reminder was sent 26 | 27 | lunch: 28 | interval: at 11:58am 29 | steps: 30 | - notify: It's lunch time very soon 31 | title: Important 32 | - say: Get ready for lunch 33 | 34 | sign-of-life: 35 | interval: every 2 hours 36 | steps: 37 | - run: ping -c 7 google.com 38 | timeout-minutes: 2 39 | 40 | weekend-exercise: 41 | cron: 0 9 * * 6 # every 9 morning on Saturday 42 | steps: 43 | - notify: Time for some exercises! 44 | title: Stay healthy 45 | ``` 46 | Just like any regular YAML, everything from the `#` character until the end of the line will be ignored. Use this to insert comments. 47 | 48 | The schedule for each task can be specified as: 49 | * [a human-friendly interval](https://breejs.github.io/later/parsers.html#text), e.g. `every 5 minutes`, `at 5pm`, or 50 | * [a cron expression](https://crontab.guru/), e.g. `0 9 * * 6` 51 | 52 | If neither is explicitly stated, then the task runs right away. 53 | 54 | Each task consists of one or more steps. 55 | 56 | Every step must be one of the following: 57 | 58 |
run: executes a shell command 59 | 60 | Example: 61 | ```yaml 62 | sign-of-life: 63 | interval: every 30 minutes 64 | steps: 65 | - run: ping -c 7 google.com 66 | ``` 67 | Optionally, `timeout-minutes` can be used to limit the execution time and `working-directory` can be used to set the directory to start the execution from. 68 | 69 | Another example: 70 | ```yaml 71 | sys-resource: 72 | interval: every 2 hours 73 | steps: 74 | - run: | 75 | date >> resources.log 76 | top | head -n 4 >> resources.log 77 | timeout-minutes: 3 78 | working-directory: /var/log 79 | ``` 80 | 81 |
82 | 83 | 84 |
print: displays a message to the standard output 85 | 86 | Example: 87 | ```yaml 88 | morning: 89 | interval: at 7:00am 90 | steps: 91 | - print: Good morning! 92 | ``` 93 | 94 |
95 | 96 |
notify: sends a desktop notification 97 | 98 | Optionally, `title` can be used to set the notification title. 99 | 100 | Example: 101 | ```yaml 102 | mahlzeit: 103 | interval: at 11:58am 104 | steps: 105 | - notify: It's lunch time very soon 106 | title: Yummy 107 | ``` 108 | 109 | The notification is supported on the following system: 110 | 111 | * Windows: [Windows.UI.Notifications](https://docs.microsoft.com/en-us/uwp/api/windows.ui.notifications.toastnotification) via [Powershell scripting](https://docs.microsoft.com/en-us/powershell/scripting) 112 | * macOS: `display notification` with [AppleScript](https://developer.apple.com/library/archive/documentation/AppleScript/Conceptual/AppleScriptLangGuide/reference/ASLR_cmds.html) 113 | * Linux: [notify-send](https://www.commandlinux.com/man-page/man1/notify-send.1.html), e.g. part of `libnotify-bin` package on Debian/Ubuntu 114 | 115 |
116 | 117 |
say: converts text to audible speech 118 | 119 | Example: 120 | ```yaml 121 | vaya-con-dios: 122 | interval: 0 17 * * 1-5 # every workday late afternoon 123 | steps: 124 | - say: Time to go home 125 | ``` 126 | 127 | The text-to-speech conversion is supported on the following system: 128 | 129 | * Windows: [System.Speech.Synthesis](https://docs.microsoft.com/en-us/dotnet/api/system.speech.synthesis) via [Powershell scripting](https://docs.microsoft.com/en-us/powershell/scripting) 130 | * macOS: `say` with [AppleScript](https://developer.apple.com/library/archive/documentation/AppleScript/Conceptual/AppleScriptLangGuide/reference/ASLR_cmds.html) 131 | * Linux: [Festival speech synthesis](https://www.cstr.ed.ac.uk/projects/festival/), e.g. `festival` and `festvox-kallpc16k` on Debian/Ubuntu 132 | 133 |
134 | 135 | Found a problem or have a new idea? File [an issue](https://github.com/ariya/berkala/issues)! 136 | 137 |
138 | Alternative way to run Berkala (with Node.js) 139 | 140 | With [Node.js](https://nodejs.org/) v14 or later (that has [npx](https://www.npmjs.com/package/npx)): 141 | 142 | ```bash 143 | npx @ariya/berkala 144 | ``` 145 | 146 | To run the development version, check out this repo and then: 147 | 148 | ```bash 149 | npm install 150 | npm start 151 | ``` 152 | 153 | [![npm version](https://img.shields.io/npm/v/@ariya/berkala)](https://www.npmjs.com/package/@ariya/berkala) 154 | [![npm bundle size (minified)](https://img.shields.io/bundlephobia/min/@ariya/berkala.svg)](https://bundlephobia.com/result?p=@ariya/berkala) 155 | 156 |
157 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const fs = require('fs'); 4 | const os = require('os'); 5 | 6 | const manifest = require('./package.json'); 7 | const readline = require('readline-sync'); 8 | const yaml = require('js-yaml'); 9 | const Bree = require('bree'); 10 | 11 | const pal = require('./src/pal'); 12 | 13 | const CONFIG_FILENAME = 'berkala.yml'; 14 | 15 | const SAMPLE_CONFIG = ` 16 | tasks: 17 | 18 | # Without an explicit interval, the task runs immediately 19 | boot: 20 | steps: 21 | - notify: Berkala starts now 22 | - say: Ready to rock and roll 23 | 24 | stay-hydrated: 25 | interval: every 1 hour 26 | steps: 27 | - notify: Drink some water! # TODO: how much? 28 | - print: Reminder was sent 29 | 30 | lunch: 31 | interval: at 11:58am 32 | steps: 33 | - notify: It's lunch time very soon 34 | title: Important 35 | - say: Get ready for lunch 36 | 37 | sign-of-life: 38 | interval: every 30 minutes 39 | steps: 40 | - print: Pings 41 | - run: | 42 | ping -c 3 google.com 43 | ping -c 5 bing.com 44 | timeout-minutes: 2 45 | 46 | weekend-exercise: 47 | cron: 0 9 * * 6 # every 9 morning on Saturday 48 | steps: 49 | - notify: Time for some exercises! 50 | title: Stay healthy 51 | `; 52 | 53 | /** 54 | * Returns true if interactivity is permitted (i.e. not in a CI) 55 | */ 56 | function isInteractive() { 57 | const stdout = process.stdout; 58 | return stdout.isTTY && !('CI' in process.env) && process.env.TERM !== 'dumb'; 59 | } 60 | 61 | /** 62 | * Retrieve the configuration from the external berkala.yml file. 63 | */ 64 | function getConfig() { 65 | const tasks = {}; 66 | let config = { tasks }; 67 | if (!fs.existsSync(CONFIG_FILENAME) && isInteractive()) { 68 | console.log(CONFIG_FILENAME, 'does not exist.'); 69 | const answer = readline.question('Do you want to create one (Y/n)? ').toUpperCase(); 70 | if (answer === 'Y' || answer === 'YES') { 71 | let conf = SAMPLE_CONFIG.trim(); 72 | if (os.type() === 'Windows_NT') { 73 | // ping on Window does not support "-c" 74 | conf = conf.replace(/ping -c/gi, 'ping -n'); 75 | } 76 | fs.writeFileSync(CONFIG_FILENAME, conf, 'utf-8'); 77 | return yaml.load(SAMPLE_CONFIG); 78 | } else { 79 | console.error('Can not continue, configuration does not exist!'); 80 | process.exit(-1); 81 | } 82 | } else { 83 | try { 84 | const contents = fs.readFileSync(CONFIG_FILENAME, 'utf-8'); 85 | config = yaml.load(contents); 86 | } catch (e) { 87 | console.error('Can not load configuration file'); 88 | console.error(e.toString()); 89 | process.exit(-1); 90 | } 91 | } 92 | return config; 93 | } 94 | 95 | function workerMessageHandler(workerData) { 96 | const workerMsg = workerData.message; 97 | const { duty } = workerMsg; 98 | if (duty === 'print') { 99 | const { message } = workerMsg; 100 | console.log(message); 101 | } else if (duty === 'notify') { 102 | const { title, message } = workerMsg; 103 | pal.notify(title, message); 104 | } else if (duty === 'say') { 105 | const { message } = workerMsg; 106 | pal.say(message); 107 | } 108 | } 109 | 110 | /** 111 | * Run a task, execute the steps sequentially. 112 | */ 113 | 114 | function runTask() { 115 | const child_process = require('child_process'); 116 | const { workerData, parentPort } = require('worker_threads'); 117 | 118 | const { job } = workerData; 119 | const { steps } = job; 120 | 121 | steps.forEach((step) => { 122 | if (step.print) { 123 | parentPort.postMessage({ duty: 'print', message: step.print }); 124 | } else if (step.notify) { 125 | const title = step.title ? step.title : 'Berkala'; 126 | const message = step.notify.trim(); 127 | parentPort.postMessage({ duty: 'notify', title, message }); 128 | } else if (step.say) { 129 | parentPort.postMessage({ duty: 'say', message: step.say }); 130 | } else if (step.run) { 131 | const command = step.run; 132 | const cwd = step['working-directory'] || process.cwd(); 133 | const timeoutMinutes = step['timeout-minutes'] || 3; 134 | const timeout = 60 * 1000 * timeoutMinutes; 135 | const options = { cwd, timeout }; 136 | try { 137 | child_process.execSync(command, options); 138 | } catch (e) { 139 | const { errno, stderr } = e; 140 | const msg = stderr ? stderr.toString() : e.toString(); 141 | console.error(`run error: ${errno} ${msg}`); 142 | } 143 | } else { 144 | console.error('Unknown step', step); 145 | } 146 | }); 147 | } 148 | 149 | /** 150 | * Convert a task definition to a Bree job. 151 | */ 152 | function convert(name, task) { 153 | const { interval, cron } = task; 154 | let { steps } = task; 155 | 156 | if (!steps || !Array.isArray(steps) || steps.length === 0) { 157 | // Migrate legacy task format 158 | steps = []; 159 | const { type } = task; 160 | if (type === 'print') { 161 | const { message } = task; 162 | steps.push({ print: message }); 163 | } else if (type === 'notify') { 164 | const { message, title } = task; 165 | steps.push({ notify: message, title }); 166 | } 167 | } 168 | 169 | const path = runTask; 170 | return { 171 | name, 172 | path, 173 | interval, 174 | cron, 175 | steps 176 | }; 177 | } 178 | 179 | /** 180 | * Create a Bree instance according to the configuration. 181 | */ 182 | function setupTasks(config) { 183 | const { tasks = [] } = config; 184 | const jobs = Object.keys(tasks).map((name) => { 185 | return convert(name, tasks[name]); 186 | }); 187 | const root = false; 188 | return new Bree({ root, jobs, workerMessageHandler }); 189 | } 190 | 191 | console.log('Berkala', manifest.version); 192 | console.log(); 193 | 194 | const config = getConfig() || {}; 195 | const tasks = setupTasks(config); 196 | tasks.start(); 197 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@ariya/berkala", 3 | "version": "1.3.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@babel/helper-validator-identifier": { 8 | "version": "7.14.9", 9 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz", 10 | "integrity": "sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g==", 11 | "dev": true 12 | }, 13 | "@babel/parser": { 14 | "version": "7.13.13", 15 | "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.13.tgz", 16 | "integrity": "sha512-OhsyMrqygfk5v8HmWwOzlYjJrtLaFhF34MrfG/Z73DgYCI6ojNUTUp2TYbtnjo8PegeJp12eamsNettCQjKjVw==", 17 | "dev": true 18 | }, 19 | "@babel/runtime": { 20 | "version": "7.14.8", 21 | "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.8.tgz", 22 | "integrity": "sha512-twj3L8Og5SaCRCErB4x4ajbvBIVV77CGeFglHpeg5WC5FF8TZzBWXtTJ4MqaD9QszLYTtr+IsaAL2rEUevb+eg==", 23 | "requires": { 24 | "regenerator-runtime": "^0.13.4" 25 | } 26 | }, 27 | "@babel/types": { 28 | "version": "7.13.12", 29 | "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.12.tgz", 30 | "integrity": "sha512-K4nY2xFN4QMvQwkQ+zmBDp6ANMbVNw6BbxWmYA4qNjhR9W+Lj/8ky5MEY2Me5r+B2c6/v6F53oMndG+f9s3IiA==", 31 | "dev": true, 32 | "requires": { 33 | "@babel/helper-validator-identifier": "^7.12.11", 34 | "lodash": "^4.17.19", 35 | "to-fast-properties": "^2.0.0" 36 | } 37 | }, 38 | "@breejs/later": { 39 | "version": "4.0.2", 40 | "resolved": "https://registry.npmjs.org/@breejs/later/-/later-4.0.2.tgz", 41 | "integrity": "sha512-EN0SlbyYouBdtZis1htdsgGlwFePzkXPwdIeqaBaavxkJT1G2/bitc2LSixjv45z2njXslxlJI1mW2O/Gmrb+A==" 42 | }, 43 | "@nodelib/fs.scandir": { 44 | "version": "2.1.5", 45 | "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", 46 | "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", 47 | "dev": true, 48 | "requires": { 49 | "@nodelib/fs.stat": "2.0.5", 50 | "run-parallel": "^1.1.9" 51 | } 52 | }, 53 | "@nodelib/fs.stat": { 54 | "version": "2.0.5", 55 | "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", 56 | "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", 57 | "dev": true 58 | }, 59 | "@nodelib/fs.walk": { 60 | "version": "1.2.8", 61 | "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", 62 | "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", 63 | "dev": true, 64 | "requires": { 65 | "@nodelib/fs.scandir": "2.1.5", 66 | "fastq": "^1.6.0" 67 | } 68 | }, 69 | "@types/lodash": { 70 | "version": "4.14.172", 71 | "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.172.tgz", 72 | "integrity": "sha512-/BHF5HAx3em7/KkzVKm3LrsD6HZAXuXO1AJZQ3cRRBZj4oHZDviWPYu0aEplAqDFNHZPW6d3G7KN+ONcCCC7pw==" 73 | }, 74 | "agent-base": { 75 | "version": "6.0.2", 76 | "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", 77 | "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", 78 | "dev": true, 79 | "requires": { 80 | "debug": "4" 81 | } 82 | }, 83 | "ansi-regex": { 84 | "version": "5.0.0", 85 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", 86 | "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", 87 | "dev": true 88 | }, 89 | "ansi-styles": { 90 | "version": "4.3.0", 91 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 92 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 93 | "dev": true, 94 | "requires": { 95 | "color-convert": "^2.0.1" 96 | } 97 | }, 98 | "aproba": { 99 | "version": "1.2.0", 100 | "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", 101 | "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", 102 | "dev": true 103 | }, 104 | "are-we-there-yet": { 105 | "version": "1.1.5", 106 | "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", 107 | "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", 108 | "dev": true, 109 | "requires": { 110 | "delegates": "^1.0.0", 111 | "readable-stream": "^2.0.6" 112 | } 113 | }, 114 | "argparse": { 115 | "version": "2.0.1", 116 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", 117 | "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" 118 | }, 119 | "array-union": { 120 | "version": "2.1.0", 121 | "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", 122 | "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", 123 | "dev": true 124 | }, 125 | "at-least-node": { 126 | "version": "1.0.0", 127 | "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", 128 | "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", 129 | "dev": true 130 | }, 131 | "base64-js": { 132 | "version": "1.5.1", 133 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", 134 | "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", 135 | "dev": true 136 | }, 137 | "bats": { 138 | "version": "1.4.1", 139 | "resolved": "https://registry.npmjs.org/bats/-/bats-1.4.1.tgz", 140 | "integrity": "sha512-sZgqfOHgPqtQSD84WKQiNU3a/44hQiiHGtA43gTUPeOdl5jYhnXSBNGCa8DGlKc8JpI/UUYcaPNf0Afg3OOibQ==", 141 | "dev": true 142 | }, 143 | "bats-assert": { 144 | "version": "2.0.0", 145 | "resolved": "https://registry.npmjs.org/bats-assert/-/bats-assert-2.0.0.tgz", 146 | "integrity": "sha512-qO3kNilWxW8iCONu9NDUfvsCiC6JzL6DPOc/DGq9z3bZ9/A7wURJ+FnFMxGbofOmWbCoy7pVhofn0o47A95qkQ==", 147 | "dev": true 148 | }, 149 | "bats-support": { 150 | "version": "0.3.0", 151 | "resolved": "https://registry.npmjs.org/bats-support/-/bats-support-0.3.0.tgz", 152 | "integrity": "sha512-z+2WzXbI4OZgLnynydqH8GpI3+DcOtepO66PlK47SfEzTkiuV9hxn9eIQX+uLVFbt2Oqoc7Ky3TJ/N83lqD+cg==", 153 | "dev": true 154 | }, 155 | "bl": { 156 | "version": "4.1.0", 157 | "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", 158 | "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", 159 | "dev": true, 160 | "requires": { 161 | "buffer": "^5.5.0", 162 | "inherits": "^2.0.4", 163 | "readable-stream": "^3.4.0" 164 | }, 165 | "dependencies": { 166 | "readable-stream": { 167 | "version": "3.6.0", 168 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", 169 | "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", 170 | "dev": true, 171 | "requires": { 172 | "inherits": "^2.0.3", 173 | "string_decoder": "^1.1.1", 174 | "util-deprecate": "^1.0.1" 175 | } 176 | } 177 | } 178 | }, 179 | "boolean": { 180 | "version": "3.1.2", 181 | "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.1.2.tgz", 182 | "integrity": "sha512-YN6UmV0FfLlBVvRvNPx3pz5W/mUoYB24J4WSXOKP/OOJpi+Oq6WYqPaNTHzjI0QzwWtnvEd5CGYyQPgp1jFxnw==" 183 | }, 184 | "braces": { 185 | "version": "3.0.2", 186 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", 187 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", 188 | "dev": true, 189 | "requires": { 190 | "fill-range": "^7.0.1" 191 | } 192 | }, 193 | "bree": { 194 | "version": "6.2.1", 195 | "resolved": "https://registry.npmjs.org/bree/-/bree-6.2.1.tgz", 196 | "integrity": "sha512-apgOBJp/4onxroljplYKMUP1gxxUKhoftSh63h037avAuQLM7vrtJuyB8TYE9+dzduWkjb2CCKwfOkqEpMFdAg==", 197 | "requires": { 198 | "@babel/runtime": "^7.12.5", 199 | "@breejs/later": "^4.0.2", 200 | "boolean": "^3.0.2", 201 | "bthreads": "^0.5.1", 202 | "combine-errors": "^3.0.3", 203 | "cron-validate": "^1.4.1", 204 | "debug": "^4.3.1", 205 | "human-interval": "^2.0.0", 206 | "is-string-and-not-blank": "^0.0.2", 207 | "is-valid-path": "^0.1.1", 208 | "ms": "^2.1.2", 209 | "p-wait-for": "3.1.0", 210 | "safe-timers": "^1.1.0" 211 | } 212 | }, 213 | "bthreads": { 214 | "version": "0.5.1", 215 | "resolved": "https://registry.npmjs.org/bthreads/-/bthreads-0.5.1.tgz", 216 | "integrity": "sha512-nK7Jo9ll+r1FRMNPWEFRTZMQrX6HhX8JjPAofxmbTNILHqWVIJPmWzCi9JlX/K0DL5AKZTFZg2Qser5C6gVs9A==", 217 | "requires": { 218 | "bufio": "~1.0.5" 219 | } 220 | }, 221 | "buffer": { 222 | "version": "5.7.1", 223 | "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", 224 | "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", 225 | "dev": true, 226 | "requires": { 227 | "base64-js": "^1.3.1", 228 | "ieee754": "^1.1.13" 229 | } 230 | }, 231 | "bufio": { 232 | "version": "1.0.7", 233 | "resolved": "https://registry.npmjs.org/bufio/-/bufio-1.0.7.tgz", 234 | "integrity": "sha512-bd1dDQhiC+bEbEfg56IdBv7faWa6OipMs/AFFFvtFnB3wAYjlwQpQRZ0pm6ZkgtfL0pILRXhKxOiQj6UzoMR7A==" 235 | }, 236 | "chalk": { 237 | "version": "4.1.2", 238 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", 239 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", 240 | "dev": true, 241 | "requires": { 242 | "ansi-styles": "^4.1.0", 243 | "supports-color": "^7.1.0" 244 | } 245 | }, 246 | "chownr": { 247 | "version": "1.1.4", 248 | "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", 249 | "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", 250 | "dev": true 251 | }, 252 | "cliui": { 253 | "version": "7.0.4", 254 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", 255 | "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", 256 | "dev": true, 257 | "requires": { 258 | "string-width": "^4.2.0", 259 | "strip-ansi": "^6.0.0", 260 | "wrap-ansi": "^7.0.0" 261 | } 262 | }, 263 | "code-point-at": { 264 | "version": "1.1.0", 265 | "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", 266 | "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", 267 | "dev": true 268 | }, 269 | "color-convert": { 270 | "version": "2.0.1", 271 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 272 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 273 | "dev": true, 274 | "requires": { 275 | "color-name": "~1.1.4" 276 | } 277 | }, 278 | "color-name": { 279 | "version": "1.1.4", 280 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 281 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 282 | "dev": true 283 | }, 284 | "combine-errors": { 285 | "version": "3.0.3", 286 | "resolved": "https://registry.npmjs.org/combine-errors/-/combine-errors-3.0.3.tgz", 287 | "integrity": "sha1-9N9nQAg+VwOjGBEQwrEFUfAD2oY=", 288 | "requires": { 289 | "custom-error-instance": "2.1.1", 290 | "lodash.uniqby": "4.5.0" 291 | } 292 | }, 293 | "console-control-strings": { 294 | "version": "1.1.0", 295 | "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", 296 | "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", 297 | "dev": true 298 | }, 299 | "core-util-is": { 300 | "version": "1.0.2", 301 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 302 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", 303 | "dev": true 304 | }, 305 | "cron-validate": { 306 | "version": "1.4.3", 307 | "resolved": "https://registry.npmjs.org/cron-validate/-/cron-validate-1.4.3.tgz", 308 | "integrity": "sha512-N+qKw019oQBEPIP5Qwi8Z5XelQ00ThN6Maahwv+9UGu2u/b/MPb35zngMQI0T8pBoNiBrIXGlhvsmspNSYae/w==", 309 | "requires": { 310 | "yup": "0.32.9" 311 | } 312 | }, 313 | "custom-error-instance": { 314 | "version": "2.1.1", 315 | "resolved": "https://registry.npmjs.org/custom-error-instance/-/custom-error-instance-2.1.1.tgz", 316 | "integrity": "sha1-PPY5FIemYppiR+sMoM4ACBt+Nho=" 317 | }, 318 | "debug": { 319 | "version": "4.3.2", 320 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", 321 | "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", 322 | "requires": { 323 | "ms": "2.1.2" 324 | }, 325 | "dependencies": { 326 | "ms": { 327 | "version": "2.1.2", 328 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 329 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 330 | } 331 | } 332 | }, 333 | "decompress-response": { 334 | "version": "4.2.1", 335 | "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", 336 | "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", 337 | "dev": true, 338 | "requires": { 339 | "mimic-response": "^2.0.0" 340 | } 341 | }, 342 | "deep-extend": { 343 | "version": "0.6.0", 344 | "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", 345 | "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", 346 | "dev": true 347 | }, 348 | "deep-is": { 349 | "version": "0.1.3", 350 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", 351 | "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", 352 | "dev": true 353 | }, 354 | "delegates": { 355 | "version": "1.0.0", 356 | "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", 357 | "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", 358 | "dev": true 359 | }, 360 | "detect-libc": { 361 | "version": "1.0.3", 362 | "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", 363 | "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", 364 | "dev": true 365 | }, 366 | "dir-glob": { 367 | "version": "3.0.1", 368 | "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", 369 | "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", 370 | "dev": true, 371 | "requires": { 372 | "path-type": "^4.0.0" 373 | } 374 | }, 375 | "emoji-regex": { 376 | "version": "8.0.0", 377 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 378 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 379 | "dev": true 380 | }, 381 | "end-of-stream": { 382 | "version": "1.4.4", 383 | "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", 384 | "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", 385 | "dev": true, 386 | "requires": { 387 | "once": "^1.4.0" 388 | } 389 | }, 390 | "escalade": { 391 | "version": "3.1.1", 392 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", 393 | "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", 394 | "dev": true 395 | }, 396 | "escodegen": { 397 | "version": "2.0.0", 398 | "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", 399 | "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", 400 | "dev": true, 401 | "requires": { 402 | "esprima": "^4.0.1", 403 | "estraverse": "^5.2.0", 404 | "esutils": "^2.0.2", 405 | "optionator": "^0.8.1", 406 | "source-map": "~0.6.1" 407 | } 408 | }, 409 | "esprima": { 410 | "version": "4.0.1", 411 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", 412 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", 413 | "dev": true 414 | }, 415 | "estraverse": { 416 | "version": "5.2.0", 417 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", 418 | "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", 419 | "dev": true 420 | }, 421 | "esutils": { 422 | "version": "2.0.3", 423 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", 424 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", 425 | "dev": true 426 | }, 427 | "expand-template": { 428 | "version": "2.0.3", 429 | "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", 430 | "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", 431 | "dev": true 432 | }, 433 | "fast-glob": { 434 | "version": "3.2.7", 435 | "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", 436 | "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", 437 | "dev": true, 438 | "requires": { 439 | "@nodelib/fs.stat": "^2.0.2", 440 | "@nodelib/fs.walk": "^1.2.3", 441 | "glob-parent": "^5.1.2", 442 | "merge2": "^1.3.0", 443 | "micromatch": "^4.0.4" 444 | } 445 | }, 446 | "fast-levenshtein": { 447 | "version": "2.0.6", 448 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 449 | "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", 450 | "dev": true 451 | }, 452 | "fastq": { 453 | "version": "1.11.1", 454 | "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.1.tgz", 455 | "integrity": "sha512-HOnr8Mc60eNYl1gzwp6r5RoUyAn5/glBolUzP/Ez6IFVPMPirxn/9phgL6zhOtaTy7ISwPvQ+wT+hfcRZh/bzw==", 456 | "dev": true, 457 | "requires": { 458 | "reusify": "^1.0.4" 459 | } 460 | }, 461 | "fill-range": { 462 | "version": "7.0.1", 463 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", 464 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", 465 | "dev": true, 466 | "requires": { 467 | "to-regex-range": "^5.0.1" 468 | } 469 | }, 470 | "from2": { 471 | "version": "2.3.0", 472 | "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", 473 | "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", 474 | "dev": true, 475 | "requires": { 476 | "inherits": "^2.0.1", 477 | "readable-stream": "^2.0.0" 478 | } 479 | }, 480 | "fs-constants": { 481 | "version": "1.0.0", 482 | "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", 483 | "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", 484 | "dev": true 485 | }, 486 | "fs-extra": { 487 | "version": "9.1.0", 488 | "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", 489 | "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", 490 | "dev": true, 491 | "requires": { 492 | "at-least-node": "^1.0.0", 493 | "graceful-fs": "^4.2.0", 494 | "jsonfile": "^6.0.1", 495 | "universalify": "^2.0.0" 496 | } 497 | }, 498 | "function-bind": { 499 | "version": "1.1.1", 500 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 501 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", 502 | "dev": true 503 | }, 504 | "gauge": { 505 | "version": "2.7.4", 506 | "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", 507 | "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", 508 | "dev": true, 509 | "requires": { 510 | "aproba": "^1.0.3", 511 | "console-control-strings": "^1.0.0", 512 | "has-unicode": "^2.0.0", 513 | "object-assign": "^4.1.0", 514 | "signal-exit": "^3.0.0", 515 | "string-width": "^1.0.1", 516 | "strip-ansi": "^3.0.1", 517 | "wide-align": "^1.1.0" 518 | }, 519 | "dependencies": { 520 | "ansi-regex": { 521 | "version": "2.1.1", 522 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", 523 | "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", 524 | "dev": true 525 | }, 526 | "is-fullwidth-code-point": { 527 | "version": "1.0.0", 528 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", 529 | "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", 530 | "dev": true, 531 | "requires": { 532 | "number-is-nan": "^1.0.0" 533 | } 534 | }, 535 | "string-width": { 536 | "version": "1.0.2", 537 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", 538 | "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", 539 | "dev": true, 540 | "requires": { 541 | "code-point-at": "^1.0.0", 542 | "is-fullwidth-code-point": "^1.0.0", 543 | "strip-ansi": "^3.0.0" 544 | } 545 | }, 546 | "strip-ansi": { 547 | "version": "3.0.1", 548 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", 549 | "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", 550 | "dev": true, 551 | "requires": { 552 | "ansi-regex": "^2.0.0" 553 | } 554 | } 555 | } 556 | }, 557 | "get-caller-file": { 558 | "version": "2.0.5", 559 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", 560 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", 561 | "dev": true 562 | }, 563 | "github-from-package": { 564 | "version": "0.0.0", 565 | "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", 566 | "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=", 567 | "dev": true 568 | }, 569 | "glob-parent": { 570 | "version": "5.1.2", 571 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 572 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 573 | "dev": true, 574 | "requires": { 575 | "is-glob": "^4.0.1" 576 | }, 577 | "dependencies": { 578 | "is-extglob": { 579 | "version": "2.1.1", 580 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 581 | "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", 582 | "dev": true 583 | }, 584 | "is-glob": { 585 | "version": "4.0.1", 586 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", 587 | "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", 588 | "dev": true, 589 | "requires": { 590 | "is-extglob": "^2.1.1" 591 | } 592 | } 593 | } 594 | }, 595 | "globby": { 596 | "version": "11.0.4", 597 | "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", 598 | "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", 599 | "dev": true, 600 | "requires": { 601 | "array-union": "^2.1.0", 602 | "dir-glob": "^3.0.1", 603 | "fast-glob": "^3.1.1", 604 | "ignore": "^5.1.4", 605 | "merge2": "^1.3.0", 606 | "slash": "^3.0.0" 607 | } 608 | }, 609 | "graceful-fs": { 610 | "version": "4.2.7", 611 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.7.tgz", 612 | "integrity": "sha512-b1suB8r7mlSJQIBs6typf13fz55WYPeE7/KYlQUvqB7E3hUkXhz4D8FVHkENHTqG8+mD2yyT9HgT5bNkGNiqeQ==", 613 | "dev": true 614 | }, 615 | "has": { 616 | "version": "1.0.3", 617 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 618 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 619 | "dev": true, 620 | "requires": { 621 | "function-bind": "^1.1.1" 622 | } 623 | }, 624 | "has-flag": { 625 | "version": "4.0.0", 626 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 627 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 628 | "dev": true 629 | }, 630 | "has-unicode": { 631 | "version": "2.0.1", 632 | "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", 633 | "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", 634 | "dev": true 635 | }, 636 | "https-proxy-agent": { 637 | "version": "5.0.0", 638 | "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", 639 | "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", 640 | "dev": true, 641 | "requires": { 642 | "agent-base": "6", 643 | "debug": "4" 644 | } 645 | }, 646 | "human-interval": { 647 | "version": "2.0.1", 648 | "resolved": "https://registry.npmjs.org/human-interval/-/human-interval-2.0.1.tgz", 649 | "integrity": "sha512-r4Aotzf+OtKIGQCB3odUowy4GfUDTy3aTWTfLd7ZF2gBCy3XW3v/dJLRefZnOFFnjqs5B1TypvS8WarpBkYUNQ==", 650 | "requires": { 651 | "numbered": "^1.1.0" 652 | } 653 | }, 654 | "ieee754": { 655 | "version": "1.2.1", 656 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", 657 | "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", 658 | "dev": true 659 | }, 660 | "ignore": { 661 | "version": "5.1.8", 662 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", 663 | "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", 664 | "dev": true 665 | }, 666 | "inherits": { 667 | "version": "2.0.4", 668 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 669 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 670 | "dev": true 671 | }, 672 | "ini": { 673 | "version": "1.3.8", 674 | "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", 675 | "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", 676 | "dev": true 677 | }, 678 | "into-stream": { 679 | "version": "6.0.0", 680 | "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-6.0.0.tgz", 681 | "integrity": "sha512-XHbaOAvP+uFKUFsOgoNPRjLkwB+I22JFPFe5OjTkQ0nwgj6+pSjb4NmB6VMxaPshLiOf+zcpOCBQuLwC1KHhZA==", 682 | "dev": true, 683 | "requires": { 684 | "from2": "^2.3.0", 685 | "p-is-promise": "^3.0.0" 686 | } 687 | }, 688 | "is-core-module": { 689 | "version": "2.5.0", 690 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.5.0.tgz", 691 | "integrity": "sha512-TXCMSDsEHMEEZ6eCA8rwRDbLu55MRGmrctljsBX/2v1d9/GzqHOxW5c5oPSgrUt2vBFXebu9rGqckXGPWOlYpg==", 692 | "dev": true, 693 | "requires": { 694 | "has": "^1.0.3" 695 | } 696 | }, 697 | "is-extglob": { 698 | "version": "1.0.0", 699 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", 700 | "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" 701 | }, 702 | "is-fullwidth-code-point": { 703 | "version": "3.0.0", 704 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 705 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", 706 | "dev": true 707 | }, 708 | "is-glob": { 709 | "version": "2.0.1", 710 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", 711 | "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", 712 | "requires": { 713 | "is-extglob": "^1.0.0" 714 | } 715 | }, 716 | "is-invalid-path": { 717 | "version": "0.1.0", 718 | "resolved": "https://registry.npmjs.org/is-invalid-path/-/is-invalid-path-0.1.0.tgz", 719 | "integrity": "sha1-MHqFWzzxqTi0TqcNLGEQYFNxTzQ=", 720 | "requires": { 721 | "is-glob": "^2.0.0" 722 | } 723 | }, 724 | "is-number": { 725 | "version": "7.0.0", 726 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 727 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 728 | "dev": true 729 | }, 730 | "is-string-and-not-blank": { 731 | "version": "0.0.2", 732 | "resolved": "https://registry.npmjs.org/is-string-and-not-blank/-/is-string-and-not-blank-0.0.2.tgz", 733 | "integrity": "sha512-FyPGAbNVyZpTeDCTXnzuwbu9/WpNXbCfbHXLpCRpN4GANhS00eEIP5Ef+k5HYSNIzIhdN9zRDoBj6unscECvtQ==", 734 | "requires": { 735 | "is-string-blank": "^1.0.1" 736 | } 737 | }, 738 | "is-string-blank": { 739 | "version": "1.0.1", 740 | "resolved": "https://registry.npmjs.org/is-string-blank/-/is-string-blank-1.0.1.tgz", 741 | "integrity": "sha512-9H+ZBCVs3L9OYqv8nuUAzpcT9OTgMD1yAWrG7ihlnibdkbtB850heAmYWxHuXc4CHy4lKeK69tN+ny1K7gBIrw==" 742 | }, 743 | "is-valid-path": { 744 | "version": "0.1.1", 745 | "resolved": "https://registry.npmjs.org/is-valid-path/-/is-valid-path-0.1.1.tgz", 746 | "integrity": "sha1-EQ+f90w39mPh7HkV60UfLbk6yd8=", 747 | "requires": { 748 | "is-invalid-path": "^0.1.0" 749 | } 750 | }, 751 | "isarray": { 752 | "version": "1.0.0", 753 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 754 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", 755 | "dev": true 756 | }, 757 | "isexe": { 758 | "version": "2.0.0", 759 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 760 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" 761 | }, 762 | "js-yaml": { 763 | "version": "4.1.0", 764 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", 765 | "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", 766 | "requires": { 767 | "argparse": "^2.0.1" 768 | } 769 | }, 770 | "jsonfile": { 771 | "version": "6.1.0", 772 | "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", 773 | "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", 774 | "dev": true, 775 | "requires": { 776 | "graceful-fs": "^4.1.6", 777 | "universalify": "^2.0.0" 778 | } 779 | }, 780 | "levn": { 781 | "version": "0.3.0", 782 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", 783 | "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", 784 | "dev": true, 785 | "requires": { 786 | "prelude-ls": "~1.1.2", 787 | "type-check": "~0.3.2" 788 | } 789 | }, 790 | "lodash": { 791 | "version": "4.17.21", 792 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", 793 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" 794 | }, 795 | "lodash-es": { 796 | "version": "4.17.21", 797 | "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", 798 | "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" 799 | }, 800 | "lodash._baseiteratee": { 801 | "version": "4.7.0", 802 | "resolved": "https://registry.npmjs.org/lodash._baseiteratee/-/lodash._baseiteratee-4.7.0.tgz", 803 | "integrity": "sha1-NKm1VDVycnw9sueO2uPA6eZr0QI=", 804 | "requires": { 805 | "lodash._stringtopath": "~4.8.0" 806 | } 807 | }, 808 | "lodash._basetostring": { 809 | "version": "4.12.0", 810 | "resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-4.12.0.tgz", 811 | "integrity": "sha1-kyfJ3FFYhmt/pLnUL0Y45XZt2d8=" 812 | }, 813 | "lodash._baseuniq": { 814 | "version": "4.6.0", 815 | "resolved": "https://registry.npmjs.org/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz", 816 | "integrity": "sha1-DrtE5FaBSveQXGIS+iybLVG4Qeg=", 817 | "requires": { 818 | "lodash._createset": "~4.0.0", 819 | "lodash._root": "~3.0.0" 820 | } 821 | }, 822 | "lodash._createset": { 823 | "version": "4.0.3", 824 | "resolved": "https://registry.npmjs.org/lodash._createset/-/lodash._createset-4.0.3.tgz", 825 | "integrity": "sha1-D0ZZ+7CddRlPqeK4imZE02PJ/iY=" 826 | }, 827 | "lodash._root": { 828 | "version": "3.0.1", 829 | "resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz", 830 | "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=" 831 | }, 832 | "lodash._stringtopath": { 833 | "version": "4.8.0", 834 | "resolved": "https://registry.npmjs.org/lodash._stringtopath/-/lodash._stringtopath-4.8.0.tgz", 835 | "integrity": "sha1-lBvPDmQmbl/B1m/tCmlZVExXaCQ=", 836 | "requires": { 837 | "lodash._basetostring": "~4.12.0" 838 | } 839 | }, 840 | "lodash.uniqby": { 841 | "version": "4.5.0", 842 | "resolved": "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.5.0.tgz", 843 | "integrity": "sha1-o6F7v2LutiQPSRhG6XwcTipeHiE=", 844 | "requires": { 845 | "lodash._baseiteratee": "~4.7.0", 846 | "lodash._baseuniq": "~4.6.0" 847 | } 848 | }, 849 | "lru-cache": { 850 | "version": "6.0.0", 851 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", 852 | "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", 853 | "dev": true, 854 | "requires": { 855 | "yallist": "^4.0.0" 856 | } 857 | }, 858 | "merge2": { 859 | "version": "1.4.1", 860 | "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", 861 | "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", 862 | "dev": true 863 | }, 864 | "micromatch": { 865 | "version": "4.0.4", 866 | "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", 867 | "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", 868 | "dev": true, 869 | "requires": { 870 | "braces": "^3.0.1", 871 | "picomatch": "^2.2.3" 872 | } 873 | }, 874 | "mimic-response": { 875 | "version": "2.1.0", 876 | "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", 877 | "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", 878 | "dev": true 879 | }, 880 | "minimist": { 881 | "version": "1.2.5", 882 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", 883 | "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", 884 | "dev": true 885 | }, 886 | "mkdirp-classic": { 887 | "version": "0.5.3", 888 | "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", 889 | "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", 890 | "dev": true 891 | }, 892 | "ms": { 893 | "version": "2.1.3", 894 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 895 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 896 | }, 897 | "multistream": { 898 | "version": "4.1.0", 899 | "resolved": "https://registry.npmjs.org/multistream/-/multistream-4.1.0.tgz", 900 | "integrity": "sha512-J1XDiAmmNpRCBfIWJv+n0ymC4ABcf/Pl+5YvC5B/D2f/2+8PtHvCNxMPKiQcZyi922Hq69J2YOpb1pTywfifyw==", 901 | "dev": true, 902 | "requires": { 903 | "once": "^1.4.0", 904 | "readable-stream": "^3.6.0" 905 | }, 906 | "dependencies": { 907 | "readable-stream": { 908 | "version": "3.6.0", 909 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", 910 | "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", 911 | "dev": true, 912 | "requires": { 913 | "inherits": "^2.0.3", 914 | "string_decoder": "^1.1.1", 915 | "util-deprecate": "^1.0.1" 916 | } 917 | } 918 | } 919 | }, 920 | "nanoclone": { 921 | "version": "0.2.1", 922 | "resolved": "https://registry.npmjs.org/nanoclone/-/nanoclone-0.2.1.tgz", 923 | "integrity": "sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA==" 924 | }, 925 | "napi-build-utils": { 926 | "version": "1.0.2", 927 | "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", 928 | "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", 929 | "dev": true 930 | }, 931 | "node-abi": { 932 | "version": "2.30.0", 933 | "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.30.0.tgz", 934 | "integrity": "sha512-g6bZh3YCKQRdwuO/tSZZYJAw622SjsRfJ2X0Iy4sSOHZ34/sPPdVBn8fev2tj7njzLwuqPw9uMtGsGkO5kIQvg==", 935 | "dev": true, 936 | "requires": { 937 | "semver": "^5.4.1" 938 | }, 939 | "dependencies": { 940 | "semver": { 941 | "version": "5.7.1", 942 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", 943 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", 944 | "dev": true 945 | } 946 | } 947 | }, 948 | "node-fetch": { 949 | "version": "2.6.1", 950 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", 951 | "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", 952 | "dev": true 953 | }, 954 | "noop-logger": { 955 | "version": "0.1.1", 956 | "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", 957 | "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=", 958 | "dev": true 959 | }, 960 | "npmlog": { 961 | "version": "4.1.2", 962 | "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", 963 | "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", 964 | "dev": true, 965 | "requires": { 966 | "are-we-there-yet": "~1.1.2", 967 | "console-control-strings": "~1.1.0", 968 | "gauge": "~2.7.3", 969 | "set-blocking": "~2.0.0" 970 | } 971 | }, 972 | "number-is-nan": { 973 | "version": "1.0.1", 974 | "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", 975 | "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", 976 | "dev": true 977 | }, 978 | "numbered": { 979 | "version": "1.1.0", 980 | "resolved": "https://registry.npmjs.org/numbered/-/numbered-1.1.0.tgz", 981 | "integrity": "sha512-pv/ue2Odr7IfYOO0byC1KgBI10wo5YDauLhxY6/saNzAdAs0r1SotGCPzzCLNPL0xtrAwWRialLu23AAu9xO1g==" 982 | }, 983 | "object-assign": { 984 | "version": "4.1.1", 985 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 986 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", 987 | "dev": true 988 | }, 989 | "once": { 990 | "version": "1.4.0", 991 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 992 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 993 | "dev": true, 994 | "requires": { 995 | "wrappy": "1" 996 | } 997 | }, 998 | "one-time": { 999 | "version": "0.0.4", 1000 | "resolved": "https://registry.npmjs.org/one-time/-/one-time-0.0.4.tgz", 1001 | "integrity": "sha1-+M33eISCb+Tf+T46nMN7HkSAdC4=" 1002 | }, 1003 | "optionator": { 1004 | "version": "0.8.3", 1005 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", 1006 | "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", 1007 | "dev": true, 1008 | "requires": { 1009 | "deep-is": "~0.1.3", 1010 | "fast-levenshtein": "~2.0.6", 1011 | "levn": "~0.3.0", 1012 | "prelude-ls": "~1.1.2", 1013 | "type-check": "~0.3.2", 1014 | "word-wrap": "~1.2.3" 1015 | } 1016 | }, 1017 | "p-finally": { 1018 | "version": "1.0.0", 1019 | "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", 1020 | "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" 1021 | }, 1022 | "p-is-promise": { 1023 | "version": "3.0.0", 1024 | "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-3.0.0.tgz", 1025 | "integrity": "sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ==", 1026 | "dev": true 1027 | }, 1028 | "p-timeout": { 1029 | "version": "3.2.0", 1030 | "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", 1031 | "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", 1032 | "requires": { 1033 | "p-finally": "^1.0.0" 1034 | } 1035 | }, 1036 | "p-wait-for": { 1037 | "version": "3.1.0", 1038 | "resolved": "https://registry.npmjs.org/p-wait-for/-/p-wait-for-3.1.0.tgz", 1039 | "integrity": "sha512-0Uy19uhxbssHelu9ynDMcON6BmMk6pH8551CvxROhiz3Vx+yC4RqxjyIDk2V4ll0g9177RKT++PK4zcV58uJ7A==", 1040 | "requires": { 1041 | "p-timeout": "^3.0.0" 1042 | } 1043 | }, 1044 | "path-parse": { 1045 | "version": "1.0.7", 1046 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", 1047 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", 1048 | "dev": true 1049 | }, 1050 | "path-type": { 1051 | "version": "4.0.0", 1052 | "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", 1053 | "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", 1054 | "dev": true 1055 | }, 1056 | "picomatch": { 1057 | "version": "2.3.0", 1058 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", 1059 | "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", 1060 | "dev": true 1061 | }, 1062 | "pkg": { 1063 | "version": "5.3.1", 1064 | "resolved": "https://registry.npmjs.org/pkg/-/pkg-5.3.1.tgz", 1065 | "integrity": "sha512-jT/sptM1ZG++FNk+jnJYNoWLDQXYd7hqpnBhd5j18SNW1jJzNYo55RahuCiD0KN0PX9mb53GWCqKM0ia/mJytA==", 1066 | "dev": true, 1067 | "requires": { 1068 | "@babel/parser": "7.13.13", 1069 | "@babel/types": "7.13.12", 1070 | "chalk": "^4.1.0", 1071 | "escodegen": "^2.0.0", 1072 | "fs-extra": "^9.1.0", 1073 | "globby": "^11.0.3", 1074 | "into-stream": "^6.0.0", 1075 | "minimist": "^1.2.5", 1076 | "multistream": "^4.1.0", 1077 | "pkg-fetch": "3.2.2", 1078 | "prebuild-install": "6.0.1", 1079 | "progress": "^2.0.3", 1080 | "resolve": "^1.20.0", 1081 | "stream-meter": "^1.0.4", 1082 | "tslib": "2.1.0" 1083 | } 1084 | }, 1085 | "pkg-fetch": { 1086 | "version": "3.2.2", 1087 | "resolved": "https://registry.npmjs.org/pkg-fetch/-/pkg-fetch-3.2.2.tgz", 1088 | "integrity": "sha512-bLhFNT4cNnONxzbHo1H2mCCKuQkCR4dgQtv0gUZnWtp8TDP0v0UAXKHG7DXhAoTC5IYP3slLsFJtIda9ksny8g==", 1089 | "dev": true, 1090 | "requires": { 1091 | "chalk": "^4.1.0", 1092 | "fs-extra": "^9.1.0", 1093 | "https-proxy-agent": "^5.0.0", 1094 | "node-fetch": "^2.6.1", 1095 | "progress": "^2.0.3", 1096 | "semver": "^7.3.5", 1097 | "yargs": "^16.2.0" 1098 | } 1099 | }, 1100 | "prebuild-install": { 1101 | "version": "6.0.1", 1102 | "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-6.0.1.tgz", 1103 | "integrity": "sha512-7GOJrLuow8yeiyv75rmvZyeMGzl8mdEX5gY69d6a6bHWmiPevwqFw+tQavhK0EYMaSg3/KD24cWqeQv1EWsqDQ==", 1104 | "dev": true, 1105 | "requires": { 1106 | "detect-libc": "^1.0.3", 1107 | "expand-template": "^2.0.3", 1108 | "github-from-package": "0.0.0", 1109 | "minimist": "^1.2.3", 1110 | "mkdirp-classic": "^0.5.3", 1111 | "napi-build-utils": "^1.0.1", 1112 | "node-abi": "^2.7.0", 1113 | "noop-logger": "^0.1.1", 1114 | "npmlog": "^4.0.1", 1115 | "pump": "^3.0.0", 1116 | "rc": "^1.2.7", 1117 | "simple-get": "^3.0.3", 1118 | "tar-fs": "^2.0.0", 1119 | "tunnel-agent": "^0.6.0", 1120 | "which-pm-runs": "^1.0.0" 1121 | } 1122 | }, 1123 | "prelude-ls": { 1124 | "version": "1.1.2", 1125 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", 1126 | "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", 1127 | "dev": true 1128 | }, 1129 | "prettier": { 1130 | "version": "2.3.2", 1131 | "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.2.tgz", 1132 | "integrity": "sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==", 1133 | "dev": true 1134 | }, 1135 | "process-nextick-args": { 1136 | "version": "2.0.1", 1137 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", 1138 | "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", 1139 | "dev": true 1140 | }, 1141 | "progress": { 1142 | "version": "2.0.3", 1143 | "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", 1144 | "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", 1145 | "dev": true 1146 | }, 1147 | "property-expr": { 1148 | "version": "2.0.4", 1149 | "resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.4.tgz", 1150 | "integrity": "sha512-sFPkHQjVKheDNnPvotjQmm3KD3uk1fWKUN7CrpdbwmUx3CrG3QiM8QpTSimvig5vTXmTvjz7+TDvXOI9+4rkcg==" 1151 | }, 1152 | "pump": { 1153 | "version": "3.0.0", 1154 | "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", 1155 | "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", 1156 | "dev": true, 1157 | "requires": { 1158 | "end-of-stream": "^1.1.0", 1159 | "once": "^1.3.1" 1160 | } 1161 | }, 1162 | "queue-microtask": { 1163 | "version": "1.2.3", 1164 | "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", 1165 | "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", 1166 | "dev": true 1167 | }, 1168 | "rc": { 1169 | "version": "1.2.8", 1170 | "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", 1171 | "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", 1172 | "dev": true, 1173 | "requires": { 1174 | "deep-extend": "^0.6.0", 1175 | "ini": "~1.3.0", 1176 | "minimist": "^1.2.0", 1177 | "strip-json-comments": "~2.0.1" 1178 | } 1179 | }, 1180 | "readable-stream": { 1181 | "version": "2.3.7", 1182 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", 1183 | "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", 1184 | "dev": true, 1185 | "requires": { 1186 | "core-util-is": "~1.0.0", 1187 | "inherits": "~2.0.3", 1188 | "isarray": "~1.0.0", 1189 | "process-nextick-args": "~2.0.0", 1190 | "safe-buffer": "~5.1.1", 1191 | "string_decoder": "~1.1.1", 1192 | "util-deprecate": "~1.0.1" 1193 | } 1194 | }, 1195 | "readline-sync": { 1196 | "version": "1.4.10", 1197 | "resolved": "https://registry.npmjs.org/readline-sync/-/readline-sync-1.4.10.tgz", 1198 | "integrity": "sha512-gNva8/6UAe8QYepIQH/jQ2qn91Qj0B9sYjMBBs3QOB8F2CXcKgLxQaJRP76sWVRQt+QU+8fAkCbCvjjMFu7Ycw==" 1199 | }, 1200 | "regenerator-runtime": { 1201 | "version": "0.13.9", 1202 | "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", 1203 | "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" 1204 | }, 1205 | "require-directory": { 1206 | "version": "2.1.1", 1207 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", 1208 | "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", 1209 | "dev": true 1210 | }, 1211 | "resolve": { 1212 | "version": "1.20.0", 1213 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", 1214 | "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", 1215 | "dev": true, 1216 | "requires": { 1217 | "is-core-module": "^2.2.0", 1218 | "path-parse": "^1.0.6" 1219 | } 1220 | }, 1221 | "reusify": { 1222 | "version": "1.0.4", 1223 | "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", 1224 | "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", 1225 | "dev": true 1226 | }, 1227 | "run-parallel": { 1228 | "version": "1.2.0", 1229 | "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", 1230 | "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", 1231 | "dev": true, 1232 | "requires": { 1233 | "queue-microtask": "^1.2.2" 1234 | } 1235 | }, 1236 | "safe-buffer": { 1237 | "version": "5.1.2", 1238 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 1239 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", 1240 | "dev": true 1241 | }, 1242 | "safe-timers": { 1243 | "version": "1.1.0", 1244 | "resolved": "https://registry.npmjs.org/safe-timers/-/safe-timers-1.1.0.tgz", 1245 | "integrity": "sha1-xYroMl2407BnMi8KTvOgytZ6rYM=" 1246 | }, 1247 | "say": { 1248 | "version": "0.16.0", 1249 | "resolved": "https://registry.npmjs.org/say/-/say-0.16.0.tgz", 1250 | "integrity": "sha512-yEfncNu3I6lcZ6RIrXgE9DqbrEmvV5uQQ8ReM14u/DodlvJYpveqNphO55RLMSj77b06ZKNif/FLmhzQxcuUXg==", 1251 | "requires": { 1252 | "one-time": "0.0.4" 1253 | } 1254 | }, 1255 | "semver": { 1256 | "version": "7.3.5", 1257 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", 1258 | "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", 1259 | "dev": true, 1260 | "requires": { 1261 | "lru-cache": "^6.0.0" 1262 | } 1263 | }, 1264 | "set-blocking": { 1265 | "version": "2.0.0", 1266 | "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", 1267 | "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", 1268 | "dev": true 1269 | }, 1270 | "signal-exit": { 1271 | "version": "3.0.3", 1272 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", 1273 | "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", 1274 | "dev": true 1275 | }, 1276 | "simple-concat": { 1277 | "version": "1.0.1", 1278 | "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", 1279 | "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", 1280 | "dev": true 1281 | }, 1282 | "simple-get": { 1283 | "version": "3.1.0", 1284 | "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz", 1285 | "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==", 1286 | "dev": true, 1287 | "requires": { 1288 | "decompress-response": "^4.2.0", 1289 | "once": "^1.3.1", 1290 | "simple-concat": "^1.0.0" 1291 | } 1292 | }, 1293 | "slash": { 1294 | "version": "3.0.0", 1295 | "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", 1296 | "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", 1297 | "dev": true 1298 | }, 1299 | "source-map": { 1300 | "version": "0.6.1", 1301 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 1302 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 1303 | "dev": true, 1304 | "optional": true 1305 | }, 1306 | "stream-meter": { 1307 | "version": "1.0.4", 1308 | "resolved": "https://registry.npmjs.org/stream-meter/-/stream-meter-1.0.4.tgz", 1309 | "integrity": "sha1-Uq+Vql6nYKJJFxZwTb/5D3Ov3R0=", 1310 | "dev": true, 1311 | "requires": { 1312 | "readable-stream": "^2.1.4" 1313 | } 1314 | }, 1315 | "string-width": { 1316 | "version": "4.2.2", 1317 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", 1318 | "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", 1319 | "dev": true, 1320 | "requires": { 1321 | "emoji-regex": "^8.0.0", 1322 | "is-fullwidth-code-point": "^3.0.0", 1323 | "strip-ansi": "^6.0.0" 1324 | } 1325 | }, 1326 | "string_decoder": { 1327 | "version": "1.1.1", 1328 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 1329 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 1330 | "dev": true, 1331 | "requires": { 1332 | "safe-buffer": "~5.1.0" 1333 | } 1334 | }, 1335 | "strip-ansi": { 1336 | "version": "6.0.0", 1337 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", 1338 | "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", 1339 | "dev": true, 1340 | "requires": { 1341 | "ansi-regex": "^5.0.0" 1342 | } 1343 | }, 1344 | "strip-json-comments": { 1345 | "version": "2.0.1", 1346 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", 1347 | "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", 1348 | "dev": true 1349 | }, 1350 | "supports-color": { 1351 | "version": "7.2.0", 1352 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 1353 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 1354 | "dev": true, 1355 | "requires": { 1356 | "has-flag": "^4.0.0" 1357 | } 1358 | }, 1359 | "tar-fs": { 1360 | "version": "2.1.1", 1361 | "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", 1362 | "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", 1363 | "dev": true, 1364 | "requires": { 1365 | "chownr": "^1.1.1", 1366 | "mkdirp-classic": "^0.5.2", 1367 | "pump": "^3.0.0", 1368 | "tar-stream": "^2.1.4" 1369 | } 1370 | }, 1371 | "tar-stream": { 1372 | "version": "2.2.0", 1373 | "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", 1374 | "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", 1375 | "dev": true, 1376 | "requires": { 1377 | "bl": "^4.0.3", 1378 | "end-of-stream": "^1.4.1", 1379 | "fs-constants": "^1.0.0", 1380 | "inherits": "^2.0.3", 1381 | "readable-stream": "^3.1.1" 1382 | }, 1383 | "dependencies": { 1384 | "readable-stream": { 1385 | "version": "3.6.0", 1386 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", 1387 | "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", 1388 | "dev": true, 1389 | "requires": { 1390 | "inherits": "^2.0.3", 1391 | "string_decoder": "^1.1.1", 1392 | "util-deprecate": "^1.0.1" 1393 | } 1394 | } 1395 | } 1396 | }, 1397 | "to-fast-properties": { 1398 | "version": "2.0.0", 1399 | "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", 1400 | "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", 1401 | "dev": true 1402 | }, 1403 | "to-regex-range": { 1404 | "version": "5.0.1", 1405 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 1406 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 1407 | "dev": true, 1408 | "requires": { 1409 | "is-number": "^7.0.0" 1410 | } 1411 | }, 1412 | "toposort": { 1413 | "version": "2.0.2", 1414 | "resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz", 1415 | "integrity": "sha1-riF2gXXRVZ1IvvNUILL0li8JwzA=" 1416 | }, 1417 | "tslib": { 1418 | "version": "2.1.0", 1419 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", 1420 | "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==", 1421 | "dev": true 1422 | }, 1423 | "tunnel-agent": { 1424 | "version": "0.6.0", 1425 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", 1426 | "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", 1427 | "dev": true, 1428 | "requires": { 1429 | "safe-buffer": "^5.0.1" 1430 | } 1431 | }, 1432 | "type-check": { 1433 | "version": "0.3.2", 1434 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", 1435 | "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", 1436 | "dev": true, 1437 | "requires": { 1438 | "prelude-ls": "~1.1.2" 1439 | } 1440 | }, 1441 | "universalify": { 1442 | "version": "2.0.0", 1443 | "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", 1444 | "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", 1445 | "dev": true 1446 | }, 1447 | "util-deprecate": { 1448 | "version": "1.0.2", 1449 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 1450 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", 1451 | "dev": true 1452 | }, 1453 | "which": { 1454 | "version": "2.0.2", 1455 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 1456 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 1457 | "requires": { 1458 | "isexe": "^2.0.0" 1459 | } 1460 | }, 1461 | "which-pm-runs": { 1462 | "version": "1.0.0", 1463 | "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", 1464 | "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=", 1465 | "dev": true 1466 | }, 1467 | "wide-align": { 1468 | "version": "1.1.3", 1469 | "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", 1470 | "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", 1471 | "dev": true, 1472 | "requires": { 1473 | "string-width": "^1.0.2 || 2" 1474 | }, 1475 | "dependencies": { 1476 | "ansi-regex": { 1477 | "version": "3.0.0", 1478 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", 1479 | "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", 1480 | "dev": true 1481 | }, 1482 | "is-fullwidth-code-point": { 1483 | "version": "2.0.0", 1484 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 1485 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", 1486 | "dev": true 1487 | }, 1488 | "string-width": { 1489 | "version": "2.1.1", 1490 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", 1491 | "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", 1492 | "dev": true, 1493 | "requires": { 1494 | "is-fullwidth-code-point": "^2.0.0", 1495 | "strip-ansi": "^4.0.0" 1496 | } 1497 | }, 1498 | "strip-ansi": { 1499 | "version": "4.0.0", 1500 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", 1501 | "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", 1502 | "dev": true, 1503 | "requires": { 1504 | "ansi-regex": "^3.0.0" 1505 | } 1506 | } 1507 | } 1508 | }, 1509 | "word-wrap": { 1510 | "version": "1.2.3", 1511 | "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", 1512 | "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", 1513 | "dev": true 1514 | }, 1515 | "wrap-ansi": { 1516 | "version": "7.0.0", 1517 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", 1518 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", 1519 | "dev": true, 1520 | "requires": { 1521 | "ansi-styles": "^4.0.0", 1522 | "string-width": "^4.1.0", 1523 | "strip-ansi": "^6.0.0" 1524 | } 1525 | }, 1526 | "wrappy": { 1527 | "version": "1.0.2", 1528 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1529 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 1530 | "dev": true 1531 | }, 1532 | "y18n": { 1533 | "version": "5.0.8", 1534 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", 1535 | "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", 1536 | "dev": true 1537 | }, 1538 | "yallist": { 1539 | "version": "4.0.0", 1540 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", 1541 | "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", 1542 | "dev": true 1543 | }, 1544 | "yargs": { 1545 | "version": "16.2.0", 1546 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", 1547 | "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", 1548 | "dev": true, 1549 | "requires": { 1550 | "cliui": "^7.0.2", 1551 | "escalade": "^3.1.1", 1552 | "get-caller-file": "^2.0.5", 1553 | "require-directory": "^2.1.1", 1554 | "string-width": "^4.2.0", 1555 | "y18n": "^5.0.5", 1556 | "yargs-parser": "^20.2.2" 1557 | } 1558 | }, 1559 | "yargs-parser": { 1560 | "version": "20.2.9", 1561 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", 1562 | "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", 1563 | "dev": true 1564 | }, 1565 | "yup": { 1566 | "version": "0.32.9", 1567 | "resolved": "https://registry.npmjs.org/yup/-/yup-0.32.9.tgz", 1568 | "integrity": "sha512-Ci1qN+i2H0XpY7syDQ0k5zKQ/DoxO0LzPg8PAR/X4Mpj6DqaeCoIYEEjDJwhArh3Fa7GWbQQVDZKeXYlSH4JMg==", 1569 | "requires": { 1570 | "@babel/runtime": "^7.10.5", 1571 | "@types/lodash": "^4.14.165", 1572 | "lodash": "^4.17.20", 1573 | "lodash-es": "^4.17.15", 1574 | "nanoclone": "^0.2.1", 1575 | "property-expr": "^2.0.4", 1576 | "toposort": "^2.0.2" 1577 | } 1578 | } 1579 | } 1580 | } 1581 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@ariya/berkala", 3 | "version": "1.3.0", 4 | "description": "Run scheduled tasks", 5 | "main": "index.js", 6 | "bin": { 7 | "berkala": "./index.js" 8 | }, 9 | "scripts": { 10 | "start": "node index.js", 11 | "test": "npm run check-format", 12 | "check-format": "prettier --check \"**/*.js\"", 13 | "format-code": "prettier --write \"**/*.js\"", 14 | "cli-tests": "npx bats tests/cli.bats", 15 | "build": "pkg --compress brotli ." 16 | }, 17 | "author": "Ariya Hidayat", 18 | "license": "MIT", 19 | "repository": { 20 | "type": "git", 21 | "url": "https://github.com/ariya/berkala.git" 22 | }, 23 | "keywords": [ 24 | "scheduler", 25 | "tasks", 26 | "cron", 27 | "cronjob" 28 | ], 29 | "engines": { 30 | "node": ">=14.0.0" 31 | }, 32 | "dependencies": { 33 | "bree": "~6.2.1", 34 | "js-yaml": "~4.1.0", 35 | "readline-sync": "~1.4.10", 36 | "say": "~0.16.0", 37 | "which": "~2.0.2" 38 | }, 39 | "devDependencies": { 40 | "bats": "~1.4.1", 41 | "bats-assert": "~2.0.0", 42 | "bats-support": "~0.3.0", 43 | "pkg": "~5.3.1", 44 | "prettier": "~2.3.2" 45 | }, 46 | "pkg": { 47 | "outputPath": "dist" 48 | }, 49 | "prettier": { 50 | "tabWidth": 4, 51 | "printWidth": 120, 52 | "quoteProps": "consistent", 53 | "singleQuote": true, 54 | "trailingComma": "none" 55 | }, 56 | "volta": { 57 | "node": "14.18.2" 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/pal.js: -------------------------------------------------------------------------------- 1 | /** PAL - Platform Abstraction Layer */ 2 | const os = require('os'); 3 | const child_process = require('child_process'); 4 | 5 | const which = require('which'); 6 | const say = require('say'); 7 | 8 | /** 9 | * Escape a string for PowerShell. 10 | * @param {string} str 11 | * @return {string} 12 | */ 13 | function psEscape(str) { 14 | let result = ''; 15 | for (let i = 0; i < str.length; i++) { 16 | const ch = str[i]; 17 | if (ch.charCodeAt(0) === 39) { 18 | // single quote, escape it with another single quote 19 | result += ch; 20 | } 21 | result += ch; 22 | } 23 | return result; 24 | } 25 | 26 | /** 27 | * Send a desktop notification 28 | * @param {string} title 29 | * @param {string} message 30 | */ 31 | function platformNotify(title, message) { 32 | if (os.type() === 'Linux') { 33 | const resolved = which.sync('notify-send', { nothrow: true }); 34 | if (resolved) { 35 | child_process.spawnSync('notify-send', ['-a', 'Berkala', title, message]); 36 | } else { 37 | console.error('notify: unable to locate notify-send'); 38 | console.log(title + ':', message); 39 | } 40 | } else if (os.type() === 'Darwin') { 41 | const command = `display notification "${message}" with title "Berkala" subtitle "${title}"`; 42 | child_process.spawnSync('osascript', ['-e', command]); 43 | } else if (os.type() === 'Windows_NT') { 44 | const script = ` 45 | [Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] > $null; 46 | $templateType = [Windows.UI.Notifications.ToastTemplateType]::ToastText02; 47 | $template = [Windows.UI.Notifications.ToastNotificationManager]::GetTemplateContent($templateType); 48 | $template.SelectSingleNode(\"//text[@id=1]\").InnerText = '${psEscape(title)}'; 49 | $template.SelectSingleNode(\"//text[@id=2]\").InnerText = '${psEscape(message)}'; 50 | $toast = [Windows.UI.Notifications.ToastNotification]::new($template); 51 | $notifier = [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier('Berkala'); 52 | $notifier.Show($toast);`; 53 | 54 | child_process.execSync(script, { shell: 'powershell.exe' }); 55 | } else { 56 | // FIXME what's this system? 57 | console.log(title, message); 58 | } 59 | } 60 | 61 | /** 62 | * Convert text to audible speech 63 | * @param {string} message 64 | */ 65 | function platformSay(message) { 66 | if (os.type() === 'Linux') { 67 | const resolved = which.sync('festival', { nothrow: true }); 68 | if (resolved) { 69 | say.speak(message); 70 | } else { 71 | console.error('say: unable to locate Festival'); 72 | platformNotify('Berkala', message); 73 | } 74 | } else if (os.type() === 'Windows_NT') { 75 | // TODO: check for Powershell first 76 | say.speak(psEscape(message)); 77 | } else if (os.type() === 'Darwin') { 78 | say.speak(message, 'Samantha'); // Siri's voice 79 | } else { 80 | // unsupported 81 | console.error('say: unsupport system', os.type()); 82 | platformNotify('Berkala', message); 83 | } 84 | } 85 | 86 | module.exports = { 87 | notify: platformNotify, 88 | say: platformSay 89 | }; 90 | -------------------------------------------------------------------------------- /tests/cli.bats: -------------------------------------------------------------------------------- 1 | setup() { 2 | load './node_modules/bats-support/load.bash' 3 | load './node_modules/bats-assert/load.bash' 4 | } 5 | 6 | teardown() { 7 | rm -rf berkala.yml 8 | } 9 | 10 | @test "can run with an empty config" { 11 | rm -rf berkala.yml 12 | touch berkala.yml 13 | run ./dist/berkala 14 | assert_success 15 | assert_output --partial 'Berkala 1.3' 16 | } 17 | 18 | @test "will not create a config file automatically in non-interactive tty" { 19 | rm -rf berkala.yml 20 | run export CI=true 21 | run ./dist/berkala 22 | assert_failure 255 23 | } 24 | 25 | @test "must run a command" { 26 | rm -rf ./must_exist.txt ./first-file.txt ./second-file.txt 27 | cp tests/test-run.yml berkala.yml 28 | run ./dist/berkala 29 | run cat ./must_exist.txt 30 | run cat ./first_file.txt 31 | run cat ./second_file.txt 32 | assert_success 33 | } 34 | 35 | @test "must support timeout" { 36 | rm -rf ./must_exist.txt ./must_not_exist.txt 37 | cp tests/test-timeout.yml berkala.yml 38 | run ./dist/berkala 39 | run cat ./must_exist.txt 40 | assert_success 41 | run cat ./must_not_exist.txt 42 | assert_failure 43 | } 44 | -------------------------------------------------------------------------------- /tests/test-run.yml: -------------------------------------------------------------------------------- 1 | tasks: 2 | boot: 3 | steps: 4 | - run: touch must_exist.txt 5 | 6 | another-boot: 7 | steps: 8 | - run: | 9 | touch first_file.txt 10 | echo "Hi" > second_file.txt 11 | -------------------------------------------------------------------------------- /tests/test-timeout.yml: -------------------------------------------------------------------------------- 1 | tasks: 2 | boot: 3 | steps: 4 | - run: | 5 | touch must_exist.txt 6 | sleep 7 7 | touch must_not_exist.txt 8 | timeout-minutes: 0.01 9 | --------------------------------------------------------------------------------