├── .gitignore ├── README.md ├── package-lock.json ├── package.json ├── src ├── bin.js ├── commands │ ├── deploy.js │ ├── init.js │ ├── package.js │ └── validate.js ├── index.js ├── log.js ├── templates │ ├── lambda.js │ └── sam.json └── utils.js └── test └── index.test.js /.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 | # local usage testing 61 | sam*.json 62 | index.js 63 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## SAMMIE - Serverless Application Model Made Infinitely Easier 2 | 3 | [AWS's Serverless Application Model (SAM)](https://github.com/awslabs/serverless-application-model) is the official AWS provided way to define serverless applications. sammie's purpose is to get you set up and deployed in seconds _using SAM_. 4 | 5 | ### Features 6 | 7 | - Generate a minimal yet flexible SAM template for you to get started. 8 | - Simplify SAM's complex packaging & deploy steps & flags into a simple `deploy` command. 9 | - Provide a best practice for deploying multiple environments. 10 | 11 | --- 12 | 13 | ### Prerequisites 14 | 15 | [AWS CLI](https://aws.amazon.com/cli/) - sammie uses this for all AWS operations under the hood. 16 | 17 | ### Quickstart 18 | 19 | ```bash 20 | npm i sammie -g 21 | sammie init my-app 22 | sammie deploy 23 | ``` 24 | 25 | This will generate a serverless application, deploy it to a development environment, and direct you to your app served over https! 26 | 27 | --- 28 | 29 | ### Commands 30 | 31 | #### init - Generates a serverless application including a SAM template & lambda function 32 | 33 | `sammie init ` 34 | _Options:_ 35 | `-y, --yaml`: Generate yaml for SAM template. Defaults to json, because javascript. 36 | 37 | #### deploy - Deploys application 38 | 39 | `sammie deploy` 40 | _Options:_ 41 | `-t, --template`: Path to a SAM template. Defaults to `sam.(json|yaml)` in the current directory. 42 | `-e, --environment`: An environment name to deploy. Defaults to "development". 43 | `-p, --parameters`: A list of parameters to override in your template. 44 | `-s, --stack-name`: Option to override the auto-generated environment stack name. 45 | `--s3-bucket`: S3 bucket where code is uploaded. Defaults to Parameters.bucketName in template which is generated for you. 46 | `--s3-prefix`: S3 path prefix added to the packaged code file. Defaults to stackName/year. 47 | 48 | --- 49 | 50 | ### Environments 51 | 52 | It's a best practice to create completely separate stacks for each of your application's environments, rather than a single stack with multiple lambda qualifiers, API Gateway stages, and permissions. This makes your application more portable and reduces the blast radius of taking down your live application during the development cycle. 53 | 54 | To support this, sammie will deploy separate stacks for you based on the environment option: 55 | 56 | E.g. your stack name is "my-app": 57 | `sammie deploy` will deploy stack "my-app-development" (development is the default) 58 | `sammie deploy --environment production` will deploy stack "my-app-production" 59 | 60 | #### Environment variables & properties 61 | 62 | To help add environment specific variables & properties, you can create separate SAM templates named with the environment suffix. 63 | E.g. `sam-production.json` containing the following, will get _merged with your base template_ `sam.json` upon `sammie deploy --environment production` 64 | 65 | ```json 66 | { 67 | "Resources": { 68 | "TestFunction": { 69 | "Properties": { 70 | "MemorySize": 1280, 71 | "Environment": { 72 | "Variables": { 73 | "ENV_VAR1": "var1-prod", 74 | "ENV_VAR2": "var2-prod" 75 | } 76 | } 77 | } 78 | } 79 | } 80 | } 81 | ``` 82 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sammie", 3 | "version": "1.2.1", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@babel/code-frame": { 8 | "version": "7.10.4", 9 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", 10 | "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", 11 | "dev": true, 12 | "requires": { 13 | "@babel/highlight": "^7.10.4" 14 | } 15 | }, 16 | "@babel/helper-validator-identifier": { 17 | "version": "7.10.4", 18 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", 19 | "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", 20 | "dev": true 21 | }, 22 | "@babel/highlight": { 23 | "version": "7.10.4", 24 | "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", 25 | "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", 26 | "dev": true, 27 | "requires": { 28 | "@babel/helper-validator-identifier": "^7.10.4", 29 | "chalk": "^2.0.0", 30 | "js-tokens": "^4.0.0" 31 | }, 32 | "dependencies": { 33 | "chalk": { 34 | "version": "2.4.2", 35 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 36 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 37 | "dev": true, 38 | "requires": { 39 | "ansi-styles": "^3.2.1", 40 | "escape-string-regexp": "^1.0.5", 41 | "supports-color": "^5.3.0" 42 | } 43 | }, 44 | "supports-color": { 45 | "version": "5.5.0", 46 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 47 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 48 | "dev": true, 49 | "requires": { 50 | "has-flag": "^3.0.0" 51 | } 52 | } 53 | } 54 | }, 55 | "@types/color-name": { 56 | "version": "1.1.1", 57 | "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", 58 | "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==" 59 | }, 60 | "@types/eslint-visitor-keys": { 61 | "version": "1.0.0", 62 | "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", 63 | "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==", 64 | "dev": true 65 | }, 66 | "@types/json-schema": { 67 | "version": "7.0.5", 68 | "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.5.tgz", 69 | "integrity": "sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==", 70 | "dev": true 71 | }, 72 | "@types/mocha": { 73 | "version": "8.0.2", 74 | "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.0.2.tgz", 75 | "integrity": "sha512-5cv8rmqT3KX9XtWDvSgGYfS4OwrKM2eei90GWLnTYz+AXRiBv5uYcKBjnkQ4katNvfYk3+o2bHGZUsDhdcoUyg==", 76 | "dev": true 77 | }, 78 | "@typescript-eslint/eslint-plugin": { 79 | "version": "3.9.0", 80 | "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.9.0.tgz", 81 | "integrity": "sha512-UD6b4p0/hSe1xdTvRCENSx7iQ+KR6ourlZFfYuPC7FlXEzdHuLPrEmuxZ23b2zW96KJX9Z3w05GE/wNOiEzrVg==", 82 | "dev": true, 83 | "requires": { 84 | "@typescript-eslint/experimental-utils": "3.9.0", 85 | "debug": "^4.1.1", 86 | "functional-red-black-tree": "^1.0.1", 87 | "regexpp": "^3.0.0", 88 | "semver": "^7.3.2", 89 | "tsutils": "^3.17.1" 90 | } 91 | }, 92 | "@typescript-eslint/experimental-utils": { 93 | "version": "3.9.0", 94 | "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-3.9.0.tgz", 95 | "integrity": "sha512-/vSHUDYizSOhrOJdjYxPNGfb4a3ibO8zd4nUKo/QBFOmxosT3cVUV7KIg8Dwi6TXlr667G7YPqFK9+VSZOorNA==", 96 | "dev": true, 97 | "requires": { 98 | "@types/json-schema": "^7.0.3", 99 | "@typescript-eslint/types": "3.9.0", 100 | "@typescript-eslint/typescript-estree": "3.9.0", 101 | "eslint-scope": "^5.0.0", 102 | "eslint-utils": "^2.0.0" 103 | } 104 | }, 105 | "@typescript-eslint/parser": { 106 | "version": "3.9.0", 107 | "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-3.9.0.tgz", 108 | "integrity": "sha512-rDHOKb6uW2jZkHQniUQVZkixQrfsZGUCNWWbKWep4A5hGhN5dLHMUCNAWnC4tXRlHedXkTDptIpxs6e4Pz8UfA==", 109 | "dev": true, 110 | "requires": { 111 | "@types/eslint-visitor-keys": "^1.0.0", 112 | "@typescript-eslint/experimental-utils": "3.9.0", 113 | "@typescript-eslint/types": "3.9.0", 114 | "@typescript-eslint/typescript-estree": "3.9.0", 115 | "eslint-visitor-keys": "^1.1.0" 116 | } 117 | }, 118 | "@typescript-eslint/types": { 119 | "version": "3.9.0", 120 | "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-3.9.0.tgz", 121 | "integrity": "sha512-rb6LDr+dk9RVVXO/NJE8dT1pGlso3voNdEIN8ugm4CWM5w5GimbThCMiMl4da1t5u3YwPWEwOnKAULCZgBtBHg==", 122 | "dev": true 123 | }, 124 | "@typescript-eslint/typescript-estree": { 125 | "version": "3.9.0", 126 | "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-3.9.0.tgz", 127 | "integrity": "sha512-N+158NKgN4rOmWVfvKOMoMFV5n8XxAliaKkArm/sOypzQ0bUL8MSnOEBW3VFIeffb/K5ce/cAV0yYhR7U4ALAA==", 128 | "dev": true, 129 | "requires": { 130 | "@typescript-eslint/types": "3.9.0", 131 | "@typescript-eslint/visitor-keys": "3.9.0", 132 | "debug": "^4.1.1", 133 | "glob": "^7.1.6", 134 | "is-glob": "^4.0.1", 135 | "lodash": "^4.17.15", 136 | "semver": "^7.3.2", 137 | "tsutils": "^3.17.1" 138 | } 139 | }, 140 | "@typescript-eslint/visitor-keys": { 141 | "version": "3.9.0", 142 | "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-3.9.0.tgz", 143 | "integrity": "sha512-O1qeoGqDbu0EZUC/MZ6F1WHTIzcBVhGqDj3LhTnj65WUA548RXVxUHbYhAW9bZWfb2rnX9QsbbP5nmeJ5Z4+ng==", 144 | "dev": true, 145 | "requires": { 146 | "eslint-visitor-keys": "^1.1.0" 147 | } 148 | }, 149 | "acorn": { 150 | "version": "7.4.0", 151 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.0.tgz", 152 | "integrity": "sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==", 153 | "dev": true 154 | }, 155 | "acorn-jsx": { 156 | "version": "5.2.0", 157 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz", 158 | "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==", 159 | "dev": true 160 | }, 161 | "ajv": { 162 | "version": "6.12.4", 163 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.4.tgz", 164 | "integrity": "sha512-eienB2c9qVQs2KWexhkrdMLVDoIQCz5KSeLxwg9Lzk4DOfBtIK9PQwwufcsn1jjGuf9WZmqPMbGxOzfcuphJCQ==", 165 | "dev": true, 166 | "requires": { 167 | "fast-deep-equal": "^3.1.1", 168 | "fast-json-stable-stringify": "^2.0.0", 169 | "json-schema-traverse": "^0.4.1", 170 | "uri-js": "^4.2.2" 171 | } 172 | }, 173 | "ansi-colors": { 174 | "version": "4.1.1", 175 | "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", 176 | "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", 177 | "dev": true 178 | }, 179 | "ansi-regex": { 180 | "version": "5.0.0", 181 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", 182 | "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", 183 | "dev": true 184 | }, 185 | "ansi-styles": { 186 | "version": "3.2.1", 187 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 188 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 189 | "dev": true, 190 | "requires": { 191 | "color-convert": "^1.9.0" 192 | } 193 | }, 194 | "anymatch": { 195 | "version": "3.1.1", 196 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", 197 | "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", 198 | "dev": true, 199 | "requires": { 200 | "normalize-path": "^3.0.0", 201 | "picomatch": "^2.0.4" 202 | } 203 | }, 204 | "argparse": { 205 | "version": "1.0.10", 206 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", 207 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", 208 | "requires": { 209 | "sprintf-js": "~1.0.2" 210 | } 211 | }, 212 | "array-includes": { 213 | "version": "3.1.1", 214 | "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz", 215 | "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==", 216 | "dev": true, 217 | "requires": { 218 | "define-properties": "^1.1.3", 219 | "es-abstract": "^1.17.0", 220 | "is-string": "^1.0.5" 221 | } 222 | }, 223 | "array.prototype.flatmap": { 224 | "version": "1.2.3", 225 | "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.3.tgz", 226 | "integrity": "sha512-OOEk+lkePcg+ODXIpvuU9PAryCikCJyo7GlDG1upleEpQRx6mzL9puEBkozQ5iAx20KV0l3DbyQwqciJtqe5Pg==", 227 | "dev": true, 228 | "requires": { 229 | "define-properties": "^1.1.3", 230 | "es-abstract": "^1.17.0-next.1", 231 | "function-bind": "^1.1.1" 232 | } 233 | }, 234 | "array.prototype.map": { 235 | "version": "1.0.2", 236 | "resolved": "https://registry.npmjs.org/array.prototype.map/-/array.prototype.map-1.0.2.tgz", 237 | "integrity": "sha512-Az3OYxgsa1g7xDYp86l0nnN4bcmuEITGe1rbdEBVkrqkzMgDcbdQ2R7r41pNzti+4NMces3H8gMmuioZUilLgw==", 238 | "dev": true, 239 | "requires": { 240 | "define-properties": "^1.1.3", 241 | "es-abstract": "^1.17.0-next.1", 242 | "es-array-method-boxes-properly": "^1.0.0", 243 | "is-string": "^1.0.4" 244 | } 245 | }, 246 | "astral-regex": { 247 | "version": "1.0.0", 248 | "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", 249 | "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", 250 | "dev": true 251 | }, 252 | "balanced-match": { 253 | "version": "1.0.0", 254 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 255 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", 256 | "dev": true 257 | }, 258 | "binary-extensions": { 259 | "version": "2.1.0", 260 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", 261 | "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", 262 | "dev": true 263 | }, 264 | "brace-expansion": { 265 | "version": "1.1.11", 266 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 267 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 268 | "dev": true, 269 | "requires": { 270 | "balanced-match": "^1.0.0", 271 | "concat-map": "0.0.1" 272 | } 273 | }, 274 | "braces": { 275 | "version": "3.0.2", 276 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", 277 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", 278 | "dev": true, 279 | "requires": { 280 | "fill-range": "^7.0.1" 281 | } 282 | }, 283 | "browser-stdout": { 284 | "version": "1.3.1", 285 | "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", 286 | "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", 287 | "dev": true 288 | }, 289 | "callsites": { 290 | "version": "3.1.0", 291 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", 292 | "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", 293 | "dev": true 294 | }, 295 | "camelcase": { 296 | "version": "5.3.1", 297 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", 298 | "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", 299 | "dev": true 300 | }, 301 | "chalk": { 302 | "version": "4.1.0", 303 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", 304 | "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", 305 | "requires": { 306 | "ansi-styles": "^4.1.0", 307 | "supports-color": "^7.1.0" 308 | }, 309 | "dependencies": { 310 | "ansi-styles": { 311 | "version": "4.2.1", 312 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", 313 | "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", 314 | "requires": { 315 | "@types/color-name": "^1.1.1", 316 | "color-convert": "^2.0.1" 317 | } 318 | }, 319 | "color-convert": { 320 | "version": "2.0.1", 321 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 322 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 323 | "requires": { 324 | "color-name": "~1.1.4" 325 | } 326 | }, 327 | "color-name": { 328 | "version": "1.1.4", 329 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 330 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" 331 | } 332 | } 333 | }, 334 | "chokidar": { 335 | "version": "3.3.1", 336 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.1.tgz", 337 | "integrity": "sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg==", 338 | "dev": true, 339 | "requires": { 340 | "anymatch": "~3.1.1", 341 | "braces": "~3.0.2", 342 | "fsevents": "~2.1.2", 343 | "glob-parent": "~5.1.0", 344 | "is-binary-path": "~2.1.0", 345 | "is-glob": "~4.0.1", 346 | "normalize-path": "~3.0.0", 347 | "readdirp": "~3.3.0" 348 | } 349 | }, 350 | "cliui": { 351 | "version": "5.0.0", 352 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", 353 | "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", 354 | "dev": true, 355 | "requires": { 356 | "string-width": "^3.1.0", 357 | "strip-ansi": "^5.2.0", 358 | "wrap-ansi": "^5.1.0" 359 | }, 360 | "dependencies": { 361 | "ansi-regex": { 362 | "version": "4.1.0", 363 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", 364 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", 365 | "dev": true 366 | }, 367 | "strip-ansi": { 368 | "version": "5.2.0", 369 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", 370 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", 371 | "dev": true, 372 | "requires": { 373 | "ansi-regex": "^4.1.0" 374 | } 375 | } 376 | } 377 | }, 378 | "cloudformation-schema-js-yaml": { 379 | "version": "1.0.1", 380 | "resolved": "https://registry.npmjs.org/cloudformation-schema-js-yaml/-/cloudformation-schema-js-yaml-1.0.1.tgz", 381 | "integrity": "sha512-4Yer4AAMszD/FZsUG2Q9BCERAN9J+9mzZL882WkcpffbFaPcEy5CeB0f5kIiBge8q2Wf814GRUn20PvEOF+pOg==" 382 | }, 383 | "color-convert": { 384 | "version": "1.9.3", 385 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 386 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 387 | "dev": true, 388 | "requires": { 389 | "color-name": "1.1.3" 390 | } 391 | }, 392 | "color-name": { 393 | "version": "1.1.3", 394 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 395 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", 396 | "dev": true 397 | }, 398 | "concat-map": { 399 | "version": "0.0.1", 400 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 401 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 402 | "dev": true 403 | }, 404 | "cross-spawn": { 405 | "version": "7.0.3", 406 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", 407 | "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", 408 | "dev": true, 409 | "requires": { 410 | "path-key": "^3.1.0", 411 | "shebang-command": "^2.0.0", 412 | "which": "^2.0.1" 413 | } 414 | }, 415 | "debug": { 416 | "version": "4.1.1", 417 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", 418 | "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", 419 | "dev": true, 420 | "requires": { 421 | "ms": "^2.1.1" 422 | } 423 | }, 424 | "decamelize": { 425 | "version": "1.2.0", 426 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", 427 | "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", 428 | "dev": true 429 | }, 430 | "deep-is": { 431 | "version": "0.1.3", 432 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", 433 | "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", 434 | "dev": true 435 | }, 436 | "deepmerge": { 437 | "version": "4.2.2", 438 | "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", 439 | "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==" 440 | }, 441 | "define-properties": { 442 | "version": "1.1.3", 443 | "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", 444 | "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", 445 | "dev": true, 446 | "requires": { 447 | "object-keys": "^1.0.12" 448 | } 449 | }, 450 | "diff": { 451 | "version": "4.0.2", 452 | "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", 453 | "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", 454 | "dev": true 455 | }, 456 | "doctrine": { 457 | "version": "3.0.0", 458 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", 459 | "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", 460 | "dev": true, 461 | "requires": { 462 | "esutils": "^2.0.2" 463 | } 464 | }, 465 | "emoji-regex": { 466 | "version": "7.0.3", 467 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", 468 | "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", 469 | "dev": true 470 | }, 471 | "enquirer": { 472 | "version": "2.3.6", 473 | "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", 474 | "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", 475 | "dev": true, 476 | "requires": { 477 | "ansi-colors": "^4.1.1" 478 | } 479 | }, 480 | "es-abstract": { 481 | "version": "1.17.6", 482 | "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", 483 | "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", 484 | "dev": true, 485 | "requires": { 486 | "es-to-primitive": "^1.2.1", 487 | "function-bind": "^1.1.1", 488 | "has": "^1.0.3", 489 | "has-symbols": "^1.0.1", 490 | "is-callable": "^1.2.0", 491 | "is-regex": "^1.1.0", 492 | "object-inspect": "^1.7.0", 493 | "object-keys": "^1.1.1", 494 | "object.assign": "^4.1.0", 495 | "string.prototype.trimend": "^1.0.1", 496 | "string.prototype.trimstart": "^1.0.1" 497 | } 498 | }, 499 | "es-array-method-boxes-properly": { 500 | "version": "1.0.0", 501 | "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", 502 | "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", 503 | "dev": true 504 | }, 505 | "es-get-iterator": { 506 | "version": "1.1.0", 507 | "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.0.tgz", 508 | "integrity": "sha512-UfrmHuWQlNMTs35e1ypnvikg6jCz3SK8v8ImvmDsh36fCVUR1MqoFDiyn0/k52C8NqO3YsO8Oe0azeesNuqSsQ==", 509 | "dev": true, 510 | "requires": { 511 | "es-abstract": "^1.17.4", 512 | "has-symbols": "^1.0.1", 513 | "is-arguments": "^1.0.4", 514 | "is-map": "^2.0.1", 515 | "is-set": "^2.0.1", 516 | "is-string": "^1.0.5", 517 | "isarray": "^2.0.5" 518 | } 519 | }, 520 | "es-to-primitive": { 521 | "version": "1.2.1", 522 | "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", 523 | "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", 524 | "dev": true, 525 | "requires": { 526 | "is-callable": "^1.1.4", 527 | "is-date-object": "^1.0.1", 528 | "is-symbol": "^1.0.2" 529 | } 530 | }, 531 | "escape-string-regexp": { 532 | "version": "1.0.5", 533 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 534 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", 535 | "dev": true 536 | }, 537 | "eslint": { 538 | "version": "7.7.0", 539 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.7.0.tgz", 540 | "integrity": "sha512-1KUxLzos0ZVsyL81PnRN335nDtQ8/vZUD6uMtWbF+5zDtjKcsklIi78XoE0MVL93QvWTu+E5y44VyyCsOMBrIg==", 541 | "dev": true, 542 | "requires": { 543 | "@babel/code-frame": "^7.0.0", 544 | "ajv": "^6.10.0", 545 | "chalk": "^4.0.0", 546 | "cross-spawn": "^7.0.2", 547 | "debug": "^4.0.1", 548 | "doctrine": "^3.0.0", 549 | "enquirer": "^2.3.5", 550 | "eslint-scope": "^5.1.0", 551 | "eslint-utils": "^2.1.0", 552 | "eslint-visitor-keys": "^1.3.0", 553 | "espree": "^7.2.0", 554 | "esquery": "^1.2.0", 555 | "esutils": "^2.0.2", 556 | "file-entry-cache": "^5.0.1", 557 | "functional-red-black-tree": "^1.0.1", 558 | "glob-parent": "^5.0.0", 559 | "globals": "^12.1.0", 560 | "ignore": "^4.0.6", 561 | "import-fresh": "^3.0.0", 562 | "imurmurhash": "^0.1.4", 563 | "is-glob": "^4.0.0", 564 | "js-yaml": "^3.13.1", 565 | "json-stable-stringify-without-jsonify": "^1.0.1", 566 | "levn": "^0.4.1", 567 | "lodash": "^4.17.19", 568 | "minimatch": "^3.0.4", 569 | "natural-compare": "^1.4.0", 570 | "optionator": "^0.9.1", 571 | "progress": "^2.0.0", 572 | "regexpp": "^3.1.0", 573 | "semver": "^7.2.1", 574 | "strip-ansi": "^6.0.0", 575 | "strip-json-comments": "^3.1.0", 576 | "table": "^5.2.3", 577 | "text-table": "^0.2.0", 578 | "v8-compile-cache": "^2.0.3" 579 | } 580 | }, 581 | "eslint-config-prettier": { 582 | "version": "6.11.0", 583 | "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.11.0.tgz", 584 | "integrity": "sha512-oB8cpLWSAjOVFEJhhyMZh6NOEOtBVziaqdDQ86+qhDHFbZXoRTM7pNSvFRfW/W/L/LrQ38C99J5CGuRBBzBsdA==", 585 | "dev": true, 586 | "requires": { 587 | "get-stdin": "^6.0.0" 588 | } 589 | }, 590 | "eslint-plugin-css-modules": { 591 | "version": "2.11.0", 592 | "resolved": "https://registry.npmjs.org/eslint-plugin-css-modules/-/eslint-plugin-css-modules-2.11.0.tgz", 593 | "integrity": "sha512-CLvQvJOMlCywZzaI4HVu7QH/ltgNXvCg7giJGiE+sA9wh5zQ+AqTgftAzrERV22wHe1p688wrU/Zwxt1Ry922w==", 594 | "dev": true, 595 | "requires": { 596 | "gonzales-pe": "^4.0.3", 597 | "lodash": "^4.17.2" 598 | } 599 | }, 600 | "eslint-plugin-es": { 601 | "version": "3.0.1", 602 | "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", 603 | "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", 604 | "dev": true, 605 | "requires": { 606 | "eslint-utils": "^2.0.0", 607 | "regexpp": "^3.0.0" 608 | } 609 | }, 610 | "eslint-plugin-node": { 611 | "version": "11.1.0", 612 | "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", 613 | "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", 614 | "dev": true, 615 | "requires": { 616 | "eslint-plugin-es": "^3.0.0", 617 | "eslint-utils": "^2.0.0", 618 | "ignore": "^5.1.1", 619 | "minimatch": "^3.0.4", 620 | "resolve": "^1.10.1", 621 | "semver": "^6.1.0" 622 | }, 623 | "dependencies": { 624 | "ignore": { 625 | "version": "5.1.8", 626 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", 627 | "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", 628 | "dev": true 629 | }, 630 | "semver": { 631 | "version": "6.3.0", 632 | "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", 633 | "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", 634 | "dev": true 635 | } 636 | } 637 | }, 638 | "eslint-plugin-react": { 639 | "version": "7.20.6", 640 | "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.20.6.tgz", 641 | "integrity": "sha512-kidMTE5HAEBSLu23CUDvj8dc3LdBU0ri1scwHBZjI41oDv4tjsWZKU7MQccFzH1QYPYhsnTF2ovh7JlcIcmxgg==", 642 | "dev": true, 643 | "requires": { 644 | "array-includes": "^3.1.1", 645 | "array.prototype.flatmap": "^1.2.3", 646 | "doctrine": "^2.1.0", 647 | "has": "^1.0.3", 648 | "jsx-ast-utils": "^2.4.1", 649 | "object.entries": "^1.1.2", 650 | "object.fromentries": "^2.0.2", 651 | "object.values": "^1.1.1", 652 | "prop-types": "^15.7.2", 653 | "resolve": "^1.17.0", 654 | "string.prototype.matchall": "^4.0.2" 655 | }, 656 | "dependencies": { 657 | "doctrine": { 658 | "version": "2.1.0", 659 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", 660 | "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", 661 | "dev": true, 662 | "requires": { 663 | "esutils": "^2.0.2" 664 | } 665 | } 666 | } 667 | }, 668 | "eslint-plugin-react-hooks": { 669 | "version": "4.1.0", 670 | "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.1.0.tgz", 671 | "integrity": "sha512-36zilUcDwDReiORXmcmTc6rRumu9JIM3WjSvV0nclHoUQ0CNrX866EwONvLR/UqaeqFutbAnVu8PEmctdo2SRQ==", 672 | "dev": true 673 | }, 674 | "eslint-scope": { 675 | "version": "5.1.0", 676 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz", 677 | "integrity": "sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==", 678 | "dev": true, 679 | "requires": { 680 | "esrecurse": "^4.1.0", 681 | "estraverse": "^4.1.1" 682 | } 683 | }, 684 | "eslint-utils": { 685 | "version": "2.1.0", 686 | "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", 687 | "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", 688 | "dev": true, 689 | "requires": { 690 | "eslint-visitor-keys": "^1.1.0" 691 | } 692 | }, 693 | "eslint-visitor-keys": { 694 | "version": "1.3.0", 695 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", 696 | "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", 697 | "dev": true 698 | }, 699 | "espree": { 700 | "version": "7.2.0", 701 | "resolved": "https://registry.npmjs.org/espree/-/espree-7.2.0.tgz", 702 | "integrity": "sha512-H+cQ3+3JYRMEIOl87e7QdHX70ocly5iW4+dttuR8iYSPr/hXKFb+7dBsZ7+u1adC4VrnPlTkv0+OwuPnDop19g==", 703 | "dev": true, 704 | "requires": { 705 | "acorn": "^7.3.1", 706 | "acorn-jsx": "^5.2.0", 707 | "eslint-visitor-keys": "^1.3.0" 708 | } 709 | }, 710 | "esprima": { 711 | "version": "4.0.1", 712 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", 713 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" 714 | }, 715 | "esquery": { 716 | "version": "1.3.1", 717 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", 718 | "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", 719 | "dev": true, 720 | "requires": { 721 | "estraverse": "^5.1.0" 722 | }, 723 | "dependencies": { 724 | "estraverse": { 725 | "version": "5.2.0", 726 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", 727 | "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", 728 | "dev": true 729 | } 730 | } 731 | }, 732 | "esrecurse": { 733 | "version": "4.2.1", 734 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", 735 | "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", 736 | "dev": true, 737 | "requires": { 738 | "estraverse": "^4.1.0" 739 | } 740 | }, 741 | "estraverse": { 742 | "version": "4.3.0", 743 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", 744 | "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", 745 | "dev": true 746 | }, 747 | "esutils": { 748 | "version": "2.0.3", 749 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", 750 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", 751 | "dev": true 752 | }, 753 | "fast-deep-equal": { 754 | "version": "3.1.3", 755 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", 756 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", 757 | "dev": true 758 | }, 759 | "fast-json-stable-stringify": { 760 | "version": "2.1.0", 761 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 762 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", 763 | "dev": true 764 | }, 765 | "fast-levenshtein": { 766 | "version": "2.0.6", 767 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 768 | "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", 769 | "dev": true 770 | }, 771 | "file-entry-cache": { 772 | "version": "5.0.1", 773 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", 774 | "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", 775 | "dev": true, 776 | "requires": { 777 | "flat-cache": "^2.0.1" 778 | } 779 | }, 780 | "fill-range": { 781 | "version": "7.0.1", 782 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", 783 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", 784 | "dev": true, 785 | "requires": { 786 | "to-regex-range": "^5.0.1" 787 | } 788 | }, 789 | "find-up": { 790 | "version": "4.1.0", 791 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", 792 | "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", 793 | "dev": true, 794 | "requires": { 795 | "locate-path": "^5.0.0", 796 | "path-exists": "^4.0.0" 797 | } 798 | }, 799 | "flat": { 800 | "version": "4.1.0", 801 | "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", 802 | "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", 803 | "dev": true, 804 | "requires": { 805 | "is-buffer": "~2.0.3" 806 | } 807 | }, 808 | "flat-cache": { 809 | "version": "2.0.1", 810 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", 811 | "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", 812 | "dev": true, 813 | "requires": { 814 | "flatted": "^2.0.0", 815 | "rimraf": "2.6.3", 816 | "write": "1.0.3" 817 | } 818 | }, 819 | "flatted": { 820 | "version": "2.0.2", 821 | "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", 822 | "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", 823 | "dev": true 824 | }, 825 | "flt": { 826 | "version": "0.32.0", 827 | "resolved": "https://registry.npmjs.org/flt/-/flt-0.32.0.tgz", 828 | "integrity": "sha512-gxgWSVKj9vV9Zk0U2tVYptnKF4UrECRfd0MxSAPIbGrs2rtFzjWirN48CqM9HKNl/ApCmHRyGopwkHJLOsOVPA==", 829 | "dev": true, 830 | "requires": { 831 | "@types/mocha": "^8.0.2", 832 | "@typescript-eslint/eslint-plugin": "^3.9.0", 833 | "@typescript-eslint/parser": "^3.9.0", 834 | "chalk": "^4.1.0", 835 | "eslint": "^7.7.0", 836 | "eslint-config-prettier": "^6.11.0", 837 | "eslint-plugin-css-modules": "^2.11.0", 838 | "eslint-plugin-node": "^11.1.0", 839 | "eslint-plugin-react": "^7.20.6", 840 | "eslint-plugin-react-hooks": "^4.1.0", 841 | "mocha": "^8.1.1", 842 | "prettier": "^2.0.5", 843 | "react": "*", 844 | "typescript": "*", 845 | "yargs": "^15.4.0" 846 | } 847 | }, 848 | "fs.realpath": { 849 | "version": "1.0.0", 850 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 851 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 852 | "dev": true 853 | }, 854 | "fsevents": { 855 | "version": "2.1.3", 856 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", 857 | "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", 858 | "dev": true, 859 | "optional": true 860 | }, 861 | "function-bind": { 862 | "version": "1.1.1", 863 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 864 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", 865 | "dev": true 866 | }, 867 | "functional-red-black-tree": { 868 | "version": "1.0.1", 869 | "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", 870 | "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", 871 | "dev": true 872 | }, 873 | "get-caller-file": { 874 | "version": "2.0.5", 875 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", 876 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", 877 | "dev": true 878 | }, 879 | "get-stdin": { 880 | "version": "6.0.0", 881 | "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", 882 | "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", 883 | "dev": true 884 | }, 885 | "glob": { 886 | "version": "7.1.6", 887 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", 888 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", 889 | "dev": true, 890 | "requires": { 891 | "fs.realpath": "^1.0.0", 892 | "inflight": "^1.0.4", 893 | "inherits": "2", 894 | "minimatch": "^3.0.4", 895 | "once": "^1.3.0", 896 | "path-is-absolute": "^1.0.0" 897 | } 898 | }, 899 | "glob-parent": { 900 | "version": "5.1.1", 901 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", 902 | "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", 903 | "dev": true, 904 | "requires": { 905 | "is-glob": "^4.0.1" 906 | } 907 | }, 908 | "globals": { 909 | "version": "12.4.0", 910 | "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", 911 | "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", 912 | "dev": true, 913 | "requires": { 914 | "type-fest": "^0.8.1" 915 | } 916 | }, 917 | "gonzales-pe": { 918 | "version": "4.3.0", 919 | "resolved": "https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-4.3.0.tgz", 920 | "integrity": "sha512-otgSPpUmdWJ43VXyiNgEYE4luzHCL2pz4wQ0OnDluC6Eg4Ko3Vexy/SrSynglw/eR+OhkzmqFCZa/OFa/RgAOQ==", 921 | "dev": true, 922 | "requires": { 923 | "minimist": "^1.2.5" 924 | } 925 | }, 926 | "growl": { 927 | "version": "1.10.5", 928 | "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", 929 | "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", 930 | "dev": true 931 | }, 932 | "has": { 933 | "version": "1.0.3", 934 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 935 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 936 | "dev": true, 937 | "requires": { 938 | "function-bind": "^1.1.1" 939 | } 940 | }, 941 | "has-flag": { 942 | "version": "3.0.0", 943 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 944 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 945 | "dev": true 946 | }, 947 | "has-symbols": { 948 | "version": "1.0.1", 949 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", 950 | "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", 951 | "dev": true 952 | }, 953 | "he": { 954 | "version": "1.2.0", 955 | "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", 956 | "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", 957 | "dev": true 958 | }, 959 | "ignore": { 960 | "version": "4.0.6", 961 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", 962 | "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", 963 | "dev": true 964 | }, 965 | "import-fresh": { 966 | "version": "3.2.1", 967 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", 968 | "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", 969 | "dev": true, 970 | "requires": { 971 | "parent-module": "^1.0.0", 972 | "resolve-from": "^4.0.0" 973 | } 974 | }, 975 | "imurmurhash": { 976 | "version": "0.1.4", 977 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 978 | "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", 979 | "dev": true 980 | }, 981 | "inflight": { 982 | "version": "1.0.6", 983 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 984 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 985 | "dev": true, 986 | "requires": { 987 | "once": "^1.3.0", 988 | "wrappy": "1" 989 | } 990 | }, 991 | "inherits": { 992 | "version": "2.0.4", 993 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 994 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 995 | "dev": true 996 | }, 997 | "internal-slot": { 998 | "version": "1.0.2", 999 | "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.2.tgz", 1000 | "integrity": "sha512-2cQNfwhAfJIkU4KZPkDI+Gj5yNNnbqi40W9Gge6dfnk4TocEVm00B3bdiL+JINrbGJil2TeHvM4rETGzk/f/0g==", 1001 | "dev": true, 1002 | "requires": { 1003 | "es-abstract": "^1.17.0-next.1", 1004 | "has": "^1.0.3", 1005 | "side-channel": "^1.0.2" 1006 | } 1007 | }, 1008 | "is-arguments": { 1009 | "version": "1.0.4", 1010 | "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", 1011 | "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==", 1012 | "dev": true 1013 | }, 1014 | "is-binary-path": { 1015 | "version": "2.1.0", 1016 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", 1017 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", 1018 | "dev": true, 1019 | "requires": { 1020 | "binary-extensions": "^2.0.0" 1021 | } 1022 | }, 1023 | "is-buffer": { 1024 | "version": "2.0.4", 1025 | "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", 1026 | "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", 1027 | "dev": true 1028 | }, 1029 | "is-callable": { 1030 | "version": "1.2.0", 1031 | "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", 1032 | "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", 1033 | "dev": true 1034 | }, 1035 | "is-date-object": { 1036 | "version": "1.0.2", 1037 | "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", 1038 | "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", 1039 | "dev": true 1040 | }, 1041 | "is-extglob": { 1042 | "version": "2.1.1", 1043 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 1044 | "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", 1045 | "dev": true 1046 | }, 1047 | "is-fullwidth-code-point": { 1048 | "version": "2.0.0", 1049 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 1050 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", 1051 | "dev": true 1052 | }, 1053 | "is-glob": { 1054 | "version": "4.0.1", 1055 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", 1056 | "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", 1057 | "dev": true, 1058 | "requires": { 1059 | "is-extglob": "^2.1.1" 1060 | } 1061 | }, 1062 | "is-map": { 1063 | "version": "2.0.1", 1064 | "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.1.tgz", 1065 | "integrity": "sha512-T/S49scO8plUiAOA2DBTBG3JHpn1yiw0kRp6dgiZ0v2/6twi5eiB0rHtHFH9ZIrvlWc6+4O+m4zg5+Z833aXgw==", 1066 | "dev": true 1067 | }, 1068 | "is-number": { 1069 | "version": "7.0.0", 1070 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 1071 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 1072 | "dev": true 1073 | }, 1074 | "is-plain-obj": { 1075 | "version": "1.1.0", 1076 | "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", 1077 | "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", 1078 | "dev": true 1079 | }, 1080 | "is-regex": { 1081 | "version": "1.1.1", 1082 | "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", 1083 | "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", 1084 | "dev": true, 1085 | "requires": { 1086 | "has-symbols": "^1.0.1" 1087 | } 1088 | }, 1089 | "is-set": { 1090 | "version": "2.0.1", 1091 | "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.1.tgz", 1092 | "integrity": "sha512-eJEzOtVyenDs1TMzSQ3kU3K+E0GUS9sno+F0OBT97xsgcJsF9nXMBtkT9/kut5JEpM7oL7X/0qxR17K3mcwIAA==", 1093 | "dev": true 1094 | }, 1095 | "is-string": { 1096 | "version": "1.0.5", 1097 | "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", 1098 | "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", 1099 | "dev": true 1100 | }, 1101 | "is-symbol": { 1102 | "version": "1.0.3", 1103 | "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", 1104 | "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", 1105 | "dev": true, 1106 | "requires": { 1107 | "has-symbols": "^1.0.1" 1108 | } 1109 | }, 1110 | "isarray": { 1111 | "version": "2.0.5", 1112 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", 1113 | "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", 1114 | "dev": true 1115 | }, 1116 | "isexe": { 1117 | "version": "2.0.0", 1118 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 1119 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", 1120 | "dev": true 1121 | }, 1122 | "iterate-iterator": { 1123 | "version": "1.0.1", 1124 | "resolved": "https://registry.npmjs.org/iterate-iterator/-/iterate-iterator-1.0.1.tgz", 1125 | "integrity": "sha512-3Q6tudGN05kbkDQDI4CqjaBf4qf85w6W6GnuZDtUVYwKgtC1q8yxYX7CZed7N+tLzQqS6roujWvszf13T+n9aw==", 1126 | "dev": true 1127 | }, 1128 | "iterate-value": { 1129 | "version": "1.0.2", 1130 | "resolved": "https://registry.npmjs.org/iterate-value/-/iterate-value-1.0.2.tgz", 1131 | "integrity": "sha512-A6fMAio4D2ot2r/TYzr4yUWrmwNdsN5xL7+HUiyACE4DXm+q8HtPcnFTp+NnW3k4N05tZ7FVYFFb2CR13NxyHQ==", 1132 | "dev": true, 1133 | "requires": { 1134 | "es-get-iterator": "^1.0.2", 1135 | "iterate-iterator": "^1.0.1" 1136 | } 1137 | }, 1138 | "js-tokens": { 1139 | "version": "4.0.0", 1140 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", 1141 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", 1142 | "dev": true 1143 | }, 1144 | "js-yaml": { 1145 | "version": "3.14.0", 1146 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", 1147 | "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", 1148 | "requires": { 1149 | "argparse": "^1.0.7", 1150 | "esprima": "^4.0.0" 1151 | } 1152 | }, 1153 | "json-schema-traverse": { 1154 | "version": "0.4.1", 1155 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 1156 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", 1157 | "dev": true 1158 | }, 1159 | "json-stable-stringify-without-jsonify": { 1160 | "version": "1.0.1", 1161 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", 1162 | "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", 1163 | "dev": true 1164 | }, 1165 | "jsx-ast-utils": { 1166 | "version": "2.4.1", 1167 | "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.4.1.tgz", 1168 | "integrity": "sha512-z1xSldJ6imESSzOjd3NNkieVJKRlKYSOtMG8SFyCj2FIrvSaSuli/WjpBkEzCBoR9bYYYFgqJw61Xhu7Lcgk+w==", 1169 | "dev": true, 1170 | "requires": { 1171 | "array-includes": "^3.1.1", 1172 | "object.assign": "^4.1.0" 1173 | } 1174 | }, 1175 | "levn": { 1176 | "version": "0.4.1", 1177 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", 1178 | "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", 1179 | "dev": true, 1180 | "requires": { 1181 | "prelude-ls": "^1.2.1", 1182 | "type-check": "~0.4.0" 1183 | } 1184 | }, 1185 | "locate-path": { 1186 | "version": "5.0.0", 1187 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", 1188 | "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", 1189 | "dev": true, 1190 | "requires": { 1191 | "p-locate": "^4.1.0" 1192 | } 1193 | }, 1194 | "lodash": { 1195 | "version": "4.17.20", 1196 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", 1197 | "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", 1198 | "dev": true 1199 | }, 1200 | "log-symbols": { 1201 | "version": "3.0.0", 1202 | "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", 1203 | "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", 1204 | "dev": true, 1205 | "requires": { 1206 | "chalk": "^2.4.2" 1207 | }, 1208 | "dependencies": { 1209 | "chalk": { 1210 | "version": "2.4.2", 1211 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 1212 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 1213 | "dev": true, 1214 | "requires": { 1215 | "ansi-styles": "^3.2.1", 1216 | "escape-string-regexp": "^1.0.5", 1217 | "supports-color": "^5.3.0" 1218 | } 1219 | }, 1220 | "supports-color": { 1221 | "version": "5.5.0", 1222 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 1223 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 1224 | "dev": true, 1225 | "requires": { 1226 | "has-flag": "^3.0.0" 1227 | } 1228 | } 1229 | } 1230 | }, 1231 | "loose-envify": { 1232 | "version": "1.4.0", 1233 | "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", 1234 | "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", 1235 | "dev": true, 1236 | "requires": { 1237 | "js-tokens": "^3.0.0 || ^4.0.0" 1238 | } 1239 | }, 1240 | "minimatch": { 1241 | "version": "3.0.4", 1242 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 1243 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 1244 | "dev": true, 1245 | "requires": { 1246 | "brace-expansion": "^1.1.7" 1247 | } 1248 | }, 1249 | "minimist": { 1250 | "version": "1.2.5", 1251 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", 1252 | "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", 1253 | "dev": true 1254 | }, 1255 | "mkdirp": { 1256 | "version": "0.5.5", 1257 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", 1258 | "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", 1259 | "dev": true, 1260 | "requires": { 1261 | "minimist": "^1.2.5" 1262 | } 1263 | }, 1264 | "mocha": { 1265 | "version": "8.1.1", 1266 | "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.1.1.tgz", 1267 | "integrity": "sha512-p7FuGlYH8t7gaiodlFreseLxEmxTgvyG9RgPHODFPySNhwUehu8NIb0vdSt3WFckSneswZ0Un5typYcWElk7HQ==", 1268 | "dev": true, 1269 | "requires": { 1270 | "ansi-colors": "4.1.1", 1271 | "browser-stdout": "1.3.1", 1272 | "chokidar": "3.3.1", 1273 | "debug": "3.2.6", 1274 | "diff": "4.0.2", 1275 | "escape-string-regexp": "1.0.5", 1276 | "find-up": "4.1.0", 1277 | "glob": "7.1.6", 1278 | "growl": "1.10.5", 1279 | "he": "1.2.0", 1280 | "js-yaml": "3.13.1", 1281 | "log-symbols": "3.0.0", 1282 | "minimatch": "3.0.4", 1283 | "ms": "2.1.2", 1284 | "object.assign": "4.1.0", 1285 | "promise.allsettled": "1.0.2", 1286 | "serialize-javascript": "4.0.0", 1287 | "strip-json-comments": "3.0.1", 1288 | "supports-color": "7.1.0", 1289 | "which": "2.0.2", 1290 | "wide-align": "1.1.3", 1291 | "workerpool": "6.0.0", 1292 | "yargs": "13.3.2", 1293 | "yargs-parser": "13.1.2", 1294 | "yargs-unparser": "1.6.1" 1295 | }, 1296 | "dependencies": { 1297 | "debug": { 1298 | "version": "3.2.6", 1299 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", 1300 | "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", 1301 | "dev": true, 1302 | "requires": { 1303 | "ms": "^2.1.1" 1304 | } 1305 | }, 1306 | "js-yaml": { 1307 | "version": "3.13.1", 1308 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", 1309 | "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", 1310 | "dev": true, 1311 | "requires": { 1312 | "argparse": "^1.0.7", 1313 | "esprima": "^4.0.0" 1314 | } 1315 | }, 1316 | "locate-path": { 1317 | "version": "3.0.0", 1318 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", 1319 | "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", 1320 | "dev": true, 1321 | "requires": { 1322 | "p-locate": "^3.0.0", 1323 | "path-exists": "^3.0.0" 1324 | } 1325 | }, 1326 | "p-locate": { 1327 | "version": "3.0.0", 1328 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", 1329 | "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", 1330 | "dev": true, 1331 | "requires": { 1332 | "p-limit": "^2.0.0" 1333 | } 1334 | }, 1335 | "path-exists": { 1336 | "version": "3.0.0", 1337 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", 1338 | "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", 1339 | "dev": true 1340 | }, 1341 | "strip-json-comments": { 1342 | "version": "3.0.1", 1343 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", 1344 | "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", 1345 | "dev": true 1346 | }, 1347 | "yargs": { 1348 | "version": "13.3.2", 1349 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", 1350 | "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", 1351 | "dev": true, 1352 | "requires": { 1353 | "cliui": "^5.0.0", 1354 | "find-up": "^3.0.0", 1355 | "get-caller-file": "^2.0.1", 1356 | "require-directory": "^2.1.1", 1357 | "require-main-filename": "^2.0.0", 1358 | "set-blocking": "^2.0.0", 1359 | "string-width": "^3.0.0", 1360 | "which-module": "^2.0.0", 1361 | "y18n": "^4.0.0", 1362 | "yargs-parser": "^13.1.2" 1363 | }, 1364 | "dependencies": { 1365 | "find-up": { 1366 | "version": "3.0.0", 1367 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", 1368 | "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", 1369 | "dev": true, 1370 | "requires": { 1371 | "locate-path": "^3.0.0" 1372 | } 1373 | } 1374 | } 1375 | } 1376 | } 1377 | }, 1378 | "mri": { 1379 | "version": "1.1.5", 1380 | "resolved": "https://registry.npmjs.org/mri/-/mri-1.1.5.tgz", 1381 | "integrity": "sha512-d2RKzMD4JNyHMbnbWnznPaa8vbdlq/4pNZ3IgdaGrVbBhebBsGUUE/6qorTMYNS6TwuH3ilfOlD2bf4Igh8CKg==" 1382 | }, 1383 | "ms": { 1384 | "version": "2.1.2", 1385 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 1386 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 1387 | "dev": true 1388 | }, 1389 | "natural-compare": { 1390 | "version": "1.4.0", 1391 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", 1392 | "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", 1393 | "dev": true 1394 | }, 1395 | "normalize-path": { 1396 | "version": "3.0.0", 1397 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", 1398 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", 1399 | "dev": true 1400 | }, 1401 | "object-assign": { 1402 | "version": "4.1.1", 1403 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 1404 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", 1405 | "dev": true 1406 | }, 1407 | "object-inspect": { 1408 | "version": "1.8.0", 1409 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", 1410 | "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", 1411 | "dev": true 1412 | }, 1413 | "object-keys": { 1414 | "version": "1.1.1", 1415 | "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", 1416 | "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", 1417 | "dev": true 1418 | }, 1419 | "object.assign": { 1420 | "version": "4.1.0", 1421 | "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", 1422 | "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", 1423 | "dev": true, 1424 | "requires": { 1425 | "define-properties": "^1.1.2", 1426 | "function-bind": "^1.1.1", 1427 | "has-symbols": "^1.0.0", 1428 | "object-keys": "^1.0.11" 1429 | } 1430 | }, 1431 | "object.entries": { 1432 | "version": "1.1.2", 1433 | "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.2.tgz", 1434 | "integrity": "sha512-BQdB9qKmb/HyNdMNWVr7O3+z5MUIx3aiegEIJqjMBbBf0YT9RRxTJSim4mzFqtyr7PDAHigq0N9dO0m0tRakQA==", 1435 | "dev": true, 1436 | "requires": { 1437 | "define-properties": "^1.1.3", 1438 | "es-abstract": "^1.17.5", 1439 | "has": "^1.0.3" 1440 | } 1441 | }, 1442 | "object.fromentries": { 1443 | "version": "2.0.2", 1444 | "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.2.tgz", 1445 | "integrity": "sha512-r3ZiBH7MQppDJVLx6fhD618GKNG40CZYH9wgwdhKxBDDbQgjeWGGd4AtkZad84d291YxvWe7bJGuE65Anh0dxQ==", 1446 | "dev": true, 1447 | "requires": { 1448 | "define-properties": "^1.1.3", 1449 | "es-abstract": "^1.17.0-next.1", 1450 | "function-bind": "^1.1.1", 1451 | "has": "^1.0.3" 1452 | } 1453 | }, 1454 | "object.values": { 1455 | "version": "1.1.1", 1456 | "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", 1457 | "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", 1458 | "dev": true, 1459 | "requires": { 1460 | "define-properties": "^1.1.3", 1461 | "es-abstract": "^1.17.0-next.1", 1462 | "function-bind": "^1.1.1", 1463 | "has": "^1.0.3" 1464 | } 1465 | }, 1466 | "once": { 1467 | "version": "1.4.0", 1468 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1469 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 1470 | "dev": true, 1471 | "requires": { 1472 | "wrappy": "1" 1473 | } 1474 | }, 1475 | "optionator": { 1476 | "version": "0.9.1", 1477 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", 1478 | "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", 1479 | "dev": true, 1480 | "requires": { 1481 | "deep-is": "^0.1.3", 1482 | "fast-levenshtein": "^2.0.6", 1483 | "levn": "^0.4.1", 1484 | "prelude-ls": "^1.2.1", 1485 | "type-check": "^0.4.0", 1486 | "word-wrap": "^1.2.3" 1487 | } 1488 | }, 1489 | "p-limit": { 1490 | "version": "2.3.0", 1491 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", 1492 | "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", 1493 | "dev": true, 1494 | "requires": { 1495 | "p-try": "^2.0.0" 1496 | } 1497 | }, 1498 | "p-locate": { 1499 | "version": "4.1.0", 1500 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", 1501 | "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", 1502 | "dev": true, 1503 | "requires": { 1504 | "p-limit": "^2.2.0" 1505 | } 1506 | }, 1507 | "p-try": { 1508 | "version": "2.2.0", 1509 | "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", 1510 | "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", 1511 | "dev": true 1512 | }, 1513 | "parent-module": { 1514 | "version": "1.0.1", 1515 | "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", 1516 | "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", 1517 | "dev": true, 1518 | "requires": { 1519 | "callsites": "^3.0.0" 1520 | } 1521 | }, 1522 | "path-exists": { 1523 | "version": "4.0.0", 1524 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", 1525 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", 1526 | "dev": true 1527 | }, 1528 | "path-is-absolute": { 1529 | "version": "1.0.1", 1530 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 1531 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 1532 | "dev": true 1533 | }, 1534 | "path-key": { 1535 | "version": "3.1.1", 1536 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", 1537 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", 1538 | "dev": true 1539 | }, 1540 | "path-parse": { 1541 | "version": "1.0.6", 1542 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", 1543 | "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", 1544 | "dev": true 1545 | }, 1546 | "picomatch": { 1547 | "version": "2.2.2", 1548 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", 1549 | "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", 1550 | "dev": true 1551 | }, 1552 | "prelude-ls": { 1553 | "version": "1.2.1", 1554 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", 1555 | "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", 1556 | "dev": true 1557 | }, 1558 | "prettier": { 1559 | "version": "2.0.5", 1560 | "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.5.tgz", 1561 | "integrity": "sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==", 1562 | "dev": true 1563 | }, 1564 | "progress": { 1565 | "version": "2.0.3", 1566 | "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", 1567 | "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", 1568 | "dev": true 1569 | }, 1570 | "promise.allsettled": { 1571 | "version": "1.0.2", 1572 | "resolved": "https://registry.npmjs.org/promise.allsettled/-/promise.allsettled-1.0.2.tgz", 1573 | "integrity": "sha512-UpcYW5S1RaNKT6pd+s9jp9K9rlQge1UXKskec0j6Mmuq7UJCvlS2J2/s/yuPN8ehftf9HXMxWlKiPbGGUzpoRg==", 1574 | "dev": true, 1575 | "requires": { 1576 | "array.prototype.map": "^1.0.1", 1577 | "define-properties": "^1.1.3", 1578 | "es-abstract": "^1.17.0-next.1", 1579 | "function-bind": "^1.1.1", 1580 | "iterate-value": "^1.0.0" 1581 | } 1582 | }, 1583 | "prop-types": { 1584 | "version": "15.7.2", 1585 | "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", 1586 | "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", 1587 | "dev": true, 1588 | "requires": { 1589 | "loose-envify": "^1.4.0", 1590 | "object-assign": "^4.1.1", 1591 | "react-is": "^16.8.1" 1592 | } 1593 | }, 1594 | "punycode": { 1595 | "version": "2.1.1", 1596 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", 1597 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", 1598 | "dev": true 1599 | }, 1600 | "randombytes": { 1601 | "version": "2.1.0", 1602 | "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", 1603 | "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", 1604 | "dev": true, 1605 | "requires": { 1606 | "safe-buffer": "^5.1.0" 1607 | } 1608 | }, 1609 | "react": { 1610 | "version": "16.13.1", 1611 | "resolved": "https://registry.npmjs.org/react/-/react-16.13.1.tgz", 1612 | "integrity": "sha512-YMZQQq32xHLX0bz5Mnibv1/LHb3Sqzngu7xstSM+vrkE5Kzr9xE0yMByK5kMoTK30YVJE61WfbxIFFvfeDKT1w==", 1613 | "dev": true, 1614 | "optional": true, 1615 | "requires": { 1616 | "loose-envify": "^1.1.0", 1617 | "object-assign": "^4.1.1", 1618 | "prop-types": "^15.6.2" 1619 | } 1620 | }, 1621 | "react-is": { 1622 | "version": "16.13.1", 1623 | "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", 1624 | "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", 1625 | "dev": true 1626 | }, 1627 | "readdirp": { 1628 | "version": "3.3.0", 1629 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.3.0.tgz", 1630 | "integrity": "sha512-zz0pAkSPOXXm1viEwygWIPSPkcBYjW1xU5j/JBh5t9bGCJwa6f9+BJa6VaB2g+b55yVrmXzqkyLf4xaWYM0IkQ==", 1631 | "dev": true, 1632 | "requires": { 1633 | "picomatch": "^2.0.7" 1634 | } 1635 | }, 1636 | "regexp.prototype.flags": { 1637 | "version": "1.3.0", 1638 | "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz", 1639 | "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==", 1640 | "dev": true, 1641 | "requires": { 1642 | "define-properties": "^1.1.3", 1643 | "es-abstract": "^1.17.0-next.1" 1644 | } 1645 | }, 1646 | "regexpp": { 1647 | "version": "3.1.0", 1648 | "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", 1649 | "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", 1650 | "dev": true 1651 | }, 1652 | "require-directory": { 1653 | "version": "2.1.1", 1654 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", 1655 | "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", 1656 | "dev": true 1657 | }, 1658 | "require-main-filename": { 1659 | "version": "2.0.0", 1660 | "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", 1661 | "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", 1662 | "dev": true 1663 | }, 1664 | "resolve": { 1665 | "version": "1.17.0", 1666 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", 1667 | "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", 1668 | "dev": true, 1669 | "requires": { 1670 | "path-parse": "^1.0.6" 1671 | } 1672 | }, 1673 | "resolve-from": { 1674 | "version": "4.0.0", 1675 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", 1676 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", 1677 | "dev": true 1678 | }, 1679 | "rimraf": { 1680 | "version": "2.6.3", 1681 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", 1682 | "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", 1683 | "dev": true, 1684 | "requires": { 1685 | "glob": "^7.1.3" 1686 | } 1687 | }, 1688 | "sade": { 1689 | "version": "1.7.3", 1690 | "resolved": "https://registry.npmjs.org/sade/-/sade-1.7.3.tgz", 1691 | "integrity": "sha512-m4BctppMvJ60W1dXnHq7jMmFe3hPJZDAH85kQ3ACTo7XZNVUuTItCQ+2HfyaMeV5cKrbw7l4vD/6We3GBxvdJw==", 1692 | "requires": { 1693 | "mri": "^1.1.0" 1694 | } 1695 | }, 1696 | "safe-buffer": { 1697 | "version": "5.2.1", 1698 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 1699 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 1700 | "dev": true 1701 | }, 1702 | "semver": { 1703 | "version": "7.3.2", 1704 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", 1705 | "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", 1706 | "dev": true 1707 | }, 1708 | "serialize-javascript": { 1709 | "version": "4.0.0", 1710 | "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", 1711 | "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", 1712 | "dev": true, 1713 | "requires": { 1714 | "randombytes": "^2.1.0" 1715 | } 1716 | }, 1717 | "set-blocking": { 1718 | "version": "2.0.0", 1719 | "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", 1720 | "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", 1721 | "dev": true 1722 | }, 1723 | "shebang-command": { 1724 | "version": "2.0.0", 1725 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", 1726 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", 1727 | "dev": true, 1728 | "requires": { 1729 | "shebang-regex": "^3.0.0" 1730 | } 1731 | }, 1732 | "shebang-regex": { 1733 | "version": "3.0.0", 1734 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", 1735 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", 1736 | "dev": true 1737 | }, 1738 | "side-channel": { 1739 | "version": "1.0.2", 1740 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.2.tgz", 1741 | "integrity": "sha512-7rL9YlPHg7Ancea1S96Pa8/QWb4BtXL/TZvS6B8XFetGBeuhAsfmUspK6DokBeZ64+Kj9TCNRD/30pVz1BvQNA==", 1742 | "dev": true, 1743 | "requires": { 1744 | "es-abstract": "^1.17.0-next.1", 1745 | "object-inspect": "^1.7.0" 1746 | } 1747 | }, 1748 | "slice-ansi": { 1749 | "version": "2.1.0", 1750 | "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", 1751 | "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", 1752 | "dev": true, 1753 | "requires": { 1754 | "ansi-styles": "^3.2.0", 1755 | "astral-regex": "^1.0.0", 1756 | "is-fullwidth-code-point": "^2.0.0" 1757 | } 1758 | }, 1759 | "sprintf-js": { 1760 | "version": "1.0.3", 1761 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", 1762 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" 1763 | }, 1764 | "string-width": { 1765 | "version": "3.1.0", 1766 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", 1767 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", 1768 | "dev": true, 1769 | "requires": { 1770 | "emoji-regex": "^7.0.1", 1771 | "is-fullwidth-code-point": "^2.0.0", 1772 | "strip-ansi": "^5.1.0" 1773 | }, 1774 | "dependencies": { 1775 | "ansi-regex": { 1776 | "version": "4.1.0", 1777 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", 1778 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", 1779 | "dev": true 1780 | }, 1781 | "strip-ansi": { 1782 | "version": "5.2.0", 1783 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", 1784 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", 1785 | "dev": true, 1786 | "requires": { 1787 | "ansi-regex": "^4.1.0" 1788 | } 1789 | } 1790 | } 1791 | }, 1792 | "string.prototype.matchall": { 1793 | "version": "4.0.2", 1794 | "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.2.tgz", 1795 | "integrity": "sha512-N/jp6O5fMf9os0JU3E72Qhf590RSRZU/ungsL/qJUYVTNv7hTG0P/dbPjxINVN9jpscu3nzYwKESU3P3RY5tOg==", 1796 | "dev": true, 1797 | "requires": { 1798 | "define-properties": "^1.1.3", 1799 | "es-abstract": "^1.17.0", 1800 | "has-symbols": "^1.0.1", 1801 | "internal-slot": "^1.0.2", 1802 | "regexp.prototype.flags": "^1.3.0", 1803 | "side-channel": "^1.0.2" 1804 | } 1805 | }, 1806 | "string.prototype.trimend": { 1807 | "version": "1.0.1", 1808 | "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", 1809 | "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", 1810 | "dev": true, 1811 | "requires": { 1812 | "define-properties": "^1.1.3", 1813 | "es-abstract": "^1.17.5" 1814 | } 1815 | }, 1816 | "string.prototype.trimstart": { 1817 | "version": "1.0.1", 1818 | "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", 1819 | "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", 1820 | "dev": true, 1821 | "requires": { 1822 | "define-properties": "^1.1.3", 1823 | "es-abstract": "^1.17.5" 1824 | } 1825 | }, 1826 | "strip-ansi": { 1827 | "version": "6.0.0", 1828 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", 1829 | "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", 1830 | "dev": true, 1831 | "requires": { 1832 | "ansi-regex": "^5.0.0" 1833 | } 1834 | }, 1835 | "strip-json-comments": { 1836 | "version": "3.1.1", 1837 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", 1838 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", 1839 | "dev": true 1840 | }, 1841 | "supports-color": { 1842 | "version": "7.1.0", 1843 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", 1844 | "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", 1845 | "requires": { 1846 | "has-flag": "^4.0.0" 1847 | }, 1848 | "dependencies": { 1849 | "has-flag": { 1850 | "version": "4.0.0", 1851 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 1852 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" 1853 | } 1854 | } 1855 | }, 1856 | "table": { 1857 | "version": "5.4.6", 1858 | "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", 1859 | "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", 1860 | "dev": true, 1861 | "requires": { 1862 | "ajv": "^6.10.2", 1863 | "lodash": "^4.17.14", 1864 | "slice-ansi": "^2.1.0", 1865 | "string-width": "^3.0.0" 1866 | } 1867 | }, 1868 | "text-table": { 1869 | "version": "0.2.0", 1870 | "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", 1871 | "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", 1872 | "dev": true 1873 | }, 1874 | "to-regex-range": { 1875 | "version": "5.0.1", 1876 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 1877 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 1878 | "dev": true, 1879 | "requires": { 1880 | "is-number": "^7.0.0" 1881 | } 1882 | }, 1883 | "tslib": { 1884 | "version": "1.13.0", 1885 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", 1886 | "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", 1887 | "dev": true 1888 | }, 1889 | "tsutils": { 1890 | "version": "3.17.1", 1891 | "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", 1892 | "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", 1893 | "dev": true, 1894 | "requires": { 1895 | "tslib": "^1.8.1" 1896 | } 1897 | }, 1898 | "type-check": { 1899 | "version": "0.4.0", 1900 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", 1901 | "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", 1902 | "dev": true, 1903 | "requires": { 1904 | "prelude-ls": "^1.2.1" 1905 | } 1906 | }, 1907 | "type-fest": { 1908 | "version": "0.8.1", 1909 | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", 1910 | "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", 1911 | "dev": true 1912 | }, 1913 | "typescript": { 1914 | "version": "3.9.7", 1915 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.7.tgz", 1916 | "integrity": "sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw==", 1917 | "dev": true, 1918 | "optional": true 1919 | }, 1920 | "uri-js": { 1921 | "version": "4.2.2", 1922 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", 1923 | "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", 1924 | "dev": true, 1925 | "requires": { 1926 | "punycode": "^2.1.0" 1927 | } 1928 | }, 1929 | "v8-compile-cache": { 1930 | "version": "2.1.1", 1931 | "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz", 1932 | "integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==", 1933 | "dev": true 1934 | }, 1935 | "which": { 1936 | "version": "2.0.2", 1937 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 1938 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 1939 | "dev": true, 1940 | "requires": { 1941 | "isexe": "^2.0.0" 1942 | } 1943 | }, 1944 | "which-module": { 1945 | "version": "2.0.0", 1946 | "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", 1947 | "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", 1948 | "dev": true 1949 | }, 1950 | "wide-align": { 1951 | "version": "1.1.3", 1952 | "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", 1953 | "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", 1954 | "dev": true, 1955 | "requires": { 1956 | "string-width": "^1.0.2 || 2" 1957 | }, 1958 | "dependencies": { 1959 | "ansi-regex": { 1960 | "version": "3.0.0", 1961 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", 1962 | "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", 1963 | "dev": true 1964 | }, 1965 | "string-width": { 1966 | "version": "2.1.1", 1967 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", 1968 | "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", 1969 | "dev": true, 1970 | "requires": { 1971 | "is-fullwidth-code-point": "^2.0.0", 1972 | "strip-ansi": "^4.0.0" 1973 | } 1974 | }, 1975 | "strip-ansi": { 1976 | "version": "4.0.0", 1977 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", 1978 | "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", 1979 | "dev": true, 1980 | "requires": { 1981 | "ansi-regex": "^3.0.0" 1982 | } 1983 | } 1984 | } 1985 | }, 1986 | "word-wrap": { 1987 | "version": "1.2.3", 1988 | "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", 1989 | "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", 1990 | "dev": true 1991 | }, 1992 | "workerpool": { 1993 | "version": "6.0.0", 1994 | "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.0.0.tgz", 1995 | "integrity": "sha512-fU2OcNA/GVAJLLyKUoHkAgIhKb0JoCpSjLC/G2vYKxUjVmQwGbRVeoPJ1a8U4pnVofz4AQV5Y/NEw8oKqxEBtA==", 1996 | "dev": true 1997 | }, 1998 | "wrap-ansi": { 1999 | "version": "5.1.0", 2000 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", 2001 | "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", 2002 | "dev": true, 2003 | "requires": { 2004 | "ansi-styles": "^3.2.0", 2005 | "string-width": "^3.0.0", 2006 | "strip-ansi": "^5.0.0" 2007 | }, 2008 | "dependencies": { 2009 | "ansi-regex": { 2010 | "version": "4.1.0", 2011 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", 2012 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", 2013 | "dev": true 2014 | }, 2015 | "strip-ansi": { 2016 | "version": "5.2.0", 2017 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", 2018 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", 2019 | "dev": true, 2020 | "requires": { 2021 | "ansi-regex": "^4.1.0" 2022 | } 2023 | } 2024 | } 2025 | }, 2026 | "wrappy": { 2027 | "version": "1.0.2", 2028 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 2029 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 2030 | "dev": true 2031 | }, 2032 | "write": { 2033 | "version": "1.0.3", 2034 | "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", 2035 | "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", 2036 | "dev": true, 2037 | "requires": { 2038 | "mkdirp": "^0.5.1" 2039 | } 2040 | }, 2041 | "y18n": { 2042 | "version": "4.0.0", 2043 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", 2044 | "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", 2045 | "dev": true 2046 | }, 2047 | "yargs": { 2048 | "version": "15.4.1", 2049 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", 2050 | "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", 2051 | "dev": true, 2052 | "requires": { 2053 | "cliui": "^6.0.0", 2054 | "decamelize": "^1.2.0", 2055 | "find-up": "^4.1.0", 2056 | "get-caller-file": "^2.0.1", 2057 | "require-directory": "^2.1.1", 2058 | "require-main-filename": "^2.0.0", 2059 | "set-blocking": "^2.0.0", 2060 | "string-width": "^4.2.0", 2061 | "which-module": "^2.0.0", 2062 | "y18n": "^4.0.0", 2063 | "yargs-parser": "^18.1.2" 2064 | }, 2065 | "dependencies": { 2066 | "ansi-styles": { 2067 | "version": "4.2.1", 2068 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", 2069 | "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", 2070 | "dev": true, 2071 | "requires": { 2072 | "@types/color-name": "^1.1.1", 2073 | "color-convert": "^2.0.1" 2074 | } 2075 | }, 2076 | "cliui": { 2077 | "version": "6.0.0", 2078 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", 2079 | "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", 2080 | "dev": true, 2081 | "requires": { 2082 | "string-width": "^4.2.0", 2083 | "strip-ansi": "^6.0.0", 2084 | "wrap-ansi": "^6.2.0" 2085 | } 2086 | }, 2087 | "color-convert": { 2088 | "version": "2.0.1", 2089 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 2090 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 2091 | "dev": true, 2092 | "requires": { 2093 | "color-name": "~1.1.4" 2094 | } 2095 | }, 2096 | "color-name": { 2097 | "version": "1.1.4", 2098 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 2099 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 2100 | "dev": true 2101 | }, 2102 | "emoji-regex": { 2103 | "version": "8.0.0", 2104 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 2105 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 2106 | "dev": true 2107 | }, 2108 | "is-fullwidth-code-point": { 2109 | "version": "3.0.0", 2110 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 2111 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", 2112 | "dev": true 2113 | }, 2114 | "string-width": { 2115 | "version": "4.2.0", 2116 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", 2117 | "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", 2118 | "dev": true, 2119 | "requires": { 2120 | "emoji-regex": "^8.0.0", 2121 | "is-fullwidth-code-point": "^3.0.0", 2122 | "strip-ansi": "^6.0.0" 2123 | } 2124 | }, 2125 | "wrap-ansi": { 2126 | "version": "6.2.0", 2127 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", 2128 | "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", 2129 | "dev": true, 2130 | "requires": { 2131 | "ansi-styles": "^4.0.0", 2132 | "string-width": "^4.1.0", 2133 | "strip-ansi": "^6.0.0" 2134 | } 2135 | }, 2136 | "yargs-parser": { 2137 | "version": "18.1.3", 2138 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", 2139 | "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", 2140 | "dev": true, 2141 | "requires": { 2142 | "camelcase": "^5.0.0", 2143 | "decamelize": "^1.2.0" 2144 | } 2145 | } 2146 | } 2147 | }, 2148 | "yargs-parser": { 2149 | "version": "13.1.2", 2150 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", 2151 | "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", 2152 | "dev": true, 2153 | "requires": { 2154 | "camelcase": "^5.0.0", 2155 | "decamelize": "^1.2.0" 2156 | } 2157 | }, 2158 | "yargs-unparser": { 2159 | "version": "1.6.1", 2160 | "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.1.tgz", 2161 | "integrity": "sha512-qZV14lK9MWsGCmcr7u5oXGH0dbGqZAIxTDrWXZDo5zUr6b6iUmelNKO6x6R1dQT24AH3LgRxJpr8meWy2unolA==", 2162 | "dev": true, 2163 | "requires": { 2164 | "camelcase": "^5.3.1", 2165 | "decamelize": "^1.2.0", 2166 | "flat": "^4.1.0", 2167 | "is-plain-obj": "^1.1.0", 2168 | "yargs": "^14.2.3" 2169 | }, 2170 | "dependencies": { 2171 | "find-up": { 2172 | "version": "3.0.0", 2173 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", 2174 | "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", 2175 | "dev": true, 2176 | "requires": { 2177 | "locate-path": "^3.0.0" 2178 | } 2179 | }, 2180 | "locate-path": { 2181 | "version": "3.0.0", 2182 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", 2183 | "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", 2184 | "dev": true, 2185 | "requires": { 2186 | "p-locate": "^3.0.0", 2187 | "path-exists": "^3.0.0" 2188 | } 2189 | }, 2190 | "p-locate": { 2191 | "version": "3.0.0", 2192 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", 2193 | "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", 2194 | "dev": true, 2195 | "requires": { 2196 | "p-limit": "^2.0.0" 2197 | } 2198 | }, 2199 | "path-exists": { 2200 | "version": "3.0.0", 2201 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", 2202 | "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", 2203 | "dev": true 2204 | }, 2205 | "yargs": { 2206 | "version": "14.2.3", 2207 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-14.2.3.tgz", 2208 | "integrity": "sha512-ZbotRWhF+lkjijC/VhmOT9wSgyBQ7+zr13+YLkhfsSiTriYsMzkTUFP18pFhWwBeMa5gUc1MzbhrO6/VB7c9Xg==", 2209 | "dev": true, 2210 | "requires": { 2211 | "cliui": "^5.0.0", 2212 | "decamelize": "^1.2.0", 2213 | "find-up": "^3.0.0", 2214 | "get-caller-file": "^2.0.1", 2215 | "require-directory": "^2.1.1", 2216 | "require-main-filename": "^2.0.0", 2217 | "set-blocking": "^2.0.0", 2218 | "string-width": "^3.0.0", 2219 | "which-module": "^2.0.0", 2220 | "y18n": "^4.0.0", 2221 | "yargs-parser": "^15.0.1" 2222 | } 2223 | }, 2224 | "yargs-parser": { 2225 | "version": "15.0.1", 2226 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.1.tgz", 2227 | "integrity": "sha512-0OAMV2mAZQrs3FkNpDQcBk1x5HXb8X4twADss4S0Iuk+2dGnLOE/fRHrsYm542GduMveyA77OF4wrNJuanRCWw==", 2228 | "dev": true, 2229 | "requires": { 2230 | "camelcase": "^5.0.0", 2231 | "decamelize": "^1.2.0" 2232 | } 2233 | } 2234 | } 2235 | } 2236 | } 2237 | } 2238 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sammie", 3 | "version": "1.2.1", 4 | "description": "Serverless Application Model Made Infinitely Easier", 5 | "license": "MIT", 6 | "author": "Garth Poitras ", 7 | "repository": { 8 | "type": "git", 9 | "url": "git+https://github.com/bustle/sammie.git" 10 | }, 11 | "keywords": [ 12 | "aws", 13 | "sam", 14 | "serverless", 15 | "lambda", 16 | "api-gateway", 17 | "cloudformation" 18 | ], 19 | "main": "src/index.js", 20 | "bin": "src/bin.js", 21 | "files": [ 22 | "src" 23 | ], 24 | "engines": { 25 | "node": ">=10" 26 | }, 27 | "dependencies": { 28 | "chalk": "^4.1.0", 29 | "cloudformation-schema-js-yaml": "^1.0.1", 30 | "deepmerge": "^4.2.2", 31 | "js-yaml": "^3.14.0", 32 | "sade": "^1.7.3" 33 | }, 34 | "devDependencies": { 35 | "flt": "^0.32.0" 36 | }, 37 | "scripts": { 38 | "test": "flt", 39 | "clean": "rm -f index.js | rm -f sam*.json | rm -f sam*.yaml | rm -f .*cache" 40 | }, 41 | "prettier": "flt/config/prettier.config.js" 42 | } 43 | -------------------------------------------------------------------------------- /src/bin.js: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env node 2 | 3 | require('.').parse(process.argv) 4 | -------------------------------------------------------------------------------- /src/commands/deploy.js: -------------------------------------------------------------------------------- 1 | const { join } = require('path') 2 | const { statSync } = require('fs') 3 | const validate = require('./validate') 4 | const packageProject = require('./package') 5 | const log = require('../log') 6 | const { spawnAsync, deleteFileAsync } = require('../utils') 7 | 8 | async function deployStack(templatePathPackaged, stackName, bucketName, capabilities, parameters) { 9 | const parametersFlag = parameters && parameters.length && parameters.join(' ') 10 | const templateStats = statSync(join(process.cwd(), templatePathPackaged)) 11 | const command = 12 | `aws cloudformation deploy ` + 13 | `--template-file ${templatePathPackaged} ` + 14 | `--stack-name ${stackName} ` + 15 | `--capabilities ${capabilities || 'CAPABILITY_IAM'} ` + 16 | `${templateStats.size > 51200 ? '--s3-bucket ' + bucketName : ''} ` + 17 | `${parametersFlag ? '--parameter-overrides ' + parametersFlag : ''}` 18 | log.info(`Deploying stack "${stackName}"...`).command(command) 19 | return spawnAsync(command) 20 | } 21 | 22 | async function getApiUrl(stackName) { 23 | const { StackResources } = await spawnAsync(`aws cloudformation describe-stack-resources --stack-name ${stackName}`) 24 | const apiInfo = StackResources && StackResources.find(({ ResourceType }) => ResourceType === 'AWS::ApiGatewayV2::Api') 25 | const apiId = apiInfo && apiInfo.PhysicalResourceId 26 | const region = apiInfo.StackId.split(':')[3] 27 | return apiId && region && `https://${apiId}.execute-api.${region}.amazonaws.com` 28 | } 29 | 30 | module.exports = async function deploy(input) { 31 | await validate(input) 32 | 33 | const packageResults = await packageProject(input) 34 | const { templatePathPackaged, environment, stackName, bucketName } = packageResults 35 | 36 | const deployParams = [].concat(input.parameters || [], `environment=${environment}`) 37 | try { 38 | await deployStack(templatePathPackaged, stackName, bucketName, input.capabilities, deployParams) 39 | log.success('Deployed') 40 | } finally { 41 | deleteFileAsync(templatePathPackaged) 42 | } 43 | 44 | try { 45 | const apiUrl = await getApiUrl(stackName) 46 | if (apiUrl) log.info('Live url:', apiUrl) 47 | } catch {} 48 | } 49 | -------------------------------------------------------------------------------- /src/commands/init.js: -------------------------------------------------------------------------------- 1 | const { join } = require('path') 2 | const yaml = require('js-yaml') 3 | const schema = require('cloudformation-schema-js-yaml') 4 | const { readFileAsync, writeFileAsync, spawnAsync } = require('../utils') 5 | const log = require('../log') 6 | const samTemplate = require('../templates/sam') 7 | 8 | async function getAccountId() { 9 | const command = `aws sts get-caller-identity` 10 | log.info('Getting AWS account id...').command(command) 11 | const data = await spawnAsync(command) 12 | const accountId = data.Account 13 | if (!accountId) throw Error('Could not get AWS account id') 14 | log.success('Account id:', accountId) 15 | return accountId 16 | } 17 | 18 | function stackSafeName(string) { 19 | return string.trim().replace(/[^a-z0-9]/gi, '-') 20 | } 21 | 22 | function resourceSafeName(string) { 23 | const pascaledString = string.replace(/(-|_|\.|\s)+(.)?/g, (m, s, c) => (c ? c.toUpperCase() : '')) 24 | return pascaledString.charAt(0).toUpperCase() + pascaledString.slice(1) 25 | } 26 | 27 | async function makeSamTemplate(stackName, accountId, input) { 28 | const useYaml = input.yaml 29 | const path = `sam.${useYaml ? 'yaml' : 'json'}` 30 | const templateString = JSON.stringify(samTemplate).replace(/__NAME__/g, resourceSafeName(stackName)) 31 | const template = JSON.parse(templateString) 32 | template.Parameters.bucketName.Default = `sam-uploads-${accountId}` 33 | template.Parameters.stackName.Default = stackName 34 | const content = useYaml ? yaml.safeDump(template, { schema }) : JSON.stringify(template, null, 2) + '\n' 35 | await writeFileAsync(path, content, { flag: 'wx' }) 36 | return path 37 | } 38 | 39 | async function makeLambdaFunction(name) { 40 | const path = 'index.js' 41 | const code = await readFileAsync(join(__dirname, '../templates/lambda.js'), 'utf8') 42 | const codeWithName = code.replace(/__NAME__/g, name) 43 | await writeFileAsync(path, codeWithName, { flag: 'wx' }) 44 | return path 45 | } 46 | 47 | module.exports = async function init(name, input) { 48 | const stackName = stackSafeName(name) 49 | const accountId = await getAccountId() 50 | log.info('Creating project...') 51 | const templatePath = await makeSamTemplate(stackName, accountId, input) 52 | const codePath = await makeLambdaFunction(name) 53 | log.success(`Created "${stackName}": ${codePath}, ${templatePath}`) 54 | } 55 | -------------------------------------------------------------------------------- /src/commands/package.js: -------------------------------------------------------------------------------- 1 | const { execSync } = require('child_process') 2 | const { basename, extname, dirname, join } = require('path') 3 | const yaml = require('js-yaml') 4 | const schema = require('cloudformation-schema-js-yaml') 5 | const deepmerge = require('deepmerge') 6 | const log = require('../log') 7 | const { findTemplatePath, spawnAsync, readFileAsync, writeFileAsync, deleteFileAsync } = require('../utils') 8 | 9 | // Older versions of aws cli don't support json for `aws cloudformation package` 10 | function checkCliVersion() { 11 | const output = execSync('aws cloudformation package help') 12 | if (!/--use-json/.test(output)) throw Error('Please upgrade aws cli to the latest version') 13 | } 14 | 15 | function parseTemplate(templateString, templateExt) { 16 | const useJson = templateExt === '.json' 17 | return useJson ? JSON.parse(templateString) : yaml.safeLoad(templateString, { schema }) 18 | } 19 | 20 | function serializeTemplate(templateJson, templateExt) { 21 | const useJson = templateExt === '.json' 22 | return useJson ? JSON.stringify(templateJson, null, 2) : yaml.safeDump(templateJson, { schema }) 23 | } 24 | 25 | function filePathWithSuffix(filePath, suffix) { 26 | const fileExt = extname(filePath) 27 | const fileWithoutExt = basename(filePath, fileExt) 28 | return join(dirname(filePath), fileWithoutExt + suffix + fileExt) 29 | } 30 | 31 | async function createS3Bucket(bucketName) { 32 | const command = `aws s3api head-bucket --bucket ${bucketName} &>/dev/null || aws s3 mb s3://${bucketName}` 33 | log.info('Creating s3 code bucket (if necessary)...').command(command) 34 | return spawnAsync(command) 35 | } 36 | 37 | async function mergeEnvTemplate(baseTemplatePath, baseTemplateJson, environment) { 38 | const templateExt = extname(baseTemplatePath) 39 | const environmentTemplatePath = filePathWithSuffix(baseTemplatePath, `-${environment}`) 40 | let enviromentTemplateString 41 | try { 42 | enviromentTemplateString = await readFileAsync(environmentTemplatePath, 'utf8') 43 | } catch (e) { 44 | return [] 45 | } 46 | log.info(`Merging ${environment} template (${environmentTemplatePath}) with base template (${baseTemplatePath})`) 47 | const enviromentTemplateJson = parseTemplate(enviromentTemplateString, templateExt) 48 | const mergedTemplateJson = deepmerge(baseTemplateJson, enviromentTemplateJson) 49 | const mergedTemplateString = serializeTemplate(mergedTemplateJson, templateExt) 50 | const mergedTemplatePath = filePathWithSuffix(baseTemplatePath, `-${environment}-merged`) 51 | await writeFileAsync(mergedTemplatePath, mergedTemplateString) 52 | return [mergedTemplatePath, mergedTemplateJson] 53 | } 54 | 55 | module.exports = async function packageProject(input) { 56 | const templatePath = findTemplatePath(input) 57 | const templateString = await readFileAsync(templatePath, 'utf8') 58 | const templateExt = extname(templatePath) 59 | const templateJson = parseTemplate(templateString, templateExt) 60 | const environment = input.environment || 'development' 61 | const [templatePathEnvMerged, templateJsonEnvMerged] = await mergeEnvTemplate(templatePath, templateJson, environment) 62 | const resolvedTemplatePath = templatePathEnvMerged || templatePath 63 | const resolvedTemplateJson = templateJsonEnvMerged || templateJson 64 | const templatePathPackaged = filePathWithSuffix(templatePath, '-packaged') 65 | const parameters = resolvedTemplateJson.Parameters 66 | const stackName = input['stack-name'] || `${parameters.stackName && parameters.stackName.Default}-${environment}` 67 | const bucketName = input['s3-bucket'] || (parameters.bucketName && parameters.bucketName.Default) 68 | const s3Prefix = 69 | input['s3-prefix'] || 70 | (parameters.s3Prefix && parameters.s3Prefix.Default) || 71 | `${stackName}/${new Date().getFullYear()}` 72 | const command = 73 | `aws cloudformation package ` + 74 | `--template-file ${resolvedTemplatePath} ` + 75 | `--output-template-file ${templatePathPackaged} ` + 76 | `--s3-bucket ${bucketName}` + 77 | `${s3Prefix ? ' --s3-prefix ' + s3Prefix : ''}` + 78 | `${templateExt === '.json' ? ' --use-json' : ''}` 79 | 80 | checkCliVersion() 81 | await createS3Bucket(bucketName) 82 | log.info('Packaging and uploading code...').command(command) 83 | await spawnAsync(command) 84 | log.success('Code packaged & uploaded') 85 | if (templatePathEnvMerged) deleteFileAsync(templatePathEnvMerged) 86 | return { templatePathPackaged, environment, stackName, bucketName } 87 | } 88 | -------------------------------------------------------------------------------- /src/commands/validate.js: -------------------------------------------------------------------------------- 1 | const { findTemplatePath, spawnAsync } = require('../utils') 2 | const log = require('../log') 3 | 4 | module.exports = async function validate(input) { 5 | const templatePath = findTemplatePath(input) 6 | const command = `aws cloudformation validate-template --template-body file://${templatePath}` 7 | log.info(`Validating template...`).command(command) 8 | await spawnAsync(command) 9 | log.success('Template valid') 10 | } 11 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | const sade = require('sade') 2 | const packageJson = require('../package') 3 | const init = require('./commands/init') 4 | const deploy = require('./commands/deploy') 5 | const validate = require('./commands/validate') 6 | const packageProject = require('./commands/package') 7 | const { error } = require('./log') 8 | 9 | process.on('unhandledRejection', (e) => { 10 | error(e.stack) // eslint-disable-line no-console 11 | process.exit(e.errno || 1) 12 | }) 13 | 14 | const cli = sade(packageJson.name) 15 | 16 | cli.version(packageJson.version) 17 | 18 | cli 19 | .command('init ') 20 | .describe('Initialize a project with a ') 21 | .option('-y, --yaml', 'Generate yaml for SAM template. Defaults to json, because javascript') 22 | .example('init my-app') 23 | .action(init) 24 | 25 | cli 26 | .command('deploy') 27 | .describe('Deploy a SAM project') 28 | .option('-t, --template', 'Path to a SAM template. Defaults to `sam.(json|yaml)` in the current directory') 29 | .option('-e, --environment', 'An environment name to deploy. Defaults to "development"') 30 | .option('-p, --parameters', 'A list of parameters to override in your template.') 31 | .option('-s, --stack-name', 'Option to override the auto-generated environment stack name') 32 | .option('--s3-bucket', 'S3 bucket where code is uploaded. Defaults to Parameters.bucketName in template') 33 | .option('--s3-prefix', 'S3 path prefix added to the packaged code file. Defaults to stackName/year') 34 | .option('--capabilities', 'See `aws cloudformation deploy`. Defaults to CAPABILITY_IAM') 35 | .example('deploy') 36 | .example('deploy --template ./configs/sam.json --environment production -p key1=val1 -p key2=val2') 37 | .action(deploy) 38 | 39 | // --------------------------------------------------------------------- 40 | // "Private" i.e. not promoting in README to keep the project focused. 41 | // Still discoverable via --help 42 | // --------------------------------------------------------------------- 43 | 44 | cli 45 | .command('validate') 46 | .describe('[private] Validate a SAM template') 47 | .option('-t, --template', 'Path to a SAM template. Defaults to `sam.(json|yaml)` in the current directory') 48 | .example('validate') 49 | .example('validate --template ./config/sam.json') 50 | .action(validate) 51 | 52 | cli 53 | .command('package') 54 | .describe('[private] Package & upload code') 55 | .option('-t, --template', 'Path to a SAM template. Defaults to `sam.(json|yaml)` in the current directory') 56 | .option('-e, --environment', 'An environment name to package. Defaults to "development"') 57 | .option('--s3-bucket', 'S3 bucket where code is uploaded. Defaults to Parameters.bucketName in template') 58 | .option('--s3-prefix', 'S3 path prefix added to the packaged code file. Defaults to stackName/year') 59 | .example('package') 60 | .example('package --template ./config/sam.json --environment production') 61 | .action(packageProject) 62 | 63 | module.exports = cli 64 | -------------------------------------------------------------------------------- /src/log.js: -------------------------------------------------------------------------------- 1 | const { cyan, green, yellow, red } = require('chalk') 2 | const prefix = '[sammie]' 3 | 4 | function info(...args) { 5 | console.info(cyan(prefix), ...args) // eslint-disable-line no-console 6 | return log 7 | } 8 | 9 | function error(...args) { 10 | console.error(red(args)) // eslint-disable-line no-console 11 | return log 12 | } 13 | 14 | function command(...args) { 15 | console.log(yellow(args)) // eslint-disable-line no-console 16 | return log 17 | } 18 | 19 | function success(...args) { 20 | console.info(green(prefix), ...args, green('✔︎')) // eslint-disable-line no-console 21 | return log 22 | } 23 | 24 | const log = { info, success, error, command } 25 | 26 | module.exports = log 27 | -------------------------------------------------------------------------------- /src/templates/lambda.js: -------------------------------------------------------------------------------- 1 | exports.handler = async (event, context) => { 2 | const body = ` 3 |

Hello __NAME__!

4 |
5 | Event 6 |
${JSON.stringify(event, null, 2)}
7 |
8 |
9 | Context 10 |
${JSON.stringify(context, null, 2)}
11 |
` 12 | 13 | return { 14 | statusCode: 200, 15 | headers: { 'content-type': 'text/html' }, 16 | body 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/templates/sam.json: -------------------------------------------------------------------------------- 1 | { 2 | "AWSTemplateFormatVersion": "2010-09-09", 3 | "Transform": "AWS::Serverless-2016-10-31", 4 | 5 | "Description": "__NAME__", 6 | "Parameters": { 7 | "stackName": { "Type": "String" }, 8 | "bucketName": { "Type": "String" }, 9 | "environment": { "Type": "String", "Default": "development" } 10 | }, 11 | 12 | "Resources": { 13 | "__NAME__Function": { 14 | "Type": "AWS::Serverless::Function", 15 | "Properties": { 16 | "FunctionName": { "Ref": "AWS::StackName" }, 17 | "CodeUri": "index.js", 18 | "Handler": "index.handler", 19 | "Runtime": "nodejs12.x", 20 | "MemorySize": 256, 21 | "Timeout": 10, 22 | "Events": { 23 | "HttpApiEvent": { 24 | "Type": "HttpApi", 25 | "Properties": { 26 | "PayloadFormatVersion": "2.0" 27 | } 28 | } 29 | } 30 | } 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/utils.js: -------------------------------------------------------------------------------- 1 | const { spawn } = require('child_process') 2 | const { relative } = require('path') 3 | const { existsSync, readFile, writeFile, unlink } = require('fs') 4 | const { promisify } = require('util') 5 | const log = require('./log') 6 | 7 | async function spawnAsync(command) { 8 | const child = spawn(command, { shell: true }) 9 | return new Promise((resolve, reject) => { 10 | let data = '' 11 | child.stdout.on('data', (chunk) => (data += chunk)) 12 | child.stderr.on('data', (data) => log.error(data.toString())) 13 | child.on('error', reject) 14 | child.on('exit', (code) => { 15 | let response 16 | try { 17 | response = JSON.parse(data) 18 | } catch (e) { 19 | response = data 20 | } 21 | code === 0 ? resolve(response) : reject(Error(code)) 22 | }) 23 | }) 24 | } 25 | 26 | function findTemplatePath(input) { 27 | if (input.template) return input.template 28 | const templatePath = ['sam.json', 'sam.yaml'] 29 | .map((name) => relative(process.cwd(), name)) 30 | .find((path) => existsSync(path)) 31 | if (templatePath) return templatePath 32 | throw Error('Template not found') 33 | } 34 | 35 | module.exports = { 36 | spawnAsync, 37 | findTemplatePath, 38 | readFileAsync: promisify(readFile), 39 | writeFileAsync: promisify(writeFile), 40 | deleteFileAsync: promisify(unlink) 41 | } 42 | -------------------------------------------------------------------------------- /test/index.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert') 2 | const sammie = require('../src/index') 3 | 4 | process.on('unhandledRejection', (e) => { 5 | throw e 6 | }) 7 | 8 | describe('sammie', () => { 9 | it('exists', () => { 10 | assert.ok(sammie) 11 | }) 12 | }) 13 | --------------------------------------------------------------------------------