├── .circleci └── config.yml ├── .devcontainer ├── Dockerfile └── devcontainer.json ├── .eslintrc.json ├── .github └── workflows │ └── codeql-analysis.yml ├── .gitignore ├── .prettierrc ├── .tool-versions ├── .travis.yml ├── CHANGELOG.md ├── LICENSE ├── LICENSE.LESSER ├── README.md ├── bin └── core ├── lib ├── cli │ ├── compile-command.js │ └── execute-command.js ├── compile │ ├── index.js │ ├── transform.js │ └── transforms.js ├── execute.js ├── index.js ├── sandbox │ └── index.js └── utils.js ├── package-lock.json ├── package.json └── test ├── compile └── index.test.js ├── execute.test.js ├── index.js ├── security.test.js └── utils.test.js /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | orbs: 2 | node: circleci/node@2.0.2 3 | 4 | version: 2.1 5 | 6 | workflows: 7 | matrix-tests: 8 | jobs: 9 | - node/test: 10 | version: "14.16" 11 | - node/test: 12 | version: "18.10" 13 | -------------------------------------------------------------------------------- /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | # See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.191.0/containers/javascript-node/.devcontainer/base.Dockerfile 2 | 3 | # [Choice] Node.js version: 16, 14, 12 4 | ARG VARIANT="14-buster" 5 | FROM --platform=linux/amd64 mcr.microsoft.com/vscode/devcontainers/javascript-node:0-${VARIANT} 6 | 7 | # [Optional] Uncomment this section to install additional OS packages. 8 | # RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ 9 | # && apt-get -y install --no-install-recommends 10 | 11 | # [Optional] Uncomment if you want to install an additional version of node using nvm 12 | # ARG EXTRA_NODE_VERSION=10 13 | # RUN su node -c "source /usr/local/share/nvm/nvm.sh && nvm install ${EXTRA_NODE_VERSION}" 14 | 15 | # [Optional] Uncomment if you want to install more global node modules 16 | RUN su node -c "npm install -g @openfn/devtools @openfn/core eslint prettier" -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | // For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: 2 | // https://github.com/microsoft/vscode-dev-containers/tree/v0.191.0/containers/javascript-node 3 | { 4 | "name": "Node.js", 5 | "build": { 6 | "dockerfile": "Dockerfile", 7 | // Update 'VARIANT' to pick a Node version: 12, 14, 16 8 | "args": { "VARIANT": "18" } 9 | }, 10 | 11 | "containerEnv": { 12 | "GH_TOKEN": "${localEnv:GH_TOKEN}", 13 | }, 14 | 15 | "mounts": [ 16 | "source=${localEnv:HOME}${localEnv:USERPROFILE}/.npmrc,target=/home/node/.npmrc,type=bind,consistency=cached" 17 | ], 18 | 19 | // Set *default* container specific settings.json values on container create. 20 | "settings": {}, 21 | 22 | // Add the IDs of extensions you want installed when the container is created. 23 | "extensions": ["dbaeumer.vscode-eslint", "esbenp.prettier-vscode"], 24 | 25 | // Use 'forwardPorts' to make a list of ports inside the container available locally. 26 | // "forwardPorts": [], 27 | 28 | // Use 'postCreateCommand' to run commands after the container is created. 29 | // "postCreateCommand": "echo \"hello world\"", 30 | 31 | // Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. 32 | "remoteUser": "node" 33 | } 34 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "es6": true, 4 | "node": true 5 | }, 6 | "extends": "eslint:recommended", 7 | "rules": { 8 | "linebreak-style": [ 9 | "error", 10 | "unix" 11 | ], 12 | "semi": [ 13 | "error", 14 | "always" 15 | ] 16 | } 17 | } -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL" 13 | 14 | on: 15 | push: 16 | branches: [ main ] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: [ main ] 20 | schedule: 21 | - cron: '43 4 * * 5' 22 | 23 | jobs: 24 | analyze: 25 | name: Analyze 26 | runs-on: ubuntu-latest 27 | permissions: 28 | actions: read 29 | contents: read 30 | security-events: write 31 | 32 | strategy: 33 | fail-fast: false 34 | matrix: 35 | language: [ 'javascript' ] 36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] 37 | # Learn more about CodeQL language support at https://git.io/codeql-language-support 38 | 39 | steps: 40 | - name: Checkout repository 41 | uses: actions/checkout@v2 42 | 43 | # Initializes the CodeQL tools for scanning. 44 | - name: Initialize CodeQL 45 | uses: github/codeql-action/init@v1 46 | with: 47 | languages: ${{ matrix.language }} 48 | # If you wish to specify custom queries, you can do so here or in a config file. 49 | # By default, queries listed here will override any specified in a config file. 50 | # Prefix the list here with "+" to use these queries and those in the config file. 51 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 52 | 53 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 54 | # If this step fails, then you should remove it and run the build manually (see below) 55 | - name: Autobuild 56 | uses: github/codeql-action/autobuild@v1 57 | 58 | # ℹ️ Command-line programs to run using the OS shell. 59 | # 📚 https://git.io/JvXDl 60 | 61 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 62 | # and modify them (or add more) to build your code if your project 63 | # uses a compiled language 64 | 65 | #- run: | 66 | # make bootstrap 67 | # make release 68 | 69 | - name: Perform CodeQL Analysis 70 | uses: github/codeql-action/analyze@v1 71 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | /tmp 3 | *.sw[mnop] 4 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "arrowParens": "avoid", 3 | "singleQuote": true 4 | } 5 | -------------------------------------------------------------------------------- /.tool-versions: -------------------------------------------------------------------------------- 1 | nodejs 18.12.1 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 12 4 | - 14 5 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | 0.4.2 2 | ===== 3 | 4 | Added ENV variable `STATE_PATH` to compiled script, allowing the final state 5 | to be written to disk on success. 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | 635 | Copyright (C) 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | Copyright (C) 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | -------------------------------------------------------------------------------- /LICENSE.LESSER: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OpenFn/Core [![CircleCI](https://circleci.com/gh/OpenFn/core.svg?style=svg)](https://circleci.com/gh/OpenFn/core) ![npm](https://img.shields.io/npm/dt/@openfn/core) 2 | 3 | Core is the central job processing program used in the OpenFn platform. It 4 | creates an isolated Node VM, passes in `state` and an `expression`, then runs 5 | the expression in this limited access Node VM. 6 | 7 | ## Getting Started 8 | 9 | It's recommended to start by getting [openfn-devTools](https://github.com/OpenFn/openfn-devtools) 10 | setup for a quick development environment on your machine. 11 | 12 | After that you can use `core execute` to run your jobs. 13 | 14 | **Install via NPM** 15 | 16 | ```sh 17 | npm install @openfn/core 18 | core 19 | ``` 20 | 21 | **Via git** 22 | 23 | ```sh 24 | git clone git@github.com:OpenFn/core.git 25 | cd core 26 | ./bin/core 27 | ``` 28 | 29 | ### Execute 30 | 31 | Used to convert an expression into an executable script. 32 | 33 | **Options**: 34 | 35 | ``` 36 | -l, --language resolvable language/adaptor path [required] 37 | -e, --expression target expression to execute [required] 38 | -s, --state Path to initial state file. [required] 39 | -o, --output Path to write result from expression 40 | -t, --test Intercepts and logs all HTTP requests to console 41 | ``` 42 | 43 | **Examples** 44 | 45 | Use a module in the parent folder, and pick out the `Adaptor` member. 46 | 47 | ``` 48 | core execute -l ../language-http.Adaptor -e exp.js -s state.json 49 | ``` 50 | 51 | Use a npm installed module, and pick out the `Adaptor` member. 52 | 53 | ``` 54 | core execute -l language-http.Adaptor -e exp.js -s state.json 55 | ``` 56 | 57 | ## Using Programmatically 58 | 59 | When creating your own runtimes, it makes more sense to call the execution 60 | code directly in NodeJS instead of via the command line. 61 | 62 | ```js 63 | const { 64 | Compile, 65 | Execute, 66 | transforms: { defaultTransforms, verify }, 67 | sandbox: { buildSandbox, VMGlobals }, 68 | } = require('./lib'); 69 | 70 | const { 71 | modulePath, 72 | getModule, 73 | readFile, 74 | writeJSON, 75 | formatCompileError, 76 | } = require('./lib/utils'); 77 | 78 | (async function () { 79 | const state = JSON.parse(await readFile('./test/fixtures/addState.json')); 80 | const code = await readFile('./test/fixtures/addExpression.js.expression'); 81 | const Adaptor = getModule(modulePath('../language-common')); 82 | 83 | // Setup our initial global object, adding language packs and any other 84 | // objects we want on our root. 85 | const sandbox = buildSandbox({ 86 | noConsole: false, 87 | testMode: false, 88 | extensions: [Adaptor], 89 | }); 90 | 91 | // Apply some transformations to the code (including a verify step) to 92 | // check all function calls are valid. 93 | const compile = new Compile(code, [ 94 | ...defaultTransforms, 95 | verify({ sandbox: { ...sandbox, ...VMGlobals } }), 96 | ]); 97 | 98 | if (compile.errors.length > 0) { 99 | throw new Error( 100 | compile.errors.map(err => formatCompileError(code, err)).join('\n') 101 | ); 102 | } 103 | 104 | try { 105 | // Run the expression and get the resulting state 106 | const finalState = await Execute({ 107 | expression: compile.toString(), 108 | state, 109 | sandbox, 110 | }); 111 | 112 | writeJSON('/tmp/output.json', finalState); 113 | } catch (err) { 114 | console.error(err); 115 | } 116 | })(); 117 | ``` 118 | 119 | > **NOTE** 120 | > We add VMGlobals to the `verify` transform, and not into 121 | > the sandbox that `Execute` uses, as VM2 provides it's own proxied copies 122 | > of these functions for each invocation - but we still need the validation 123 | > step to be aware that these generic functions are available 124 | 125 | ## Debugging 126 | 127 | Note that only certain parts of Node are whitelisted for use in Core. 128 | These are the [globals exposed by VM2](https://github.com/patriksimek/vm2/blob/a63bef73e7239f9d14e48280b3c6f6763a5145d5/lib/main.js#L240-L265) 129 | and the `extensions` we add for each run: 130 | 131 | ```js 132 | const extensions = Object.assign( 133 | { 134 | console: argv.noConsole ? disabledConsole : console, // --nc or --noConsole 135 | testMode: argv.test, // --t or --test 136 | setTimeout, // We allow as Erlang will handle killing long-running VMs. 137 | }, 138 | Adaptor 139 | ); 140 | ``` 141 | 142 | This means that you'll have access to whatever is exposed by the 143 | language-package (aka `Adaptor`), `console` (unless blocked by a project 144 | administrator for OpenFn Platform projects), and `setTimeout`. The `testMode` 145 | property is used to intercept HTTP requests for offline testing. 146 | 147 | ## Writing language-packages 148 | 149 | ### Canonical sync "operation" or "helper function" for a language-pacakge 150 | 151 | ```js 152 | export function sample(arg1, arg2) { 153 | return state => { 154 | state.output = arg1 + arg2; 155 | return state; 156 | }; 157 | } 158 | ``` 159 | 160 | ### Canonical async "operation" or "helper function" for a language-pacakge 161 | 162 | ```js 163 | export function sample(arg1, arg2) { 164 | return state => { 165 | return new Promise((resolve, reject) => { 166 | try { 167 | state.output = arg1 + arg2; 168 | resolve(state); 169 | } catch (error) { 170 | reject(error); 171 | } 172 | }); 173 | }; 174 | } 175 | ``` 176 | 177 | ## Internal notes on how execute works 178 | 179 | ```js 180 | (function(state) { 181 | execute( 182 | alterState(() => {}), 183 | alterState((state) => {}), // function(state) { } 184 | alterState(() => {}) 185 | )(state); 186 | })(state) 187 | 188 | [ 189 | (alterState(() => {}), alterState(() => {}), alterState(() => {})) 190 | ].reduce((acc, v) => { 191 | return v(state).then(acc) 192 | }, new Promise); 193 | 194 | 195 | f(state).then((state) => return state).then() 196 | ``` 197 | -------------------------------------------------------------------------------- /bin/core: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const yargs = require('yargs/yargs'); 4 | const { hideBin } = require('yargs/helpers'); 5 | 6 | yargs(hideBin(process.argv)) 7 | .command(require('../lib/cli/compile-command')) 8 | .command(require('../lib/cli/execute-command')) 9 | .demandCommand(1, 'must provide a command') 10 | .help('h') 11 | .alias('h', 'help') 12 | .epilog('OpenFn 2021').argv; -------------------------------------------------------------------------------- /lib/cli/compile-command.js: -------------------------------------------------------------------------------- 1 | const { 2 | Compile, 3 | transforms: { defaultTransforms, verify }, 4 | sandbox: { buildSandbox, VMGlobals }, 5 | } = require('..'); 6 | 7 | const { 8 | safeResolve, 9 | readFile, 10 | formatCompileError, 11 | } = require('../utils'); 12 | 13 | function handler(argv) { 14 | try { 15 | const adaptorPath = 16 | safeResolve(argv.language) || 17 | safeResolve(argv.language, { paths: ['.'] }); 18 | 19 | if (!adaptorPath) { 20 | throw new Error(`Cannot find module '${argv.language}'.`); 21 | } 22 | 23 | const adaptor = require(adaptorPath); 24 | 25 | const sandbox = buildSandbox({ 26 | noConsole: argv.noConsole, 27 | testMode: argv.test, 28 | extensions: [adaptor.Adaptor || adaptor], 29 | }); 30 | 31 | readFile(argv.expression) 32 | .then(code => { 33 | const compile = new Compile(code, [ 34 | ...defaultTransforms, 35 | verify({ sandbox: { ...sandbox, ...VMGlobals } }), 36 | ]); 37 | 38 | if (compile.errors.length > 0) { 39 | console.error( 40 | compile.errors.map(err => formatCompileError(code, err)).join('\n') 41 | ); 42 | 43 | return Promise.reject(new Error('Compilation failed.')); 44 | } 45 | 46 | return compile.toString(); 47 | }) 48 | .then(code => { 49 | console.log(code); 50 | }) 51 | .catch(e => { 52 | console.error(e.message); 53 | process.exitCode = 10; 54 | }); 55 | } catch (e) { 56 | console.log(e); 57 | process.exitCode = 1; 58 | } 59 | } 60 | exports.command = 'compile'; 61 | 62 | exports.describe = 'compile an expression'; 63 | 64 | exports.builder = function (yargs) { 65 | return yargs 66 | .option('l', { 67 | alias: 'language', 68 | description: 'language/adaptor', 69 | }) 70 | .demand('language') 71 | 72 | .option('e', { 73 | alias: 'expression', 74 | description: 'target file to compile', 75 | }) 76 | .demand('expression') 77 | 78 | .option('o', { 79 | alias: 'output', 80 | description: 'send output to a file', 81 | }) 82 | 83 | .option('d', { 84 | alias: 'debug', 85 | description: 'debug', 86 | }) 87 | 88 | .example( 89 | '$0 compile -l salesforce -e foo.js', 90 | 'Using the salesforce language pack, compile foo.js to STDOUT' 91 | ) 92 | .example( 93 | '$0 compile -l salesforce -e foo.js -o output.js', 94 | 'Using the salesforce language pack, compile foo.js to output.js' 95 | ) 96 | 97 | .help('help'); 98 | }; 99 | 100 | exports.handler = handler; 101 | -------------------------------------------------------------------------------- /lib/cli/execute-command.js: -------------------------------------------------------------------------------- 1 | const { 2 | Compile, 3 | Execute, 4 | transforms: { defaultTransforms, verify }, 5 | sandbox: { buildSandbox, VMGlobals }, 6 | } = require('..'); 7 | 8 | const { 9 | safeResolve, 10 | readFile, 11 | writeJSON, 12 | formatCompileError, 13 | interceptRequests, 14 | getModuleDetails, 15 | addDebugLogs, 16 | } = require('../utils'); 17 | 18 | function handler(argv) { 19 | try { 20 | if (argv.test) { 21 | interceptRequests(); 22 | } 23 | 24 | const moduleDetails = getModuleDetails(argv.language); 25 | 26 | addDebugLogs(moduleDetails); 27 | 28 | // We try and resolve the location of the module entry point by first trying 29 | // with the default lookups/NODE_PATH env var, then fall back to looking in 30 | // local directory. 31 | // This is to allow loading language packs from both a node_modules folder 32 | // or relative paths. Working around that a relative path is considered 33 | // from _this_ file - and not from the cwd where the path was given. 34 | const adaptorPath = 35 | safeResolve(argv.language) || 36 | safeResolve(argv.language, { paths: ['.', process.cwd()] }); 37 | 38 | if (!adaptorPath) { 39 | throw new Error(`Cannot find module '${argv.language}'.`); 40 | } 41 | 42 | const adaptor = require(adaptorPath); 43 | 44 | const sandbox = buildSandbox({ 45 | noConsole: argv.noConsole, 46 | testMode: argv.test, 47 | extensions: [adaptor.Adaptor || adaptor], 48 | }); 49 | 50 | Promise.all([ 51 | readFile(argv.state).then(JSON.parse), 52 | readFile(argv.expression).then(code => { 53 | const compile = new Compile(code, [ 54 | ...defaultTransforms, 55 | verify({ sandbox: { ...sandbox, ...VMGlobals } }), 56 | ]); 57 | 58 | if (compile.errors.length > 0) { 59 | console.error( 60 | compile.errors.map(err => formatCompileError(code, err)).join('\n') 61 | ); 62 | 63 | return Promise.reject(new Error('Compilation failed.')); 64 | } 65 | 66 | return compile.toString(); 67 | }), 68 | ]) 69 | .then(([state, expression]) => { 70 | // Break comment if you want to see the expression prior to execution. 71 | // console.log(expression); 72 | return Execute({ expression, state, sandbox }) 73 | .then(state => { 74 | // TODO: stat path and check is writable before running expression 75 | if (argv.output) { 76 | if (['object', 'string', 'number'].includes(typeof state)) { 77 | return writeJSON(argv.output, state); 78 | } else { 79 | throw new Error( 80 | `Could not write state to file, type must be serializable. Got '${typeof state}'` 81 | ); 82 | } 83 | } 84 | return state; 85 | }) 86 | .then(state => { 87 | console.log('Finished.'); 88 | process.exitCode = 0; 89 | }) 90 | .catch(err => { 91 | process.exitCode = 1; 92 | return Promise.reject(err); 93 | }); 94 | }) 95 | .catch(err => { 96 | // Outer catch, for compilation. 97 | // TODO: check Error type and respond with appropriate error code 98 | console.error(err); 99 | process.exitCode = 1; 100 | }); 101 | } catch (e) { 102 | console.error(e); 103 | process.exitCode = 10; 104 | } 105 | } 106 | 107 | exports.command = 'execute'; 108 | 109 | exports.describe = 'run an expression'; 110 | 111 | exports.builder = function (yargs) { 112 | return yargs 113 | .option('l', { 114 | alias: 'language', 115 | description: 'resolvable language/adaptor path', 116 | }) 117 | .demand('language') 118 | 119 | .option('e', { 120 | alias: 'expression', 121 | description: 'target expression to execute', 122 | }) 123 | .demand('expression') 124 | 125 | .option('s', { 126 | alias: 'state', 127 | description: 'Path to initial state file.', 128 | }) 129 | .demand('state') 130 | 131 | .option('o', { 132 | alias: 'output', 133 | description: 'Path to write output.', 134 | }) 135 | 136 | .option('t', { 137 | alias: 'test', 138 | description: 'test mode, no HTTP requests', 139 | }) 140 | 141 | .option('nc', { 142 | alias: 'noConsole', 143 | description: 'if set to true, removes console.log for security', 144 | }) 145 | 146 | .example( 147 | '$0 execute -l salesforce -e foo.js -s state.json', 148 | 'Using the salesforce language pack, execute foo.js to STDOUT' 149 | ) 150 | 151 | .help('help'); 152 | }; 153 | 154 | exports.handler = handler; 155 | -------------------------------------------------------------------------------- /lib/compile/index.js: -------------------------------------------------------------------------------- 1 | const recast = require('recast'); 2 | 3 | class Compile { 4 | constructor(ast, transforms = []) { 5 | if (typeof ast === 'string') { 6 | ast = recast.parse(ast.replace(/\ $/, ''), { 7 | tolerant: true, 8 | range: true, 9 | parser: { 10 | parse(source) { 11 | return require('acorn').parse(source, { 12 | sourceType: 'script', 13 | ecmaVersion: 10, 14 | allowHashBang: true, 15 | locations: true, 16 | }); 17 | }, 18 | }, 19 | }); 20 | // Recast with Acorn doesn't have an initial errors array. 21 | if (!ast.program.errors) { 22 | ast.program.errors = []; 23 | } 24 | } 25 | 26 | this.ast = transforms.reduce((ast, transform) => { 27 | const next = transform(ast); 28 | 29 | if (!next) { 30 | throw new Error(`A transform unexpectedly returned ${next}`); 31 | } 32 | 33 | return next; 34 | }, ast); 35 | 36 | Object.defineProperty(this, 'errors', { 37 | get: function () { 38 | return this.ast.program.errors; 39 | }, 40 | }); 41 | } 42 | 43 | toString() { 44 | return recast.print(this.ast).code; 45 | } 46 | } 47 | 48 | module.exports = Compile; 49 | -------------------------------------------------------------------------------- /lib/compile/transform.js: -------------------------------------------------------------------------------- 1 | const recast = require('recast'), 2 | estemplate = require('estemplate'), 3 | fs = require('fs'); 4 | 5 | const types = require("ast-types"); 6 | const { namedTypes: n, builders: b } = types; 7 | 8 | const { createTree } = require('@openfn/doclet-query'); 9 | 10 | function toString(ast) { 11 | return recast.print(ast).code; 12 | } 13 | 14 | /** 15 | * Retrieves a given modules exports given a module config 16 | * 17 | * @function 18 | * @param {Object} moduleConfig 19 | * @param {string} moduleConfig.packageName 20 | * @param {string} moduleConfig.memberProperty 21 | * @param {object} doclets - list of JSDoc tags for module 22 | */ 23 | function getModuleExports({ packageName, memberProperty }, doclets) { 24 | if (!memberProperty) 25 | throw new Error( 26 | `Inspecting JSDoc data for non-namespaced modules not supported. 27 | Use . format.`) 28 | 29 | try { 30 | return createTree(doclets)[packageName].modules[memberProperty].exports 31 | } catch (e) { 32 | throw new Error( 33 | `Error locating exported members of ${packageName}.${memberProperty} 34 | Please check the JSDoc data that was provided.`) 35 | } 36 | } 37 | 38 | /** 39 | * Splits a language pack path into package and member parts 40 | * 41 | * @function 42 | * @param {string} languagePack - package/module 43 | */ 44 | function getModuleConfig(languagePack) { 45 | // We currently ignore namespaces deeper than 1. i.e. foo.bar 46 | const [ packageName, memberProperty ] = languagePack.split(".") 47 | return ({ packageName, memberProperty }) 48 | } 49 | 50 | /** 51 | * Analyses and generates an executable program based on a given language pack. 52 | * 53 | * @function 54 | * @param {object|string} ast - Code to transform 55 | * @param {Object} options 56 | * @param {string} options.languagePack - relative package/module name 57 | * @param {object} options.doclets - list of JSDoc tags for languagePack 58 | */ 59 | function transform(ast, { languagePack, doclets }) { 60 | 61 | let moduleConfig = getModuleConfig(languagePack); 62 | const adaptorExports = getModuleExports(moduleConfig, doclets) 63 | 64 | try { 65 | // Check if the language pack specified exists 66 | // TODO: referencing call expressions not available in the languagePack 67 | // should register errors on the AST. 68 | require.resolve(moduleConfig.packageName) 69 | } catch (e) { 70 | console.warn(`Warning: ${languagePack} could not be resolved.`) 71 | } 72 | 73 | if (typeof ast === 'string') 74 | ast = recast.parse(ast, { 75 | parser: { 76 | parse(source) { 77 | return require('acorn').parse(source, { 78 | sourceType: 'script', 79 | ecmaVersion: 10, 80 | allowHashBang: true, 81 | locations: true, 82 | }); 83 | }, 84 | }, 85 | }) 86 | 87 | // Recast with Acorn doesn't have an initial errors array. 88 | // if (!ast.program.errors) { 89 | // ast.program.errors = []; 90 | // } 91 | 92 | // Inject all the exported members of the module into the top of the AST. 93 | // This is used to infer existence of a call expression for the language pack 94 | // using the `scope.lookup` facility. 95 | ast.program.body.unshift(estemplate( 96 | `const <%= members %> = AdaptorStub;`, 97 | { 98 | members: b.objectPattern( 99 | Object.keys(adaptorExports) 100 | .map(b.identifier) 101 | .map(id => b.property("init", id, id)) 102 | ) 103 | }).body[0]) 104 | 105 | // ======================================================================= 106 | // Language Call Expressions 107 | // ======================================================================= 108 | // 109 | // We traverse the AST and collect the call expressions that *look* like 110 | // they belong to our language. 111 | // 112 | // * CallExpression - `operation(...args)` 113 | // * MemberExpression - `namespace.operation(...args)` 114 | // 115 | // TODO: Provide a more comprehensive understanding of Language Call Expressions 116 | // We currently do not reflect the identifiers against our language pack. 117 | // What this means is that we can't tell the difference between: 118 | // `foo.split(" ")` and `beta.each(...)` 119 | // This limits users freedom when using anonymous functions as arguments. 120 | 121 | ast.callExpressions = []; 122 | 123 | console.log("Analysing expression"); 124 | // get static analysis of expression 125 | 126 | types.visit(ast, { 127 | // This method will be called for any node with .type "CallExpression": 128 | visitCallExpression: function(path) { 129 | var node = path.node; 130 | 131 | // If a callExpression's callee is also a callExpression 132 | // then we can assume state is being injected. 133 | // i.e. operation(...args)(state) 134 | if ( n.Identifier.check(node.callee) ) { 135 | // We only track callees with identity. 136 | // So skip over over outer callExpressions. 137 | if (path.scope.lookup(node.callee.name)) { 138 | ast.callExpressions.push(node); 139 | } 140 | } 141 | 142 | if ( n.MemberExpression.check(node.callee) && n.Identifier.check(node.callee.object) ) { 143 | if (path.scope.lookup(node.callee.object.name)) { 144 | ast.callExpressions.push(node); 145 | } 146 | } 147 | 148 | this.traverse(path); 149 | } 150 | }); 151 | 152 | 153 | // Unique Expressions 154 | let languageCallExpressions = ast.callExpressions 155 | .map(c => { 156 | switch (c.callee.type) { 157 | // operation(...args) 158 | case 'Identifier': 159 | return c.callee.name 160 | 161 | // namespace.operation(...args) 162 | case 'MemberExpression': 163 | if (n.Identifier.check(c.callee.object)) { 164 | return c.callee.object.name 165 | } 166 | 167 | default: 168 | throw new TypeError(`Invalid language pack call expression: \n ${recast.print(c).code}`) 169 | 170 | } 171 | }) 172 | .filter(( value,index,self ) => self.indexOf(value) === index) 173 | 174 | 175 | console.info(`Found ${ast.callExpressions.length} call expressions.`); 176 | console.info(`This expression uses the following calls:\n ${languageCallExpressions.join(', ')}`) 177 | 178 | // ======================================================================= 179 | // Execute Wrapper 180 | // ======================================================================= 181 | 182 | ast.rootExpressions = [] 183 | 184 | types.visit(ast, { 185 | visitCallExpression: function(path) { 186 | var node = path.node; 187 | 188 | ast.rootExpressions.push(node); 189 | 190 | return false; 191 | } 192 | }); 193 | 194 | console.info(`Found ${ast.rootExpressions.length} root call expressions.`); 195 | console.info("Wrapping root call expressions in `execute` call."); 196 | 197 | console.info("Adding `execute` to language pack dependency list.") 198 | 199 | languageCallExpressions.push('execute') 200 | 201 | ast.program.body = [ 202 | b.expressionStatement( 203 | b.callExpression( b.identifier('execute'), ast.rootExpressions ) 204 | ) 205 | ] 206 | 207 | // ======================================================================= 208 | // Dependency Injector 209 | // ======================================================================= 210 | 211 | console.info("Injecting language pack dependencies.") 212 | let expression = ast.program.body[0].expression 213 | 214 | let injectedCallExpression = b.callExpression( 215 | b.functionExpression( 216 | null, 217 | languageCallExpressions.sort().map(b.identifier), 218 | b.blockStatement([ 219 | b.returnStatement( expression ) 220 | ]) 221 | ), 222 | languageCallExpressions.sort().map(name => { 223 | return b.memberExpression(b.identifier('languagePack'), b.identifier(name)) 224 | }) 225 | 226 | ) 227 | 228 | // ======================================================================= 229 | // Main Function 230 | // ======================================================================= 231 | 232 | let executeChain = estemplate( 233 | ` 234 | function main(initialState) { 235 | var expression = <%= expressionStatement %>; 236 | 237 | expression(initialState) 238 | .then(function(state) { 239 | if (finalStatePath) { 240 | require('fs') 241 | .writeFileSync(finalStatePath, JSON.stringify(state, null, 2), 'utf8'); 242 | } 243 | return state; 244 | }) 245 | .catch(function(e) { 246 | console.error(e) 247 | process.exitCode = 1 248 | }); 249 | 250 | } 251 | `, { 252 | expressionStatement: injectedCallExpression 253 | }).body; 254 | 255 | 256 | // ======================================================================= 257 | // CommonJS Requires 258 | // ======================================================================= 259 | 260 | let moduleReferences = languagePack.split('.') 261 | let moduleRequires 262 | 263 | if (moduleReferences.length > 1) { 264 | moduleRequires = estemplate( 265 | ` 266 | var finalStatePath = process.env.STATE_PATH; 267 | var languagePack = require(<%= moduleName %>)[<%= memberProperty %>] 268 | `, 269 | { 270 | moduleName: b.literal(moduleReferences[0]), 271 | memberProperty: b.literal(moduleReferences[1]) 272 | } 273 | ).body 274 | } else { 275 | moduleRequires = estemplate( 276 | ` 277 | var finalStatePath = process.env.STATE_PATH; 278 | var languagePack = require(<%= moduleName %>) 279 | `, 280 | { moduleName: b.literal(moduleReferences[0]) } 281 | ).body 282 | } 283 | 284 | // ======================================================================= 285 | // Get initial state from STDIN 286 | // ======================================================================= 287 | 288 | let getInitialState = estemplate( 289 | ` 290 | var stdin = process.stdin, 291 | stdout = process.stdout, 292 | data = ''; 293 | 294 | stdin.setEncoding('binary'); 295 | 296 | stdin.on('readable', function () { 297 | var chunk = stdin.read(); 298 | if (chunk === null) { 299 | stdin.end(); 300 | } else { 301 | data += chunk; 302 | } 303 | 304 | }); 305 | 306 | stdin.on('end', function () { 307 | 308 | if (data == '') { 309 | throw new TypeError('No data provided.') 310 | } 311 | 312 | var initialState = JSON.parse(data) || null 313 | main(initialState) 314 | 315 | }); 316 | `, {} 317 | ).body 318 | 319 | 320 | ast.program.body = [ ...moduleRequires, ...getInitialState, ...executeChain ]; 321 | 322 | return ast 323 | 324 | } 325 | 326 | module.exports = { 327 | transform, 328 | toString 329 | }; 330 | -------------------------------------------------------------------------------- /lib/compile/transforms.js: -------------------------------------------------------------------------------- 1 | const types = require('ast-types'); 2 | const estemplate = require('estemplate'); 3 | const { namedTypes: n, builders: b } = types; 4 | 5 | // column : 26 6 | // description : "Strict mode code may not include a with statement" 7 | // index : 171 8 | // lineNumber : 14 9 | 10 | function CompilationError({ node, description }) { 11 | this.node = node; 12 | this.name = 'CompilationError'; 13 | this.message = description; 14 | } 15 | CompilationError.prototype = Object.create(Error.prototype); 16 | CompilationError.prototype.constructor = CompilationError; 17 | 18 | // Using a sandbox, verify injects that into the top of the AST. 19 | // This enables it to do checks for call expressions, this allows a fair 20 | // degree of certainty the expression will be able to run. 21 | // 22 | // For example: `foo(); bar()`, with a sandbox of { foo: ..., bar: ... } 23 | // will be successful, however if the sandbox does not contain any number of 24 | // functions these will be added to the errors list. 25 | function verify(opts) { 26 | if (!opts.sandbox) { 27 | throw new Error('verify requires a `sandbox` option.'); 28 | } 29 | return ast => { 30 | // Inject all the exported members of the module into the top of the AST. 31 | // This is used to infer existence of a call expression for the language pack 32 | // using the `scope.lookup` facility. 33 | ast.program.body.unshift( 34 | estemplate(`const <%= members %> = AdaptorStub;`, { 35 | members: b.objectPattern( 36 | Object.keys(opts.sandbox) 37 | .map(b.identifier) 38 | .map(id => b.property('init', id, id)) 39 | ), 40 | }).body[0] 41 | ); 42 | 43 | types.visit(ast, { 44 | // This method will be called for any node with .type "CallExpression": 45 | visitCallExpression: function (path) { 46 | var node = path.node; 47 | 48 | // If a callExpression's callee is also a callExpression 49 | // then we can assume state is being injected. 50 | // i.e. operation(...args)(state) 51 | if (n.Identifier.check(node.callee)) { 52 | // We only track callees with identity. 53 | // So skip over over outer callExpressions. 54 | 55 | if (path.scope.lookup(node.callee.name)) { 56 | // ast.callExpressions.push(node); 57 | } else { 58 | ast.program.errors.push( 59 | new CompilationError({ 60 | node, 61 | description: 'Function not available.', 62 | }) 63 | ); 64 | } 65 | } 66 | 67 | if ( 68 | n.MemberExpression.check(node.callee) && 69 | n.Identifier.check(node.callee.object) 70 | ) { 71 | if (path.scope.lookup(node.callee.object.name)) { 72 | // ast.callExpressions.push(node); 73 | } else { 74 | ast.program.errors.push( 75 | new CompilationError({ 76 | node, 77 | description: 'Function not available.', 78 | }) 79 | ); 80 | } 81 | } 82 | 83 | this.traverse(path); 84 | }, 85 | }); 86 | 87 | // Remove the sandbox injection. 88 | ast.program.body.shift(); 89 | 90 | return ast; 91 | }; 92 | } 93 | 94 | // Takes all the callExpressions found on the root, and wraps them in another 95 | // call expression with a given name: 96 | // 97 | // Example: 98 | // `foo(); bar();` => wrapRootExpressions('execute') => `execute(foo(), bar())` 99 | function wrapRootExpressions(ident) { 100 | return ast => { 101 | ast.rootExpressions = []; 102 | 103 | types.visit(ast, { 104 | visitCallExpression: function (path) { 105 | var node = path.node; 106 | 107 | ast.rootExpressions.push(node); 108 | 109 | return false; 110 | }, 111 | }); 112 | 113 | ast.program.body = [ 114 | b.expressionStatement( 115 | b.callExpression(b.identifier(ident), ast.rootExpressions) 116 | ), 117 | ]; 118 | 119 | return ast; 120 | }; 121 | } 122 | 123 | // Given a call expression identifier name, and an external identifier name 124 | // it wraps a callExpression in another callExpression calling it with the 125 | // identifier name given. 126 | // 127 | // Example: `foo(1,2,3)` => callFunction('foo', 'bar') => `foo(1,2,3)(bar)` 128 | function callFunction(call, ident) { 129 | return ast => { 130 | types.visit(ast, { 131 | visitCallExpression: function (path) { 132 | var node = path.node; 133 | 134 | // If a callExpression's callee is also a callExpression 135 | // then we can assume state is being injected. 136 | // i.e. operation(...args)(state) 137 | if (n.Identifier.check(node.callee) && node.callee.name == call) { 138 | path.replace(b.callExpression(node, [b.identifier(ident)])); 139 | } 140 | 141 | return false; 142 | }, 143 | }); 144 | 145 | return ast; 146 | }; 147 | } 148 | 149 | // Wraps the first expression on the program in an IIFE. 150 | // 151 | // Example: `foo()` => wrapIIFE() => `(function() { return foo(); })()` 152 | function wrapIIFE() { 153 | return ast => { 154 | ast.program.body = [ 155 | b.expressionStatement( 156 | b.callExpression( 157 | b.functionExpression( 158 | null, 159 | [], 160 | b.blockStatement([ 161 | b.returnStatement(ast.program.body[0].expression), 162 | ]) 163 | ), 164 | [] 165 | ) 166 | ), 167 | ]; 168 | return ast; 169 | }; 170 | } 171 | 172 | // Class statements are now illegal in expressions, as they may expose 173 | // security vulnerabilities. See https://github.com/OpenFn/core/issues/47 174 | function banClasses() { 175 | return ast => { 176 | types.visit(ast, { 177 | visitClassDeclaration: () => { 178 | throw new Error('Illegal class statement'); 179 | }, 180 | }); 181 | return ast; 182 | }; 183 | } 184 | 185 | const defaultTransforms = [ 186 | banClasses(), 187 | wrapRootExpressions('execute'), 188 | callFunction('execute', 'state'), 189 | wrapIIFE(), 190 | ]; 191 | 192 | module.exports = { 193 | verify, 194 | wrapRootExpressions, 195 | callFunction, 196 | wrapIIFE, 197 | banClasses, 198 | defaultTransforms, 199 | }; 200 | -------------------------------------------------------------------------------- /lib/execute.js: -------------------------------------------------------------------------------- 1 | const { VM } = require('vm2'); 2 | 3 | // Executes a given expression in a sandbox, adding state in to the global 4 | // object. 5 | function Execute({ expression, state, sandbox }) { 6 | if (!expression) { 7 | throw new Error('Cannot execute without an expression.'); 8 | } 9 | if (!state) { 10 | throw new Error('Cannot execute without an initial state.'); 11 | } 12 | 13 | return new VM({ 14 | sandbox: Object.assign({ state }, sandbox), 15 | }).run(expression); 16 | } 17 | 18 | module.exports = Execute; 19 | -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | const Compile = require('./compile'); 2 | const Execute = require('./execute'); 3 | const transforms = require('./compile/transforms'); 4 | const sandbox = require('./sandbox'); 5 | 6 | module.exports = { 7 | Compile, Execute, transforms, sandbox 8 | } 9 | -------------------------------------------------------------------------------- /lib/sandbox/index.js: -------------------------------------------------------------------------------- 1 | const { VM } = require('vm2'); 2 | const { disabledConsole } = require('../utils'); 3 | 4 | // Get all the globals from an empty VM2 sandbox 5 | const VMGlobals = new VM({}).run( 6 | `Object.getOwnPropertyNames(this).reduce((obj, item) => { 7 | obj[item] = this[item]; 8 | return obj; 9 | }, {});` 10 | ); 11 | 12 | function buildSandbox( 13 | opts = { noConsole: false, testMode: false, extensions: [] } 14 | ) { 15 | // Create an object to be used as an extension to the VMs root object. 16 | 17 | return Object.assign( 18 | { 19 | console: opts.noConsole ? disabledConsole : console, // --nc or --noConsole 20 | testMode: opts.testMode, // --t or --test 21 | setTimeout, // We allow as Erlang will handle killing long-running VMs. 22 | }, 23 | ...opts.extensions 24 | ); 25 | } 26 | 27 | module.exports = { buildSandbox, VMGlobals }; 28 | -------------------------------------------------------------------------------- /lib/utils.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const safeStringify = require('fast-safe-stringify'); 3 | const path = require('path'); 4 | 5 | function getPackageJson(path) { 6 | const packageJson = fs.readFileSync(path); 7 | return JSON.parse(packageJson); 8 | } 9 | 10 | function getModuleDetails(languagePack) { 11 | return [...require.resolve.paths(languagePack), '.', process.cwd()].reduce( 12 | (result, p) => { 13 | if (result) return result; 14 | 15 | const maybePath = path.resolve(p, languagePack) + '/package.json'; 16 | 17 | if (fs.statSync(maybePath, { throwIfNoEntry: false })) { 18 | return getPackageJson(maybePath); 19 | } 20 | }, 21 | null 22 | ); 23 | } 24 | 25 | // require.resolve wrapped in an error handler, so that we can call successsively 26 | // to locate the package.json for a language-pack 27 | function safeResolve(request, options) { 28 | try { 29 | return require.resolve(request, options); 30 | } catch (error) { 31 | if (error.code == 'MODULE_NOT_FOUND') { 32 | return false; 33 | } 34 | 35 | throw error; 36 | } 37 | } 38 | 39 | // Generic Promise wrapper for fs.readFile. 40 | async function readFile(path, options = 'utf8') { 41 | return new Promise((resolve, reject) => { 42 | fs.readFile(path, options, (err, data) => { 43 | if (err) reject(err); 44 | resolve(data); 45 | }); 46 | }); 47 | } 48 | 49 | // Serialise and write object to JSON file. 50 | async function readJSON(path, options = 'utf8') { 51 | return JSON.parse(await readFile(...arguments)); 52 | } 53 | 54 | // Serialise and write object to JSON file. 55 | async function writeJSON(path, obj, options = 'utf8') { 56 | return new Promise((resolve, reject) => { 57 | try { 58 | let data = safeStringify(obj, null, 2); 59 | fs.writeFile(path, data, options, err => { 60 | if (err) reject(err); 61 | resolve(); 62 | }); 63 | } catch (e) { 64 | reject(e); 65 | } 66 | }); 67 | } 68 | 69 | function formatCompileError(code, error) { 70 | if (error.node.loc) { 71 | let { start, end } = error.node.loc; 72 | let margin; 73 | return [ 74 | (margin = `Line ${start.line}: `), 75 | code.split('\n')[start.line - 1] + '\n', 76 | Array(start.column + 1 + margin.length).join(' '), 77 | Array(Math.max(end.column - start.column + 1, 0)).join('^'), 78 | '\n' + error.message, 79 | ].join(''); 80 | } 81 | } 82 | 83 | function interceptRequests() { 84 | console.log('Test mode enabled...'); 85 | var Mitm = require('mitm'); 86 | var mitm = Mitm(); 87 | mitm.on('request', function (req, res) { 88 | console.log('Intercepted HTTP Request...'); 89 | console.log(`Method: ${req.method}`); 90 | console.log(`URL: ${req.url}`); 91 | console.log(`Headers: ${safeStringify(req.headers, null, 2)}`); 92 | var body = ''; 93 | req.on('readable', function () { 94 | body += req.read(); 95 | }); 96 | req.on('end', function () { 97 | try { 98 | jsonBody = JSON.parse(body); 99 | console.log(safeStringify(jsonBody, null, 2)); 100 | } catch (e) { 101 | console.log(body); 102 | } 103 | res.write( 104 | "What is real? How do you define 'real'? If you're talking about what\ 105 | you can feel, what you can smell, what you can taste and see,\ 106 | then 'real' is simply electrical signals interpreted by your brain." 107 | ); 108 | res.end(); 109 | }); 110 | }); 111 | } 112 | 113 | function warn() { 114 | console.log('🔒 console has been disabled for this run'); 115 | } 116 | 117 | const disabledConsole = { 118 | debug() { 119 | return warn(); 120 | }, 121 | error() { 122 | return warn(); 123 | }, 124 | info() { 125 | return warn(); 126 | }, 127 | log() { 128 | return warn(); 129 | }, 130 | warn() { 131 | return warn(); 132 | }, 133 | }; 134 | 135 | function addDebugLogs(languagePackage) { 136 | const corePackage = require('../package.json'); 137 | const adaptorVersion = languagePackage 138 | ? `${languagePackage.name}@${languagePackage.version}` 139 | : `unknown`; 140 | const debug1 = `│ ◲ ◱ ${corePackage.name}#v${corePackage.version} (Node.js ${process.version}) │`; 141 | const debug2 = 142 | '│ ◳ ◰ ' + 143 | ' '.repeat(debug1.length - adaptorVersion.length - 9) + 144 | ` ${adaptorVersion} │`; 145 | 146 | console.log('╭' + '─'.repeat(debug1.length - 2) + '╮'); 147 | console.log(debug1); 148 | console.log(debug2); 149 | console.log('╰' + '─'.repeat(debug1.length - 2) + '╯'); 150 | } 151 | 152 | module.exports = { 153 | addDebugLogs, 154 | disabledConsole, 155 | formatCompileError, 156 | interceptRequests, 157 | getModuleDetails, 158 | getPackageJson, 159 | readFile, 160 | readJSON, 161 | safeResolve, 162 | writeJSON, 163 | }; 164 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@openfn/core", 3 | "version": "1.5.1", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "@openfn/core", 9 | "version": "1.5.1", 10 | "license": "LGPL-3.0", 11 | "dependencies": { 12 | "@openfn/doclet-query": "^0.0.3", 13 | "acorn": "^8.0.5", 14 | "ast-types": "^0.14.2", 15 | "estemplate": "^0.5.1", 16 | "fast-safe-stringify": "^2.0.7", 17 | "mitm": "^1.3.2", 18 | "recast": "0.20.5", 19 | "vm2": "3.9.19", 20 | "yargs": "^17.4.0" 21 | }, 22 | "bin": { 23 | "core": "bin/core" 24 | }, 25 | "devDependencies": { 26 | "deep-eql": "4.0.1", 27 | "eslint": ">=4.18.2", 28 | "mocha": "^9.2.2", 29 | "prettier": "^2.2.1" 30 | }, 31 | "engines": { 32 | "node": ">= 12.17.0" 33 | } 34 | }, 35 | "node_modules/@eslint/eslintrc": { 36 | "version": "1.2.1", 37 | "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.1.tgz", 38 | "integrity": "sha512-bxvbYnBPN1Gibwyp6NrpnFzA3YtRL3BBAyEAFVIpNTm2Rn4Vy87GA5M4aSn3InRrlsbX5N0GW7XIx+U4SAEKdQ==", 39 | "dev": true, 40 | "dependencies": { 41 | "ajv": "^6.12.4", 42 | "debug": "^4.3.2", 43 | "espree": "^9.3.1", 44 | "globals": "^13.9.0", 45 | "ignore": "^5.2.0", 46 | "import-fresh": "^3.2.1", 47 | "js-yaml": "^4.1.0", 48 | "minimatch": "^3.0.4", 49 | "strip-json-comments": "^3.1.1" 50 | }, 51 | "engines": { 52 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 53 | } 54 | }, 55 | "node_modules/@humanwhocodes/config-array": { 56 | "version": "0.9.5", 57 | "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", 58 | "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", 59 | "dev": true, 60 | "dependencies": { 61 | "@humanwhocodes/object-schema": "^1.2.1", 62 | "debug": "^4.1.1", 63 | "minimatch": "^3.0.4" 64 | }, 65 | "engines": { 66 | "node": ">=10.10.0" 67 | } 68 | }, 69 | "node_modules/@humanwhocodes/object-schema": { 70 | "version": "1.2.1", 71 | "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", 72 | "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", 73 | "dev": true 74 | }, 75 | "node_modules/@openfn/doclet-query": { 76 | "version": "0.0.3", 77 | "resolved": "https://registry.npmjs.org/@openfn/doclet-query/-/doclet-query-0.0.3.tgz", 78 | "integrity": "sha512-OIVVGBAIzJ3uW3TcIVWnDsQ5xUtsHqdGt/gmlKA5Ku2sPpkpyBndm/bHt1MERmdYhXL8kwDKDOLH+y09MqinKA==", 79 | "dependencies": { 80 | "lodash": "^4.13.1" 81 | } 82 | }, 83 | "node_modules/@ungap/promise-all-settled": { 84 | "version": "1.1.2", 85 | "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", 86 | "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", 87 | "dev": true 88 | }, 89 | "node_modules/acorn": { 90 | "version": "8.7.0", 91 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", 92 | "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", 93 | "bin": { 94 | "acorn": "bin/acorn" 95 | }, 96 | "engines": { 97 | "node": ">=0.4.0" 98 | } 99 | }, 100 | "node_modules/acorn-jsx": { 101 | "version": "5.3.2", 102 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", 103 | "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", 104 | "dev": true, 105 | "peerDependencies": { 106 | "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" 107 | } 108 | }, 109 | "node_modules/acorn-walk": { 110 | "version": "8.2.0", 111 | "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", 112 | "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", 113 | "engines": { 114 | "node": ">=0.4.0" 115 | } 116 | }, 117 | "node_modules/ajv": { 118 | "version": "6.12.6", 119 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", 120 | "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", 121 | "dev": true, 122 | "dependencies": { 123 | "fast-deep-equal": "^3.1.1", 124 | "fast-json-stable-stringify": "^2.0.0", 125 | "json-schema-traverse": "^0.4.1", 126 | "uri-js": "^4.2.2" 127 | }, 128 | "funding": { 129 | "type": "github", 130 | "url": "https://github.com/sponsors/epoberezkin" 131 | } 132 | }, 133 | "node_modules/ansi-colors": { 134 | "version": "4.1.1", 135 | "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", 136 | "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", 137 | "dev": true, 138 | "engines": { 139 | "node": ">=6" 140 | } 141 | }, 142 | "node_modules/ansi-regex": { 143 | "version": "5.0.1", 144 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 145 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 146 | "engines": { 147 | "node": ">=8" 148 | } 149 | }, 150 | "node_modules/ansi-styles": { 151 | "version": "4.3.0", 152 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 153 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 154 | "dependencies": { 155 | "color-convert": "^2.0.1" 156 | }, 157 | "engines": { 158 | "node": ">=8" 159 | }, 160 | "funding": { 161 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 162 | } 163 | }, 164 | "node_modules/anymatch": { 165 | "version": "3.1.2", 166 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", 167 | "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", 168 | "dev": true, 169 | "dependencies": { 170 | "normalize-path": "^3.0.0", 171 | "picomatch": "^2.0.4" 172 | }, 173 | "engines": { 174 | "node": ">= 8" 175 | } 176 | }, 177 | "node_modules/argparse": { 178 | "version": "2.0.1", 179 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", 180 | "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", 181 | "dev": true 182 | }, 183 | "node_modules/ast-types": { 184 | "version": "0.14.2", 185 | "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.14.2.tgz", 186 | "integrity": "sha512-O0yuUDnZeQDL+ncNGlJ78BiO4jnYI3bvMsD5prT0/nsgijG/LpNBIr63gTjVTNsiGkgQhiyCShTgxt8oXOrklA==", 187 | "dependencies": { 188 | "tslib": "^2.0.1" 189 | }, 190 | "engines": { 191 | "node": ">=4" 192 | } 193 | }, 194 | "node_modules/balanced-match": { 195 | "version": "1.0.2", 196 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 197 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 198 | "dev": true 199 | }, 200 | "node_modules/binary-extensions": { 201 | "version": "2.2.0", 202 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", 203 | "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", 204 | "dev": true, 205 | "engines": { 206 | "node": ">=8" 207 | } 208 | }, 209 | "node_modules/brace-expansion": { 210 | "version": "1.1.11", 211 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 212 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 213 | "dev": true, 214 | "dependencies": { 215 | "balanced-match": "^1.0.0", 216 | "concat-map": "0.0.1" 217 | } 218 | }, 219 | "node_modules/braces": { 220 | "version": "3.0.3", 221 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", 222 | "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", 223 | "dev": true, 224 | "dependencies": { 225 | "fill-range": "^7.1.1" 226 | }, 227 | "engines": { 228 | "node": ">=8" 229 | } 230 | }, 231 | "node_modules/browser-stdout": { 232 | "version": "1.3.1", 233 | "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", 234 | "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", 235 | "dev": true 236 | }, 237 | "node_modules/callsites": { 238 | "version": "3.1.0", 239 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", 240 | "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", 241 | "dev": true, 242 | "engines": { 243 | "node": ">=6" 244 | } 245 | }, 246 | "node_modules/camelcase": { 247 | "version": "6.3.0", 248 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", 249 | "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", 250 | "dev": true, 251 | "engines": { 252 | "node": ">=10" 253 | }, 254 | "funding": { 255 | "url": "https://github.com/sponsors/sindresorhus" 256 | } 257 | }, 258 | "node_modules/chalk": { 259 | "version": "4.1.2", 260 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", 261 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", 262 | "dev": true, 263 | "dependencies": { 264 | "ansi-styles": "^4.1.0", 265 | "supports-color": "^7.1.0" 266 | }, 267 | "engines": { 268 | "node": ">=10" 269 | }, 270 | "funding": { 271 | "url": "https://github.com/chalk/chalk?sponsor=1" 272 | } 273 | }, 274 | "node_modules/chokidar": { 275 | "version": "3.5.3", 276 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", 277 | "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", 278 | "dev": true, 279 | "funding": [ 280 | { 281 | "type": "individual", 282 | "url": "https://paulmillr.com/funding/" 283 | } 284 | ], 285 | "dependencies": { 286 | "anymatch": "~3.1.2", 287 | "braces": "~3.0.2", 288 | "glob-parent": "~5.1.2", 289 | "is-binary-path": "~2.1.0", 290 | "is-glob": "~4.0.1", 291 | "normalize-path": "~3.0.0", 292 | "readdirp": "~3.6.0" 293 | }, 294 | "engines": { 295 | "node": ">= 8.10.0" 296 | }, 297 | "optionalDependencies": { 298 | "fsevents": "~2.3.2" 299 | } 300 | }, 301 | "node_modules/chokidar/node_modules/glob-parent": { 302 | "version": "5.1.2", 303 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 304 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 305 | "dev": true, 306 | "dependencies": { 307 | "is-glob": "^4.0.1" 308 | }, 309 | "engines": { 310 | "node": ">= 6" 311 | } 312 | }, 313 | "node_modules/cliui": { 314 | "version": "7.0.4", 315 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", 316 | "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", 317 | "dependencies": { 318 | "string-width": "^4.2.0", 319 | "strip-ansi": "^6.0.0", 320 | "wrap-ansi": "^7.0.0" 321 | } 322 | }, 323 | "node_modules/color-convert": { 324 | "version": "2.0.1", 325 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 326 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 327 | "dependencies": { 328 | "color-name": "~1.1.4" 329 | }, 330 | "engines": { 331 | "node": ">=7.0.0" 332 | } 333 | }, 334 | "node_modules/color-name": { 335 | "version": "1.1.4", 336 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 337 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" 338 | }, 339 | "node_modules/concat-map": { 340 | "version": "0.0.1", 341 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 342 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 343 | "dev": true 344 | }, 345 | "node_modules/cross-spawn": { 346 | "version": "7.0.3", 347 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", 348 | "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", 349 | "dev": true, 350 | "dependencies": { 351 | "path-key": "^3.1.0", 352 | "shebang-command": "^2.0.0", 353 | "which": "^2.0.1" 354 | }, 355 | "engines": { 356 | "node": ">= 8" 357 | } 358 | }, 359 | "node_modules/debug": { 360 | "version": "4.3.4", 361 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", 362 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", 363 | "dev": true, 364 | "dependencies": { 365 | "ms": "2.1.2" 366 | }, 367 | "engines": { 368 | "node": ">=6.0" 369 | }, 370 | "peerDependenciesMeta": { 371 | "supports-color": { 372 | "optional": true 373 | } 374 | } 375 | }, 376 | "node_modules/decamelize": { 377 | "version": "4.0.0", 378 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", 379 | "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", 380 | "dev": true, 381 | "engines": { 382 | "node": ">=10" 383 | }, 384 | "funding": { 385 | "url": "https://github.com/sponsors/sindresorhus" 386 | } 387 | }, 388 | "node_modules/deep-eql": { 389 | "version": "4.0.1", 390 | "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.0.1.tgz", 391 | "integrity": "sha512-D/Oxqobjr+kxaHsgiQBZq9b6iAWdEj5W/JdJm8deNduAPc9CwXQ3BJJCuEqlrPXcy45iOMkGPZ0T81Dnz7UDCA==", 392 | "dev": true, 393 | "dependencies": { 394 | "type-detect": "^4.0.0" 395 | }, 396 | "engines": { 397 | "node": ">=6" 398 | } 399 | }, 400 | "node_modules/deep-is": { 401 | "version": "0.1.4", 402 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", 403 | "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", 404 | "dev": true 405 | }, 406 | "node_modules/diff": { 407 | "version": "5.0.0", 408 | "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", 409 | "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", 410 | "dev": true, 411 | "engines": { 412 | "node": ">=0.3.1" 413 | } 414 | }, 415 | "node_modules/doctrine": { 416 | "version": "3.0.0", 417 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", 418 | "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", 419 | "dev": true, 420 | "dependencies": { 421 | "esutils": "^2.0.2" 422 | }, 423 | "engines": { 424 | "node": ">=6.0.0" 425 | } 426 | }, 427 | "node_modules/emoji-regex": { 428 | "version": "8.0.0", 429 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 430 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" 431 | }, 432 | "node_modules/escalade": { 433 | "version": "3.1.1", 434 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", 435 | "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", 436 | "engines": { 437 | "node": ">=6" 438 | } 439 | }, 440 | "node_modules/escape-string-regexp": { 441 | "version": "4.0.0", 442 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", 443 | "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", 444 | "dev": true, 445 | "engines": { 446 | "node": ">=10" 447 | }, 448 | "funding": { 449 | "url": "https://github.com/sponsors/sindresorhus" 450 | } 451 | }, 452 | "node_modules/eslint": { 453 | "version": "8.11.0", 454 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.11.0.tgz", 455 | "integrity": "sha512-/KRpd9mIRg2raGxHRGwW9ZywYNAClZrHjdueHcrVDuO3a6bj83eoTirCCk0M0yPwOjWYKHwRVRid+xK4F/GHgA==", 456 | "dev": true, 457 | "dependencies": { 458 | "@eslint/eslintrc": "^1.2.1", 459 | "@humanwhocodes/config-array": "^0.9.2", 460 | "ajv": "^6.10.0", 461 | "chalk": "^4.0.0", 462 | "cross-spawn": "^7.0.2", 463 | "debug": "^4.3.2", 464 | "doctrine": "^3.0.0", 465 | "escape-string-regexp": "^4.0.0", 466 | "eslint-scope": "^7.1.1", 467 | "eslint-utils": "^3.0.0", 468 | "eslint-visitor-keys": "^3.3.0", 469 | "espree": "^9.3.1", 470 | "esquery": "^1.4.0", 471 | "esutils": "^2.0.2", 472 | "fast-deep-equal": "^3.1.3", 473 | "file-entry-cache": "^6.0.1", 474 | "functional-red-black-tree": "^1.0.1", 475 | "glob-parent": "^6.0.1", 476 | "globals": "^13.6.0", 477 | "ignore": "^5.2.0", 478 | "import-fresh": "^3.0.0", 479 | "imurmurhash": "^0.1.4", 480 | "is-glob": "^4.0.0", 481 | "js-yaml": "^4.1.0", 482 | "json-stable-stringify-without-jsonify": "^1.0.1", 483 | "levn": "^0.4.1", 484 | "lodash.merge": "^4.6.2", 485 | "minimatch": "^3.0.4", 486 | "natural-compare": "^1.4.0", 487 | "optionator": "^0.9.1", 488 | "regexpp": "^3.2.0", 489 | "strip-ansi": "^6.0.1", 490 | "strip-json-comments": "^3.1.0", 491 | "text-table": "^0.2.0", 492 | "v8-compile-cache": "^2.0.3" 493 | }, 494 | "bin": { 495 | "eslint": "bin/eslint.js" 496 | }, 497 | "engines": { 498 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 499 | }, 500 | "funding": { 501 | "url": "https://opencollective.com/eslint" 502 | } 503 | }, 504 | "node_modules/eslint-scope": { 505 | "version": "7.1.1", 506 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", 507 | "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", 508 | "dev": true, 509 | "dependencies": { 510 | "esrecurse": "^4.3.0", 511 | "estraverse": "^5.2.0" 512 | }, 513 | "engines": { 514 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 515 | } 516 | }, 517 | "node_modules/eslint-utils": { 518 | "version": "3.0.0", 519 | "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", 520 | "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", 521 | "dev": true, 522 | "dependencies": { 523 | "eslint-visitor-keys": "^2.0.0" 524 | }, 525 | "engines": { 526 | "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" 527 | }, 528 | "funding": { 529 | "url": "https://github.com/sponsors/mysticatea" 530 | }, 531 | "peerDependencies": { 532 | "eslint": ">=5" 533 | } 534 | }, 535 | "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { 536 | "version": "2.1.0", 537 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", 538 | "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", 539 | "dev": true, 540 | "engines": { 541 | "node": ">=10" 542 | } 543 | }, 544 | "node_modules/eslint-visitor-keys": { 545 | "version": "3.3.0", 546 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", 547 | "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", 548 | "dev": true, 549 | "engines": { 550 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 551 | } 552 | }, 553 | "node_modules/espree": { 554 | "version": "9.3.1", 555 | "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz", 556 | "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==", 557 | "dev": true, 558 | "dependencies": { 559 | "acorn": "^8.7.0", 560 | "acorn-jsx": "^5.3.1", 561 | "eslint-visitor-keys": "^3.3.0" 562 | }, 563 | "engines": { 564 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 565 | } 566 | }, 567 | "node_modules/esprima": { 568 | "version": "2.7.3", 569 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", 570 | "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", 571 | "bin": { 572 | "esparse": "bin/esparse.js", 573 | "esvalidate": "bin/esvalidate.js" 574 | }, 575 | "engines": { 576 | "node": ">=0.10.0" 577 | } 578 | }, 579 | "node_modules/esquery": { 580 | "version": "1.4.0", 581 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", 582 | "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", 583 | "dev": true, 584 | "dependencies": { 585 | "estraverse": "^5.1.0" 586 | }, 587 | "engines": { 588 | "node": ">=0.10" 589 | } 590 | }, 591 | "node_modules/esrecurse": { 592 | "version": "4.3.0", 593 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", 594 | "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", 595 | "dev": true, 596 | "dependencies": { 597 | "estraverse": "^5.2.0" 598 | }, 599 | "engines": { 600 | "node": ">=4.0" 601 | } 602 | }, 603 | "node_modules/estemplate": { 604 | "version": "0.5.1", 605 | "resolved": "https://registry.npmjs.org/estemplate/-/estemplate-0.5.1.tgz", 606 | "integrity": "sha1-FxSp1GGQc4rJWLyv1J4CnNpWo54=", 607 | "dependencies": { 608 | "esprima": "^2.7.2", 609 | "estraverse": "^4.1.1" 610 | } 611 | }, 612 | "node_modules/estemplate/node_modules/estraverse": { 613 | "version": "4.3.0", 614 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", 615 | "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", 616 | "engines": { 617 | "node": ">=4.0" 618 | } 619 | }, 620 | "node_modules/estraverse": { 621 | "version": "5.3.0", 622 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", 623 | "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", 624 | "dev": true, 625 | "engines": { 626 | "node": ">=4.0" 627 | } 628 | }, 629 | "node_modules/esutils": { 630 | "version": "2.0.3", 631 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", 632 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", 633 | "dev": true, 634 | "engines": { 635 | "node": ">=0.10.0" 636 | } 637 | }, 638 | "node_modules/fast-deep-equal": { 639 | "version": "3.1.3", 640 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", 641 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", 642 | "dev": true 643 | }, 644 | "node_modules/fast-json-stable-stringify": { 645 | "version": "2.1.0", 646 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 647 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", 648 | "dev": true 649 | }, 650 | "node_modules/fast-levenshtein": { 651 | "version": "2.0.6", 652 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 653 | "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", 654 | "dev": true 655 | }, 656 | "node_modules/fast-safe-stringify": { 657 | "version": "2.1.1", 658 | "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", 659 | "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" 660 | }, 661 | "node_modules/file-entry-cache": { 662 | "version": "6.0.1", 663 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", 664 | "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", 665 | "dev": true, 666 | "dependencies": { 667 | "flat-cache": "^3.0.4" 668 | }, 669 | "engines": { 670 | "node": "^10.12.0 || >=12.0.0" 671 | } 672 | }, 673 | "node_modules/fill-range": { 674 | "version": "7.1.1", 675 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", 676 | "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", 677 | "dev": true, 678 | "dependencies": { 679 | "to-regex-range": "^5.0.1" 680 | }, 681 | "engines": { 682 | "node": ">=8" 683 | } 684 | }, 685 | "node_modules/find-up": { 686 | "version": "5.0.0", 687 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", 688 | "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", 689 | "dev": true, 690 | "dependencies": { 691 | "locate-path": "^6.0.0", 692 | "path-exists": "^4.0.0" 693 | }, 694 | "engines": { 695 | "node": ">=10" 696 | }, 697 | "funding": { 698 | "url": "https://github.com/sponsors/sindresorhus" 699 | } 700 | }, 701 | "node_modules/flat": { 702 | "version": "5.0.2", 703 | "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", 704 | "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", 705 | "dev": true, 706 | "bin": { 707 | "flat": "cli.js" 708 | } 709 | }, 710 | "node_modules/flat-cache": { 711 | "version": "3.0.4", 712 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", 713 | "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", 714 | "dev": true, 715 | "dependencies": { 716 | "flatted": "^3.1.0", 717 | "rimraf": "^3.0.2" 718 | }, 719 | "engines": { 720 | "node": "^10.12.0 || >=12.0.0" 721 | } 722 | }, 723 | "node_modules/flatted": { 724 | "version": "3.2.5", 725 | "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", 726 | "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", 727 | "dev": true 728 | }, 729 | "node_modules/fs.realpath": { 730 | "version": "1.0.0", 731 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 732 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 733 | "dev": true 734 | }, 735 | "node_modules/fsevents": { 736 | "version": "2.3.2", 737 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 738 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 739 | "dev": true, 740 | "hasInstallScript": true, 741 | "optional": true, 742 | "os": [ 743 | "darwin" 744 | ], 745 | "engines": { 746 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 747 | } 748 | }, 749 | "node_modules/functional-red-black-tree": { 750 | "version": "1.0.1", 751 | "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", 752 | "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", 753 | "dev": true 754 | }, 755 | "node_modules/get-caller-file": { 756 | "version": "2.0.5", 757 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", 758 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", 759 | "engines": { 760 | "node": "6.* || 8.* || >= 10.*" 761 | } 762 | }, 763 | "node_modules/glob": { 764 | "version": "7.2.0", 765 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", 766 | "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", 767 | "dev": true, 768 | "dependencies": { 769 | "fs.realpath": "^1.0.0", 770 | "inflight": "^1.0.4", 771 | "inherits": "2", 772 | "minimatch": "^3.0.4", 773 | "once": "^1.3.0", 774 | "path-is-absolute": "^1.0.0" 775 | }, 776 | "engines": { 777 | "node": "*" 778 | }, 779 | "funding": { 780 | "url": "https://github.com/sponsors/isaacs" 781 | } 782 | }, 783 | "node_modules/glob-parent": { 784 | "version": "6.0.2", 785 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", 786 | "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", 787 | "dev": true, 788 | "dependencies": { 789 | "is-glob": "^4.0.3" 790 | }, 791 | "engines": { 792 | "node": ">=10.13.0" 793 | } 794 | }, 795 | "node_modules/globals": { 796 | "version": "13.13.0", 797 | "resolved": "https://registry.npmjs.org/globals/-/globals-13.13.0.tgz", 798 | "integrity": "sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A==", 799 | "dev": true, 800 | "dependencies": { 801 | "type-fest": "^0.20.2" 802 | }, 803 | "engines": { 804 | "node": ">=8" 805 | }, 806 | "funding": { 807 | "url": "https://github.com/sponsors/sindresorhus" 808 | } 809 | }, 810 | "node_modules/growl": { 811 | "version": "1.10.5", 812 | "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", 813 | "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", 814 | "dev": true, 815 | "engines": { 816 | "node": ">=4.x" 817 | } 818 | }, 819 | "node_modules/has-flag": { 820 | "version": "4.0.0", 821 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 822 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 823 | "dev": true, 824 | "engines": { 825 | "node": ">=8" 826 | } 827 | }, 828 | "node_modules/he": { 829 | "version": "1.2.0", 830 | "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", 831 | "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", 832 | "dev": true, 833 | "bin": { 834 | "he": "bin/he" 835 | } 836 | }, 837 | "node_modules/ignore": { 838 | "version": "5.2.0", 839 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", 840 | "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", 841 | "dev": true, 842 | "engines": { 843 | "node": ">= 4" 844 | } 845 | }, 846 | "node_modules/import-fresh": { 847 | "version": "3.3.0", 848 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", 849 | "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", 850 | "dev": true, 851 | "dependencies": { 852 | "parent-module": "^1.0.0", 853 | "resolve-from": "^4.0.0" 854 | }, 855 | "engines": { 856 | "node": ">=6" 857 | }, 858 | "funding": { 859 | "url": "https://github.com/sponsors/sindresorhus" 860 | } 861 | }, 862 | "node_modules/imurmurhash": { 863 | "version": "0.1.4", 864 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 865 | "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", 866 | "dev": true, 867 | "engines": { 868 | "node": ">=0.8.19" 869 | } 870 | }, 871 | "node_modules/inflight": { 872 | "version": "1.0.6", 873 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 874 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 875 | "dev": true, 876 | "dependencies": { 877 | "once": "^1.3.0", 878 | "wrappy": "1" 879 | } 880 | }, 881 | "node_modules/inherits": { 882 | "version": "2.0.4", 883 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 884 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 885 | "dev": true 886 | }, 887 | "node_modules/is-binary-path": { 888 | "version": "2.1.0", 889 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", 890 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", 891 | "dev": true, 892 | "dependencies": { 893 | "binary-extensions": "^2.0.0" 894 | }, 895 | "engines": { 896 | "node": ">=8" 897 | } 898 | }, 899 | "node_modules/is-extglob": { 900 | "version": "2.1.1", 901 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 902 | "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", 903 | "dev": true, 904 | "engines": { 905 | "node": ">=0.10.0" 906 | } 907 | }, 908 | "node_modules/is-fullwidth-code-point": { 909 | "version": "3.0.0", 910 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 911 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", 912 | "engines": { 913 | "node": ">=8" 914 | } 915 | }, 916 | "node_modules/is-glob": { 917 | "version": "4.0.3", 918 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 919 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 920 | "dev": true, 921 | "dependencies": { 922 | "is-extglob": "^2.1.1" 923 | }, 924 | "engines": { 925 | "node": ">=0.10.0" 926 | } 927 | }, 928 | "node_modules/is-number": { 929 | "version": "7.0.0", 930 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 931 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 932 | "dev": true, 933 | "engines": { 934 | "node": ">=0.12.0" 935 | } 936 | }, 937 | "node_modules/is-plain-obj": { 938 | "version": "2.1.0", 939 | "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", 940 | "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", 941 | "dev": true, 942 | "engines": { 943 | "node": ">=8" 944 | } 945 | }, 946 | "node_modules/is-unicode-supported": { 947 | "version": "0.1.0", 948 | "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", 949 | "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", 950 | "dev": true, 951 | "engines": { 952 | "node": ">=10" 953 | }, 954 | "funding": { 955 | "url": "https://github.com/sponsors/sindresorhus" 956 | } 957 | }, 958 | "node_modules/isexe": { 959 | "version": "2.0.0", 960 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 961 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", 962 | "dev": true 963 | }, 964 | "node_modules/js-yaml": { 965 | "version": "4.1.0", 966 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", 967 | "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", 968 | "dev": true, 969 | "dependencies": { 970 | "argparse": "^2.0.1" 971 | }, 972 | "bin": { 973 | "js-yaml": "bin/js-yaml.js" 974 | } 975 | }, 976 | "node_modules/json-schema-traverse": { 977 | "version": "0.4.1", 978 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 979 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", 980 | "dev": true 981 | }, 982 | "node_modules/json-stable-stringify-without-jsonify": { 983 | "version": "1.0.1", 984 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", 985 | "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", 986 | "dev": true 987 | }, 988 | "node_modules/levn": { 989 | "version": "0.4.1", 990 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", 991 | "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", 992 | "dev": true, 993 | "dependencies": { 994 | "prelude-ls": "^1.2.1", 995 | "type-check": "~0.4.0" 996 | }, 997 | "engines": { 998 | "node": ">= 0.8.0" 999 | } 1000 | }, 1001 | "node_modules/locate-path": { 1002 | "version": "6.0.0", 1003 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", 1004 | "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", 1005 | "dev": true, 1006 | "dependencies": { 1007 | "p-locate": "^5.0.0" 1008 | }, 1009 | "engines": { 1010 | "node": ">=10" 1011 | }, 1012 | "funding": { 1013 | "url": "https://github.com/sponsors/sindresorhus" 1014 | } 1015 | }, 1016 | "node_modules/lodash": { 1017 | "version": "4.17.21", 1018 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", 1019 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" 1020 | }, 1021 | "node_modules/lodash.merge": { 1022 | "version": "4.6.2", 1023 | "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", 1024 | "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", 1025 | "dev": true 1026 | }, 1027 | "node_modules/log-symbols": { 1028 | "version": "4.1.0", 1029 | "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", 1030 | "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", 1031 | "dev": true, 1032 | "dependencies": { 1033 | "chalk": "^4.1.0", 1034 | "is-unicode-supported": "^0.1.0" 1035 | }, 1036 | "engines": { 1037 | "node": ">=10" 1038 | }, 1039 | "funding": { 1040 | "url": "https://github.com/sponsors/sindresorhus" 1041 | } 1042 | }, 1043 | "node_modules/minimatch": { 1044 | "version": "3.1.2", 1045 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 1046 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 1047 | "dev": true, 1048 | "dependencies": { 1049 | "brace-expansion": "^1.1.7" 1050 | }, 1051 | "engines": { 1052 | "node": "*" 1053 | } 1054 | }, 1055 | "node_modules/mitm": { 1056 | "version": "1.7.2", 1057 | "resolved": "https://registry.npmjs.org/mitm/-/mitm-1.7.2.tgz", 1058 | "integrity": "sha512-SuiJbc5xisP/iUYvsKAvrvPeoyJQbYI3WOfnp8A7XHDn4wkdtmGZe2ZTFXIo3K1of05oxUiaJIK+GoAU5KgFOw==", 1059 | "dependencies": { 1060 | "semver": ">= 5 < 6", 1061 | "underscore": ">= 1.1.6 < 1.14" 1062 | }, 1063 | "engines": { 1064 | "node": ">= 0.10.24" 1065 | } 1066 | }, 1067 | "node_modules/mocha": { 1068 | "version": "9.2.2", 1069 | "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz", 1070 | "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==", 1071 | "dev": true, 1072 | "dependencies": { 1073 | "@ungap/promise-all-settled": "1.1.2", 1074 | "ansi-colors": "4.1.1", 1075 | "browser-stdout": "1.3.1", 1076 | "chokidar": "3.5.3", 1077 | "debug": "4.3.3", 1078 | "diff": "5.0.0", 1079 | "escape-string-regexp": "4.0.0", 1080 | "find-up": "5.0.0", 1081 | "glob": "7.2.0", 1082 | "growl": "1.10.5", 1083 | "he": "1.2.0", 1084 | "js-yaml": "4.1.0", 1085 | "log-symbols": "4.1.0", 1086 | "minimatch": "4.2.1", 1087 | "ms": "2.1.3", 1088 | "nanoid": "3.3.1", 1089 | "serialize-javascript": "6.0.0", 1090 | "strip-json-comments": "3.1.1", 1091 | "supports-color": "8.1.1", 1092 | "which": "2.0.2", 1093 | "workerpool": "6.2.0", 1094 | "yargs": "16.2.0", 1095 | "yargs-parser": "20.2.4", 1096 | "yargs-unparser": "2.0.0" 1097 | }, 1098 | "bin": { 1099 | "_mocha": "bin/_mocha", 1100 | "mocha": "bin/mocha" 1101 | }, 1102 | "engines": { 1103 | "node": ">= 12.0.0" 1104 | }, 1105 | "funding": { 1106 | "type": "opencollective", 1107 | "url": "https://opencollective.com/mochajs" 1108 | } 1109 | }, 1110 | "node_modules/mocha/node_modules/debug": { 1111 | "version": "4.3.3", 1112 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", 1113 | "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", 1114 | "dev": true, 1115 | "dependencies": { 1116 | "ms": "2.1.2" 1117 | }, 1118 | "engines": { 1119 | "node": ">=6.0" 1120 | }, 1121 | "peerDependenciesMeta": { 1122 | "supports-color": { 1123 | "optional": true 1124 | } 1125 | } 1126 | }, 1127 | "node_modules/mocha/node_modules/debug/node_modules/ms": { 1128 | "version": "2.1.2", 1129 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 1130 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 1131 | "dev": true 1132 | }, 1133 | "node_modules/mocha/node_modules/minimatch": { 1134 | "version": "4.2.1", 1135 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", 1136 | "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==", 1137 | "dev": true, 1138 | "dependencies": { 1139 | "brace-expansion": "^1.1.7" 1140 | }, 1141 | "engines": { 1142 | "node": ">=10" 1143 | } 1144 | }, 1145 | "node_modules/mocha/node_modules/ms": { 1146 | "version": "2.1.3", 1147 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 1148 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 1149 | "dev": true 1150 | }, 1151 | "node_modules/mocha/node_modules/supports-color": { 1152 | "version": "8.1.1", 1153 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", 1154 | "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", 1155 | "dev": true, 1156 | "dependencies": { 1157 | "has-flag": "^4.0.0" 1158 | }, 1159 | "engines": { 1160 | "node": ">=10" 1161 | }, 1162 | "funding": { 1163 | "url": "https://github.com/chalk/supports-color?sponsor=1" 1164 | } 1165 | }, 1166 | "node_modules/mocha/node_modules/yargs": { 1167 | "version": "16.2.0", 1168 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", 1169 | "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", 1170 | "dev": true, 1171 | "dependencies": { 1172 | "cliui": "^7.0.2", 1173 | "escalade": "^3.1.1", 1174 | "get-caller-file": "^2.0.5", 1175 | "require-directory": "^2.1.1", 1176 | "string-width": "^4.2.0", 1177 | "y18n": "^5.0.5", 1178 | "yargs-parser": "^20.2.2" 1179 | }, 1180 | "engines": { 1181 | "node": ">=10" 1182 | } 1183 | }, 1184 | "node_modules/ms": { 1185 | "version": "2.1.2", 1186 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 1187 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 1188 | "dev": true 1189 | }, 1190 | "node_modules/nanoid": { 1191 | "version": "3.3.1", 1192 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", 1193 | "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", 1194 | "dev": true, 1195 | "bin": { 1196 | "nanoid": "bin/nanoid.cjs" 1197 | }, 1198 | "engines": { 1199 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" 1200 | } 1201 | }, 1202 | "node_modules/natural-compare": { 1203 | "version": "1.4.0", 1204 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", 1205 | "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", 1206 | "dev": true 1207 | }, 1208 | "node_modules/normalize-path": { 1209 | "version": "3.0.0", 1210 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", 1211 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", 1212 | "dev": true, 1213 | "engines": { 1214 | "node": ">=0.10.0" 1215 | } 1216 | }, 1217 | "node_modules/once": { 1218 | "version": "1.4.0", 1219 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1220 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 1221 | "dev": true, 1222 | "dependencies": { 1223 | "wrappy": "1" 1224 | } 1225 | }, 1226 | "node_modules/optionator": { 1227 | "version": "0.9.1", 1228 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", 1229 | "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", 1230 | "dev": true, 1231 | "dependencies": { 1232 | "deep-is": "^0.1.3", 1233 | "fast-levenshtein": "^2.0.6", 1234 | "levn": "^0.4.1", 1235 | "prelude-ls": "^1.2.1", 1236 | "type-check": "^0.4.0", 1237 | "word-wrap": "^1.2.3" 1238 | }, 1239 | "engines": { 1240 | "node": ">= 0.8.0" 1241 | } 1242 | }, 1243 | "node_modules/p-limit": { 1244 | "version": "3.1.0", 1245 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", 1246 | "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", 1247 | "dev": true, 1248 | "dependencies": { 1249 | "yocto-queue": "^0.1.0" 1250 | }, 1251 | "engines": { 1252 | "node": ">=10" 1253 | }, 1254 | "funding": { 1255 | "url": "https://github.com/sponsors/sindresorhus" 1256 | } 1257 | }, 1258 | "node_modules/p-locate": { 1259 | "version": "5.0.0", 1260 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", 1261 | "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", 1262 | "dev": true, 1263 | "dependencies": { 1264 | "p-limit": "^3.0.2" 1265 | }, 1266 | "engines": { 1267 | "node": ">=10" 1268 | }, 1269 | "funding": { 1270 | "url": "https://github.com/sponsors/sindresorhus" 1271 | } 1272 | }, 1273 | "node_modules/parent-module": { 1274 | "version": "1.0.1", 1275 | "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", 1276 | "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", 1277 | "dev": true, 1278 | "dependencies": { 1279 | "callsites": "^3.0.0" 1280 | }, 1281 | "engines": { 1282 | "node": ">=6" 1283 | } 1284 | }, 1285 | "node_modules/path-exists": { 1286 | "version": "4.0.0", 1287 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", 1288 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", 1289 | "dev": true, 1290 | "engines": { 1291 | "node": ">=8" 1292 | } 1293 | }, 1294 | "node_modules/path-is-absolute": { 1295 | "version": "1.0.1", 1296 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 1297 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 1298 | "dev": true, 1299 | "engines": { 1300 | "node": ">=0.10.0" 1301 | } 1302 | }, 1303 | "node_modules/path-key": { 1304 | "version": "3.1.1", 1305 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", 1306 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", 1307 | "dev": true, 1308 | "engines": { 1309 | "node": ">=8" 1310 | } 1311 | }, 1312 | "node_modules/picomatch": { 1313 | "version": "2.3.1", 1314 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 1315 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", 1316 | "dev": true, 1317 | "engines": { 1318 | "node": ">=8.6" 1319 | }, 1320 | "funding": { 1321 | "url": "https://github.com/sponsors/jonschlinkert" 1322 | } 1323 | }, 1324 | "node_modules/prelude-ls": { 1325 | "version": "1.2.1", 1326 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", 1327 | "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", 1328 | "dev": true, 1329 | "engines": { 1330 | "node": ">= 0.8.0" 1331 | } 1332 | }, 1333 | "node_modules/prettier": { 1334 | "version": "2.6.1", 1335 | "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.1.tgz", 1336 | "integrity": "sha512-8UVbTBYGwN37Bs9LERmxCPjdvPxlEowx2urIL6urHzdb3SDq4B/Z6xLFCblrSnE4iKWcS6ziJ3aOYrc1kz/E2A==", 1337 | "dev": true, 1338 | "bin": { 1339 | "prettier": "bin-prettier.js" 1340 | }, 1341 | "engines": { 1342 | "node": ">=10.13.0" 1343 | }, 1344 | "funding": { 1345 | "url": "https://github.com/prettier/prettier?sponsor=1" 1346 | } 1347 | }, 1348 | "node_modules/punycode": { 1349 | "version": "2.1.1", 1350 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", 1351 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", 1352 | "dev": true, 1353 | "engines": { 1354 | "node": ">=6" 1355 | } 1356 | }, 1357 | "node_modules/randombytes": { 1358 | "version": "2.1.0", 1359 | "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", 1360 | "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", 1361 | "dev": true, 1362 | "dependencies": { 1363 | "safe-buffer": "^5.1.0" 1364 | } 1365 | }, 1366 | "node_modules/readdirp": { 1367 | "version": "3.6.0", 1368 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", 1369 | "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", 1370 | "dev": true, 1371 | "dependencies": { 1372 | "picomatch": "^2.2.1" 1373 | }, 1374 | "engines": { 1375 | "node": ">=8.10.0" 1376 | } 1377 | }, 1378 | "node_modules/recast": { 1379 | "version": "0.20.5", 1380 | "resolved": "https://registry.npmjs.org/recast/-/recast-0.20.5.tgz", 1381 | "integrity": "sha512-E5qICoPoNL4yU0H0NoBDntNB0Q5oMSNh9usFctYniLBluTthi3RsQVBXIJNbApOlvSwW/RGxIuokPcAc59J5fQ==", 1382 | "dependencies": { 1383 | "ast-types": "0.14.2", 1384 | "esprima": "~4.0.0", 1385 | "source-map": "~0.6.1", 1386 | "tslib": "^2.0.1" 1387 | }, 1388 | "engines": { 1389 | "node": ">= 4" 1390 | } 1391 | }, 1392 | "node_modules/recast/node_modules/esprima": { 1393 | "version": "4.0.1", 1394 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", 1395 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", 1396 | "bin": { 1397 | "esparse": "bin/esparse.js", 1398 | "esvalidate": "bin/esvalidate.js" 1399 | }, 1400 | "engines": { 1401 | "node": ">=4" 1402 | } 1403 | }, 1404 | "node_modules/regexpp": { 1405 | "version": "3.2.0", 1406 | "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", 1407 | "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", 1408 | "dev": true, 1409 | "engines": { 1410 | "node": ">=8" 1411 | }, 1412 | "funding": { 1413 | "url": "https://github.com/sponsors/mysticatea" 1414 | } 1415 | }, 1416 | "node_modules/require-directory": { 1417 | "version": "2.1.1", 1418 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", 1419 | "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", 1420 | "engines": { 1421 | "node": ">=0.10.0" 1422 | } 1423 | }, 1424 | "node_modules/resolve-from": { 1425 | "version": "4.0.0", 1426 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", 1427 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", 1428 | "dev": true, 1429 | "engines": { 1430 | "node": ">=4" 1431 | } 1432 | }, 1433 | "node_modules/rimraf": { 1434 | "version": "3.0.2", 1435 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", 1436 | "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", 1437 | "dev": true, 1438 | "dependencies": { 1439 | "glob": "^7.1.3" 1440 | }, 1441 | "bin": { 1442 | "rimraf": "bin.js" 1443 | }, 1444 | "funding": { 1445 | "url": "https://github.com/sponsors/isaacs" 1446 | } 1447 | }, 1448 | "node_modules/safe-buffer": { 1449 | "version": "5.2.1", 1450 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 1451 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 1452 | "dev": true, 1453 | "funding": [ 1454 | { 1455 | "type": "github", 1456 | "url": "https://github.com/sponsors/feross" 1457 | }, 1458 | { 1459 | "type": "patreon", 1460 | "url": "https://www.patreon.com/feross" 1461 | }, 1462 | { 1463 | "type": "consulting", 1464 | "url": "https://feross.org/support" 1465 | } 1466 | ] 1467 | }, 1468 | "node_modules/semver": { 1469 | "version": "5.7.2", 1470 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", 1471 | "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", 1472 | "bin": { 1473 | "semver": "bin/semver" 1474 | } 1475 | }, 1476 | "node_modules/serialize-javascript": { 1477 | "version": "6.0.0", 1478 | "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", 1479 | "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", 1480 | "dev": true, 1481 | "dependencies": { 1482 | "randombytes": "^2.1.0" 1483 | } 1484 | }, 1485 | "node_modules/shebang-command": { 1486 | "version": "2.0.0", 1487 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", 1488 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", 1489 | "dev": true, 1490 | "dependencies": { 1491 | "shebang-regex": "^3.0.0" 1492 | }, 1493 | "engines": { 1494 | "node": ">=8" 1495 | } 1496 | }, 1497 | "node_modules/shebang-regex": { 1498 | "version": "3.0.0", 1499 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", 1500 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", 1501 | "dev": true, 1502 | "engines": { 1503 | "node": ">=8" 1504 | } 1505 | }, 1506 | "node_modules/source-map": { 1507 | "version": "0.6.1", 1508 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 1509 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 1510 | "engines": { 1511 | "node": ">=0.10.0" 1512 | } 1513 | }, 1514 | "node_modules/string-width": { 1515 | "version": "4.2.3", 1516 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", 1517 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", 1518 | "dependencies": { 1519 | "emoji-regex": "^8.0.0", 1520 | "is-fullwidth-code-point": "^3.0.0", 1521 | "strip-ansi": "^6.0.1" 1522 | }, 1523 | "engines": { 1524 | "node": ">=8" 1525 | } 1526 | }, 1527 | "node_modules/strip-ansi": { 1528 | "version": "6.0.1", 1529 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 1530 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 1531 | "dependencies": { 1532 | "ansi-regex": "^5.0.1" 1533 | }, 1534 | "engines": { 1535 | "node": ">=8" 1536 | } 1537 | }, 1538 | "node_modules/strip-json-comments": { 1539 | "version": "3.1.1", 1540 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", 1541 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", 1542 | "dev": true, 1543 | "engines": { 1544 | "node": ">=8" 1545 | }, 1546 | "funding": { 1547 | "url": "https://github.com/sponsors/sindresorhus" 1548 | } 1549 | }, 1550 | "node_modules/supports-color": { 1551 | "version": "7.2.0", 1552 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 1553 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 1554 | "dev": true, 1555 | "dependencies": { 1556 | "has-flag": "^4.0.0" 1557 | }, 1558 | "engines": { 1559 | "node": ">=8" 1560 | } 1561 | }, 1562 | "node_modules/text-table": { 1563 | "version": "0.2.0", 1564 | "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", 1565 | "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", 1566 | "dev": true 1567 | }, 1568 | "node_modules/to-regex-range": { 1569 | "version": "5.0.1", 1570 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 1571 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 1572 | "dev": true, 1573 | "dependencies": { 1574 | "is-number": "^7.0.0" 1575 | }, 1576 | "engines": { 1577 | "node": ">=8.0" 1578 | } 1579 | }, 1580 | "node_modules/tslib": { 1581 | "version": "2.3.1", 1582 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", 1583 | "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" 1584 | }, 1585 | "node_modules/type-check": { 1586 | "version": "0.4.0", 1587 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", 1588 | "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", 1589 | "dev": true, 1590 | "dependencies": { 1591 | "prelude-ls": "^1.2.1" 1592 | }, 1593 | "engines": { 1594 | "node": ">= 0.8.0" 1595 | } 1596 | }, 1597 | "node_modules/type-detect": { 1598 | "version": "4.0.8", 1599 | "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", 1600 | "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", 1601 | "dev": true, 1602 | "engines": { 1603 | "node": ">=4" 1604 | } 1605 | }, 1606 | "node_modules/type-fest": { 1607 | "version": "0.20.2", 1608 | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", 1609 | "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", 1610 | "dev": true, 1611 | "engines": { 1612 | "node": ">=10" 1613 | }, 1614 | "funding": { 1615 | "url": "https://github.com/sponsors/sindresorhus" 1616 | } 1617 | }, 1618 | "node_modules/underscore": { 1619 | "version": "1.13.2", 1620 | "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.2.tgz", 1621 | "integrity": "sha512-ekY1NhRzq0B08g4bGuX4wd2jZx5GnKz6mKSqFL4nqBlfyMGiG10gDFhDTMEfYmDL6Jy0FUIZp7wiRB+0BP7J2g==" 1622 | }, 1623 | "node_modules/uri-js": { 1624 | "version": "4.4.1", 1625 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", 1626 | "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", 1627 | "dev": true, 1628 | "dependencies": { 1629 | "punycode": "^2.1.0" 1630 | } 1631 | }, 1632 | "node_modules/v8-compile-cache": { 1633 | "version": "2.3.0", 1634 | "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", 1635 | "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", 1636 | "dev": true 1637 | }, 1638 | "node_modules/vm2": { 1639 | "version": "3.9.19", 1640 | "resolved": "https://registry.npmjs.org/vm2/-/vm2-3.9.19.tgz", 1641 | "integrity": "sha512-J637XF0DHDMV57R6JyVsTak7nIL8gy5KH4r1HiwWLf/4GBbb5MKL5y7LpmF4A8E2nR6XmzpmMFQ7V7ppPTmUQg==", 1642 | "dependencies": { 1643 | "acorn": "^8.7.0", 1644 | "acorn-walk": "^8.2.0" 1645 | }, 1646 | "bin": { 1647 | "vm2": "bin/vm2" 1648 | }, 1649 | "engines": { 1650 | "node": ">=6.0" 1651 | } 1652 | }, 1653 | "node_modules/which": { 1654 | "version": "2.0.2", 1655 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 1656 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 1657 | "dev": true, 1658 | "dependencies": { 1659 | "isexe": "^2.0.0" 1660 | }, 1661 | "bin": { 1662 | "node-which": "bin/node-which" 1663 | }, 1664 | "engines": { 1665 | "node": ">= 8" 1666 | } 1667 | }, 1668 | "node_modules/word-wrap": { 1669 | "version": "1.2.4", 1670 | "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz", 1671 | "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==", 1672 | "dev": true, 1673 | "engines": { 1674 | "node": ">=0.10.0" 1675 | } 1676 | }, 1677 | "node_modules/workerpool": { 1678 | "version": "6.2.0", 1679 | "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", 1680 | "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", 1681 | "dev": true 1682 | }, 1683 | "node_modules/wrap-ansi": { 1684 | "version": "7.0.0", 1685 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", 1686 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", 1687 | "dependencies": { 1688 | "ansi-styles": "^4.0.0", 1689 | "string-width": "^4.1.0", 1690 | "strip-ansi": "^6.0.0" 1691 | }, 1692 | "engines": { 1693 | "node": ">=10" 1694 | }, 1695 | "funding": { 1696 | "url": "https://github.com/chalk/wrap-ansi?sponsor=1" 1697 | } 1698 | }, 1699 | "node_modules/wrappy": { 1700 | "version": "1.0.2", 1701 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1702 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 1703 | "dev": true 1704 | }, 1705 | "node_modules/y18n": { 1706 | "version": "5.0.8", 1707 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", 1708 | "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", 1709 | "engines": { 1710 | "node": ">=10" 1711 | } 1712 | }, 1713 | "node_modules/yargs": { 1714 | "version": "17.4.0", 1715 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.4.0.tgz", 1716 | "integrity": "sha512-WJudfrk81yWFSOkZYpAZx4Nt7V4xp7S/uJkX0CnxovMCt1wCE8LNftPpNuF9X/u9gN5nsD7ycYtRcDf2pL3UiA==", 1717 | "dependencies": { 1718 | "cliui": "^7.0.2", 1719 | "escalade": "^3.1.1", 1720 | "get-caller-file": "^2.0.5", 1721 | "require-directory": "^2.1.1", 1722 | "string-width": "^4.2.3", 1723 | "y18n": "^5.0.5", 1724 | "yargs-parser": "^21.0.0" 1725 | }, 1726 | "engines": { 1727 | "node": ">=12" 1728 | } 1729 | }, 1730 | "node_modules/yargs-parser": { 1731 | "version": "20.2.4", 1732 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", 1733 | "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", 1734 | "dev": true, 1735 | "engines": { 1736 | "node": ">=10" 1737 | } 1738 | }, 1739 | "node_modules/yargs-unparser": { 1740 | "version": "2.0.0", 1741 | "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", 1742 | "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", 1743 | "dev": true, 1744 | "dependencies": { 1745 | "camelcase": "^6.0.0", 1746 | "decamelize": "^4.0.0", 1747 | "flat": "^5.0.2", 1748 | "is-plain-obj": "^2.1.0" 1749 | }, 1750 | "engines": { 1751 | "node": ">=10" 1752 | } 1753 | }, 1754 | "node_modules/yargs/node_modules/yargs-parser": { 1755 | "version": "21.0.1", 1756 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz", 1757 | "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==", 1758 | "engines": { 1759 | "node": ">=12" 1760 | } 1761 | }, 1762 | "node_modules/yocto-queue": { 1763 | "version": "0.1.0", 1764 | "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", 1765 | "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", 1766 | "dev": true, 1767 | "engines": { 1768 | "node": ">=10" 1769 | }, 1770 | "funding": { 1771 | "url": "https://github.com/sponsors/sindresorhus" 1772 | } 1773 | } 1774 | }, 1775 | "dependencies": { 1776 | "@eslint/eslintrc": { 1777 | "version": "1.2.1", 1778 | "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.1.tgz", 1779 | "integrity": "sha512-bxvbYnBPN1Gibwyp6NrpnFzA3YtRL3BBAyEAFVIpNTm2Rn4Vy87GA5M4aSn3InRrlsbX5N0GW7XIx+U4SAEKdQ==", 1780 | "dev": true, 1781 | "requires": { 1782 | "ajv": "^6.12.4", 1783 | "debug": "^4.3.2", 1784 | "espree": "^9.3.1", 1785 | "globals": "^13.9.0", 1786 | "ignore": "^5.2.0", 1787 | "import-fresh": "^3.2.1", 1788 | "js-yaml": "^4.1.0", 1789 | "minimatch": "^3.0.4", 1790 | "strip-json-comments": "^3.1.1" 1791 | } 1792 | }, 1793 | "@humanwhocodes/config-array": { 1794 | "version": "0.9.5", 1795 | "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", 1796 | "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", 1797 | "dev": true, 1798 | "requires": { 1799 | "@humanwhocodes/object-schema": "^1.2.1", 1800 | "debug": "^4.1.1", 1801 | "minimatch": "^3.0.4" 1802 | } 1803 | }, 1804 | "@humanwhocodes/object-schema": { 1805 | "version": "1.2.1", 1806 | "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", 1807 | "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", 1808 | "dev": true 1809 | }, 1810 | "@openfn/doclet-query": { 1811 | "version": "0.0.3", 1812 | "resolved": "https://registry.npmjs.org/@openfn/doclet-query/-/doclet-query-0.0.3.tgz", 1813 | "integrity": "sha512-OIVVGBAIzJ3uW3TcIVWnDsQ5xUtsHqdGt/gmlKA5Ku2sPpkpyBndm/bHt1MERmdYhXL8kwDKDOLH+y09MqinKA==", 1814 | "requires": { 1815 | "lodash": "^4.13.1" 1816 | } 1817 | }, 1818 | "@ungap/promise-all-settled": { 1819 | "version": "1.1.2", 1820 | "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", 1821 | "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", 1822 | "dev": true 1823 | }, 1824 | "acorn": { 1825 | "version": "8.7.0", 1826 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", 1827 | "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==" 1828 | }, 1829 | "acorn-jsx": { 1830 | "version": "5.3.2", 1831 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", 1832 | "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", 1833 | "dev": true, 1834 | "requires": {} 1835 | }, 1836 | "acorn-walk": { 1837 | "version": "8.2.0", 1838 | "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", 1839 | "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==" 1840 | }, 1841 | "ajv": { 1842 | "version": "6.12.6", 1843 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", 1844 | "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", 1845 | "dev": true, 1846 | "requires": { 1847 | "fast-deep-equal": "^3.1.1", 1848 | "fast-json-stable-stringify": "^2.0.0", 1849 | "json-schema-traverse": "^0.4.1", 1850 | "uri-js": "^4.2.2" 1851 | } 1852 | }, 1853 | "ansi-colors": { 1854 | "version": "4.1.1", 1855 | "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", 1856 | "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", 1857 | "dev": true 1858 | }, 1859 | "ansi-regex": { 1860 | "version": "5.0.1", 1861 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 1862 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" 1863 | }, 1864 | "ansi-styles": { 1865 | "version": "4.3.0", 1866 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 1867 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 1868 | "requires": { 1869 | "color-convert": "^2.0.1" 1870 | } 1871 | }, 1872 | "anymatch": { 1873 | "version": "3.1.2", 1874 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", 1875 | "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", 1876 | "dev": true, 1877 | "requires": { 1878 | "normalize-path": "^3.0.0", 1879 | "picomatch": "^2.0.4" 1880 | } 1881 | }, 1882 | "argparse": { 1883 | "version": "2.0.1", 1884 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", 1885 | "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", 1886 | "dev": true 1887 | }, 1888 | "ast-types": { 1889 | "version": "0.14.2", 1890 | "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.14.2.tgz", 1891 | "integrity": "sha512-O0yuUDnZeQDL+ncNGlJ78BiO4jnYI3bvMsD5prT0/nsgijG/LpNBIr63gTjVTNsiGkgQhiyCShTgxt8oXOrklA==", 1892 | "requires": { 1893 | "tslib": "^2.0.1" 1894 | } 1895 | }, 1896 | "balanced-match": { 1897 | "version": "1.0.2", 1898 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 1899 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 1900 | "dev": true 1901 | }, 1902 | "binary-extensions": { 1903 | "version": "2.2.0", 1904 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", 1905 | "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", 1906 | "dev": true 1907 | }, 1908 | "brace-expansion": { 1909 | "version": "1.1.11", 1910 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 1911 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 1912 | "dev": true, 1913 | "requires": { 1914 | "balanced-match": "^1.0.0", 1915 | "concat-map": "0.0.1" 1916 | } 1917 | }, 1918 | "braces": { 1919 | "version": "3.0.3", 1920 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", 1921 | "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", 1922 | "dev": true, 1923 | "requires": { 1924 | "fill-range": "^7.1.1" 1925 | } 1926 | }, 1927 | "browser-stdout": { 1928 | "version": "1.3.1", 1929 | "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", 1930 | "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", 1931 | "dev": true 1932 | }, 1933 | "callsites": { 1934 | "version": "3.1.0", 1935 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", 1936 | "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", 1937 | "dev": true 1938 | }, 1939 | "camelcase": { 1940 | "version": "6.3.0", 1941 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", 1942 | "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", 1943 | "dev": true 1944 | }, 1945 | "chalk": { 1946 | "version": "4.1.2", 1947 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", 1948 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", 1949 | "dev": true, 1950 | "requires": { 1951 | "ansi-styles": "^4.1.0", 1952 | "supports-color": "^7.1.0" 1953 | } 1954 | }, 1955 | "chokidar": { 1956 | "version": "3.5.3", 1957 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", 1958 | "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", 1959 | "dev": true, 1960 | "requires": { 1961 | "anymatch": "~3.1.2", 1962 | "braces": "~3.0.2", 1963 | "fsevents": "~2.3.2", 1964 | "glob-parent": "~5.1.2", 1965 | "is-binary-path": "~2.1.0", 1966 | "is-glob": "~4.0.1", 1967 | "normalize-path": "~3.0.0", 1968 | "readdirp": "~3.6.0" 1969 | }, 1970 | "dependencies": { 1971 | "glob-parent": { 1972 | "version": "5.1.2", 1973 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 1974 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 1975 | "dev": true, 1976 | "requires": { 1977 | "is-glob": "^4.0.1" 1978 | } 1979 | } 1980 | } 1981 | }, 1982 | "cliui": { 1983 | "version": "7.0.4", 1984 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", 1985 | "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", 1986 | "requires": { 1987 | "string-width": "^4.2.0", 1988 | "strip-ansi": "^6.0.0", 1989 | "wrap-ansi": "^7.0.0" 1990 | } 1991 | }, 1992 | "color-convert": { 1993 | "version": "2.0.1", 1994 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 1995 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 1996 | "requires": { 1997 | "color-name": "~1.1.4" 1998 | } 1999 | }, 2000 | "color-name": { 2001 | "version": "1.1.4", 2002 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 2003 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" 2004 | }, 2005 | "concat-map": { 2006 | "version": "0.0.1", 2007 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 2008 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 2009 | "dev": true 2010 | }, 2011 | "cross-spawn": { 2012 | "version": "7.0.3", 2013 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", 2014 | "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", 2015 | "dev": true, 2016 | "requires": { 2017 | "path-key": "^3.1.0", 2018 | "shebang-command": "^2.0.0", 2019 | "which": "^2.0.1" 2020 | } 2021 | }, 2022 | "debug": { 2023 | "version": "4.3.4", 2024 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", 2025 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", 2026 | "dev": true, 2027 | "requires": { 2028 | "ms": "2.1.2" 2029 | } 2030 | }, 2031 | "decamelize": { 2032 | "version": "4.0.0", 2033 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", 2034 | "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", 2035 | "dev": true 2036 | }, 2037 | "deep-eql": { 2038 | "version": "4.0.1", 2039 | "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.0.1.tgz", 2040 | "integrity": "sha512-D/Oxqobjr+kxaHsgiQBZq9b6iAWdEj5W/JdJm8deNduAPc9CwXQ3BJJCuEqlrPXcy45iOMkGPZ0T81Dnz7UDCA==", 2041 | "dev": true, 2042 | "requires": { 2043 | "type-detect": "^4.0.0" 2044 | } 2045 | }, 2046 | "deep-is": { 2047 | "version": "0.1.4", 2048 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", 2049 | "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", 2050 | "dev": true 2051 | }, 2052 | "diff": { 2053 | "version": "5.0.0", 2054 | "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", 2055 | "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", 2056 | "dev": true 2057 | }, 2058 | "doctrine": { 2059 | "version": "3.0.0", 2060 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", 2061 | "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", 2062 | "dev": true, 2063 | "requires": { 2064 | "esutils": "^2.0.2" 2065 | } 2066 | }, 2067 | "emoji-regex": { 2068 | "version": "8.0.0", 2069 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 2070 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" 2071 | }, 2072 | "escalade": { 2073 | "version": "3.1.1", 2074 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", 2075 | "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" 2076 | }, 2077 | "escape-string-regexp": { 2078 | "version": "4.0.0", 2079 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", 2080 | "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", 2081 | "dev": true 2082 | }, 2083 | "eslint": { 2084 | "version": "8.11.0", 2085 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.11.0.tgz", 2086 | "integrity": "sha512-/KRpd9mIRg2raGxHRGwW9ZywYNAClZrHjdueHcrVDuO3a6bj83eoTirCCk0M0yPwOjWYKHwRVRid+xK4F/GHgA==", 2087 | "dev": true, 2088 | "requires": { 2089 | "@eslint/eslintrc": "^1.2.1", 2090 | "@humanwhocodes/config-array": "^0.9.2", 2091 | "ajv": "^6.10.0", 2092 | "chalk": "^4.0.0", 2093 | "cross-spawn": "^7.0.2", 2094 | "debug": "^4.3.2", 2095 | "doctrine": "^3.0.0", 2096 | "escape-string-regexp": "^4.0.0", 2097 | "eslint-scope": "^7.1.1", 2098 | "eslint-utils": "^3.0.0", 2099 | "eslint-visitor-keys": "^3.3.0", 2100 | "espree": "^9.3.1", 2101 | "esquery": "^1.4.0", 2102 | "esutils": "^2.0.2", 2103 | "fast-deep-equal": "^3.1.3", 2104 | "file-entry-cache": "^6.0.1", 2105 | "functional-red-black-tree": "^1.0.1", 2106 | "glob-parent": "^6.0.1", 2107 | "globals": "^13.6.0", 2108 | "ignore": "^5.2.0", 2109 | "import-fresh": "^3.0.0", 2110 | "imurmurhash": "^0.1.4", 2111 | "is-glob": "^4.0.0", 2112 | "js-yaml": "^4.1.0", 2113 | "json-stable-stringify-without-jsonify": "^1.0.1", 2114 | "levn": "^0.4.1", 2115 | "lodash.merge": "^4.6.2", 2116 | "minimatch": "^3.0.4", 2117 | "natural-compare": "^1.4.0", 2118 | "optionator": "^0.9.1", 2119 | "regexpp": "^3.2.0", 2120 | "strip-ansi": "^6.0.1", 2121 | "strip-json-comments": "^3.1.0", 2122 | "text-table": "^0.2.0", 2123 | "v8-compile-cache": "^2.0.3" 2124 | } 2125 | }, 2126 | "eslint-scope": { 2127 | "version": "7.1.1", 2128 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", 2129 | "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", 2130 | "dev": true, 2131 | "requires": { 2132 | "esrecurse": "^4.3.0", 2133 | "estraverse": "^5.2.0" 2134 | } 2135 | }, 2136 | "eslint-utils": { 2137 | "version": "3.0.0", 2138 | "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", 2139 | "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", 2140 | "dev": true, 2141 | "requires": { 2142 | "eslint-visitor-keys": "^2.0.0" 2143 | }, 2144 | "dependencies": { 2145 | "eslint-visitor-keys": { 2146 | "version": "2.1.0", 2147 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", 2148 | "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", 2149 | "dev": true 2150 | } 2151 | } 2152 | }, 2153 | "eslint-visitor-keys": { 2154 | "version": "3.3.0", 2155 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", 2156 | "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", 2157 | "dev": true 2158 | }, 2159 | "espree": { 2160 | "version": "9.3.1", 2161 | "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz", 2162 | "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==", 2163 | "dev": true, 2164 | "requires": { 2165 | "acorn": "^8.7.0", 2166 | "acorn-jsx": "^5.3.1", 2167 | "eslint-visitor-keys": "^3.3.0" 2168 | } 2169 | }, 2170 | "esprima": { 2171 | "version": "2.7.3", 2172 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", 2173 | "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=" 2174 | }, 2175 | "esquery": { 2176 | "version": "1.4.0", 2177 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", 2178 | "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", 2179 | "dev": true, 2180 | "requires": { 2181 | "estraverse": "^5.1.0" 2182 | } 2183 | }, 2184 | "esrecurse": { 2185 | "version": "4.3.0", 2186 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", 2187 | "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", 2188 | "dev": true, 2189 | "requires": { 2190 | "estraverse": "^5.2.0" 2191 | } 2192 | }, 2193 | "estemplate": { 2194 | "version": "0.5.1", 2195 | "resolved": "https://registry.npmjs.org/estemplate/-/estemplate-0.5.1.tgz", 2196 | "integrity": "sha1-FxSp1GGQc4rJWLyv1J4CnNpWo54=", 2197 | "requires": { 2198 | "esprima": "^2.7.2", 2199 | "estraverse": "^4.1.1" 2200 | }, 2201 | "dependencies": { 2202 | "estraverse": { 2203 | "version": "4.3.0", 2204 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", 2205 | "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" 2206 | } 2207 | } 2208 | }, 2209 | "estraverse": { 2210 | "version": "5.3.0", 2211 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", 2212 | "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", 2213 | "dev": true 2214 | }, 2215 | "esutils": { 2216 | "version": "2.0.3", 2217 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", 2218 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", 2219 | "dev": true 2220 | }, 2221 | "fast-deep-equal": { 2222 | "version": "3.1.3", 2223 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", 2224 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", 2225 | "dev": true 2226 | }, 2227 | "fast-json-stable-stringify": { 2228 | "version": "2.1.0", 2229 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 2230 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", 2231 | "dev": true 2232 | }, 2233 | "fast-levenshtein": { 2234 | "version": "2.0.6", 2235 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 2236 | "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", 2237 | "dev": true 2238 | }, 2239 | "fast-safe-stringify": { 2240 | "version": "2.1.1", 2241 | "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", 2242 | "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" 2243 | }, 2244 | "file-entry-cache": { 2245 | "version": "6.0.1", 2246 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", 2247 | "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", 2248 | "dev": true, 2249 | "requires": { 2250 | "flat-cache": "^3.0.4" 2251 | } 2252 | }, 2253 | "fill-range": { 2254 | "version": "7.1.1", 2255 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", 2256 | "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", 2257 | "dev": true, 2258 | "requires": { 2259 | "to-regex-range": "^5.0.1" 2260 | } 2261 | }, 2262 | "find-up": { 2263 | "version": "5.0.0", 2264 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", 2265 | "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", 2266 | "dev": true, 2267 | "requires": { 2268 | "locate-path": "^6.0.0", 2269 | "path-exists": "^4.0.0" 2270 | } 2271 | }, 2272 | "flat": { 2273 | "version": "5.0.2", 2274 | "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", 2275 | "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", 2276 | "dev": true 2277 | }, 2278 | "flat-cache": { 2279 | "version": "3.0.4", 2280 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", 2281 | "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", 2282 | "dev": true, 2283 | "requires": { 2284 | "flatted": "^3.1.0", 2285 | "rimraf": "^3.0.2" 2286 | } 2287 | }, 2288 | "flatted": { 2289 | "version": "3.2.5", 2290 | "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", 2291 | "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", 2292 | "dev": true 2293 | }, 2294 | "fs.realpath": { 2295 | "version": "1.0.0", 2296 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 2297 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 2298 | "dev": true 2299 | }, 2300 | "fsevents": { 2301 | "version": "2.3.2", 2302 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 2303 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 2304 | "dev": true, 2305 | "optional": true 2306 | }, 2307 | "functional-red-black-tree": { 2308 | "version": "1.0.1", 2309 | "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", 2310 | "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", 2311 | "dev": true 2312 | }, 2313 | "get-caller-file": { 2314 | "version": "2.0.5", 2315 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", 2316 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" 2317 | }, 2318 | "glob": { 2319 | "version": "7.2.0", 2320 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", 2321 | "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", 2322 | "dev": true, 2323 | "requires": { 2324 | "fs.realpath": "^1.0.0", 2325 | "inflight": "^1.0.4", 2326 | "inherits": "2", 2327 | "minimatch": "^3.0.4", 2328 | "once": "^1.3.0", 2329 | "path-is-absolute": "^1.0.0" 2330 | } 2331 | }, 2332 | "glob-parent": { 2333 | "version": "6.0.2", 2334 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", 2335 | "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", 2336 | "dev": true, 2337 | "requires": { 2338 | "is-glob": "^4.0.3" 2339 | } 2340 | }, 2341 | "globals": { 2342 | "version": "13.13.0", 2343 | "resolved": "https://registry.npmjs.org/globals/-/globals-13.13.0.tgz", 2344 | "integrity": "sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A==", 2345 | "dev": true, 2346 | "requires": { 2347 | "type-fest": "^0.20.2" 2348 | } 2349 | }, 2350 | "growl": { 2351 | "version": "1.10.5", 2352 | "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", 2353 | "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", 2354 | "dev": true 2355 | }, 2356 | "has-flag": { 2357 | "version": "4.0.0", 2358 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 2359 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 2360 | "dev": true 2361 | }, 2362 | "he": { 2363 | "version": "1.2.0", 2364 | "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", 2365 | "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", 2366 | "dev": true 2367 | }, 2368 | "ignore": { 2369 | "version": "5.2.0", 2370 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", 2371 | "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", 2372 | "dev": true 2373 | }, 2374 | "import-fresh": { 2375 | "version": "3.3.0", 2376 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", 2377 | "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", 2378 | "dev": true, 2379 | "requires": { 2380 | "parent-module": "^1.0.0", 2381 | "resolve-from": "^4.0.0" 2382 | } 2383 | }, 2384 | "imurmurhash": { 2385 | "version": "0.1.4", 2386 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 2387 | "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", 2388 | "dev": true 2389 | }, 2390 | "inflight": { 2391 | "version": "1.0.6", 2392 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 2393 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 2394 | "dev": true, 2395 | "requires": { 2396 | "once": "^1.3.0", 2397 | "wrappy": "1" 2398 | } 2399 | }, 2400 | "inherits": { 2401 | "version": "2.0.4", 2402 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 2403 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 2404 | "dev": true 2405 | }, 2406 | "is-binary-path": { 2407 | "version": "2.1.0", 2408 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", 2409 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", 2410 | "dev": true, 2411 | "requires": { 2412 | "binary-extensions": "^2.0.0" 2413 | } 2414 | }, 2415 | "is-extglob": { 2416 | "version": "2.1.1", 2417 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 2418 | "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", 2419 | "dev": true 2420 | }, 2421 | "is-fullwidth-code-point": { 2422 | "version": "3.0.0", 2423 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 2424 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" 2425 | }, 2426 | "is-glob": { 2427 | "version": "4.0.3", 2428 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 2429 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 2430 | "dev": true, 2431 | "requires": { 2432 | "is-extglob": "^2.1.1" 2433 | } 2434 | }, 2435 | "is-number": { 2436 | "version": "7.0.0", 2437 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 2438 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 2439 | "dev": true 2440 | }, 2441 | "is-plain-obj": { 2442 | "version": "2.1.0", 2443 | "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", 2444 | "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", 2445 | "dev": true 2446 | }, 2447 | "is-unicode-supported": { 2448 | "version": "0.1.0", 2449 | "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", 2450 | "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", 2451 | "dev": true 2452 | }, 2453 | "isexe": { 2454 | "version": "2.0.0", 2455 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 2456 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", 2457 | "dev": true 2458 | }, 2459 | "js-yaml": { 2460 | "version": "4.1.0", 2461 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", 2462 | "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", 2463 | "dev": true, 2464 | "requires": { 2465 | "argparse": "^2.0.1" 2466 | } 2467 | }, 2468 | "json-schema-traverse": { 2469 | "version": "0.4.1", 2470 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 2471 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", 2472 | "dev": true 2473 | }, 2474 | "json-stable-stringify-without-jsonify": { 2475 | "version": "1.0.1", 2476 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", 2477 | "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", 2478 | "dev": true 2479 | }, 2480 | "levn": { 2481 | "version": "0.4.1", 2482 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", 2483 | "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", 2484 | "dev": true, 2485 | "requires": { 2486 | "prelude-ls": "^1.2.1", 2487 | "type-check": "~0.4.0" 2488 | } 2489 | }, 2490 | "locate-path": { 2491 | "version": "6.0.0", 2492 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", 2493 | "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", 2494 | "dev": true, 2495 | "requires": { 2496 | "p-locate": "^5.0.0" 2497 | } 2498 | }, 2499 | "lodash": { 2500 | "version": "4.17.21", 2501 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", 2502 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" 2503 | }, 2504 | "lodash.merge": { 2505 | "version": "4.6.2", 2506 | "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", 2507 | "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", 2508 | "dev": true 2509 | }, 2510 | "log-symbols": { 2511 | "version": "4.1.0", 2512 | "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", 2513 | "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", 2514 | "dev": true, 2515 | "requires": { 2516 | "chalk": "^4.1.0", 2517 | "is-unicode-supported": "^0.1.0" 2518 | } 2519 | }, 2520 | "minimatch": { 2521 | "version": "3.1.2", 2522 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 2523 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 2524 | "dev": true, 2525 | "requires": { 2526 | "brace-expansion": "^1.1.7" 2527 | } 2528 | }, 2529 | "mitm": { 2530 | "version": "1.7.2", 2531 | "resolved": "https://registry.npmjs.org/mitm/-/mitm-1.7.2.tgz", 2532 | "integrity": "sha512-SuiJbc5xisP/iUYvsKAvrvPeoyJQbYI3WOfnp8A7XHDn4wkdtmGZe2ZTFXIo3K1of05oxUiaJIK+GoAU5KgFOw==", 2533 | "requires": { 2534 | "semver": ">= 5 < 6", 2535 | "underscore": ">= 1.1.6 < 1.14" 2536 | } 2537 | }, 2538 | "mocha": { 2539 | "version": "9.2.2", 2540 | "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz", 2541 | "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==", 2542 | "dev": true, 2543 | "requires": { 2544 | "@ungap/promise-all-settled": "1.1.2", 2545 | "ansi-colors": "4.1.1", 2546 | "browser-stdout": "1.3.1", 2547 | "chokidar": "3.5.3", 2548 | "debug": "4.3.3", 2549 | "diff": "5.0.0", 2550 | "escape-string-regexp": "4.0.0", 2551 | "find-up": "5.0.0", 2552 | "glob": "7.2.0", 2553 | "growl": "1.10.5", 2554 | "he": "1.2.0", 2555 | "js-yaml": "4.1.0", 2556 | "log-symbols": "4.1.0", 2557 | "minimatch": "4.2.1", 2558 | "ms": "2.1.3", 2559 | "nanoid": "3.3.1", 2560 | "serialize-javascript": "6.0.0", 2561 | "strip-json-comments": "3.1.1", 2562 | "supports-color": "8.1.1", 2563 | "which": "2.0.2", 2564 | "workerpool": "6.2.0", 2565 | "yargs": "16.2.0", 2566 | "yargs-parser": "20.2.4", 2567 | "yargs-unparser": "2.0.0" 2568 | }, 2569 | "dependencies": { 2570 | "debug": { 2571 | "version": "4.3.3", 2572 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", 2573 | "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", 2574 | "dev": true, 2575 | "requires": { 2576 | "ms": "2.1.2" 2577 | }, 2578 | "dependencies": { 2579 | "ms": { 2580 | "version": "2.1.2", 2581 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 2582 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 2583 | "dev": true 2584 | } 2585 | } 2586 | }, 2587 | "minimatch": { 2588 | "version": "4.2.1", 2589 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", 2590 | "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==", 2591 | "dev": true, 2592 | "requires": { 2593 | "brace-expansion": "^1.1.7" 2594 | } 2595 | }, 2596 | "ms": { 2597 | "version": "2.1.3", 2598 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 2599 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 2600 | "dev": true 2601 | }, 2602 | "supports-color": { 2603 | "version": "8.1.1", 2604 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", 2605 | "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", 2606 | "dev": true, 2607 | "requires": { 2608 | "has-flag": "^4.0.0" 2609 | } 2610 | }, 2611 | "yargs": { 2612 | "version": "16.2.0", 2613 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", 2614 | "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", 2615 | "dev": true, 2616 | "requires": { 2617 | "cliui": "^7.0.2", 2618 | "escalade": "^3.1.1", 2619 | "get-caller-file": "^2.0.5", 2620 | "require-directory": "^2.1.1", 2621 | "string-width": "^4.2.0", 2622 | "y18n": "^5.0.5", 2623 | "yargs-parser": "^20.2.2" 2624 | } 2625 | } 2626 | } 2627 | }, 2628 | "ms": { 2629 | "version": "2.1.2", 2630 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 2631 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 2632 | "dev": true 2633 | }, 2634 | "nanoid": { 2635 | "version": "3.3.1", 2636 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", 2637 | "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", 2638 | "dev": true 2639 | }, 2640 | "natural-compare": { 2641 | "version": "1.4.0", 2642 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", 2643 | "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", 2644 | "dev": true 2645 | }, 2646 | "normalize-path": { 2647 | "version": "3.0.0", 2648 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", 2649 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", 2650 | "dev": true 2651 | }, 2652 | "once": { 2653 | "version": "1.4.0", 2654 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 2655 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 2656 | "dev": true, 2657 | "requires": { 2658 | "wrappy": "1" 2659 | } 2660 | }, 2661 | "optionator": { 2662 | "version": "0.9.1", 2663 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", 2664 | "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", 2665 | "dev": true, 2666 | "requires": { 2667 | "deep-is": "^0.1.3", 2668 | "fast-levenshtein": "^2.0.6", 2669 | "levn": "^0.4.1", 2670 | "prelude-ls": "^1.2.1", 2671 | "type-check": "^0.4.0", 2672 | "word-wrap": "^1.2.3" 2673 | } 2674 | }, 2675 | "p-limit": { 2676 | "version": "3.1.0", 2677 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", 2678 | "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", 2679 | "dev": true, 2680 | "requires": { 2681 | "yocto-queue": "^0.1.0" 2682 | } 2683 | }, 2684 | "p-locate": { 2685 | "version": "5.0.0", 2686 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", 2687 | "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", 2688 | "dev": true, 2689 | "requires": { 2690 | "p-limit": "^3.0.2" 2691 | } 2692 | }, 2693 | "parent-module": { 2694 | "version": "1.0.1", 2695 | "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", 2696 | "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", 2697 | "dev": true, 2698 | "requires": { 2699 | "callsites": "^3.0.0" 2700 | } 2701 | }, 2702 | "path-exists": { 2703 | "version": "4.0.0", 2704 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", 2705 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", 2706 | "dev": true 2707 | }, 2708 | "path-is-absolute": { 2709 | "version": "1.0.1", 2710 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 2711 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 2712 | "dev": true 2713 | }, 2714 | "path-key": { 2715 | "version": "3.1.1", 2716 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", 2717 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", 2718 | "dev": true 2719 | }, 2720 | "picomatch": { 2721 | "version": "2.3.1", 2722 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 2723 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", 2724 | "dev": true 2725 | }, 2726 | "prelude-ls": { 2727 | "version": "1.2.1", 2728 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", 2729 | "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", 2730 | "dev": true 2731 | }, 2732 | "prettier": { 2733 | "version": "2.6.1", 2734 | "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.1.tgz", 2735 | "integrity": "sha512-8UVbTBYGwN37Bs9LERmxCPjdvPxlEowx2urIL6urHzdb3SDq4B/Z6xLFCblrSnE4iKWcS6ziJ3aOYrc1kz/E2A==", 2736 | "dev": true 2737 | }, 2738 | "punycode": { 2739 | "version": "2.1.1", 2740 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", 2741 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", 2742 | "dev": true 2743 | }, 2744 | "randombytes": { 2745 | "version": "2.1.0", 2746 | "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", 2747 | "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", 2748 | "dev": true, 2749 | "requires": { 2750 | "safe-buffer": "^5.1.0" 2751 | } 2752 | }, 2753 | "readdirp": { 2754 | "version": "3.6.0", 2755 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", 2756 | "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", 2757 | "dev": true, 2758 | "requires": { 2759 | "picomatch": "^2.2.1" 2760 | } 2761 | }, 2762 | "recast": { 2763 | "version": "0.20.5", 2764 | "resolved": "https://registry.npmjs.org/recast/-/recast-0.20.5.tgz", 2765 | "integrity": "sha512-E5qICoPoNL4yU0H0NoBDntNB0Q5oMSNh9usFctYniLBluTthi3RsQVBXIJNbApOlvSwW/RGxIuokPcAc59J5fQ==", 2766 | "requires": { 2767 | "ast-types": "0.14.2", 2768 | "esprima": "~4.0.0", 2769 | "source-map": "~0.6.1", 2770 | "tslib": "^2.0.1" 2771 | }, 2772 | "dependencies": { 2773 | "esprima": { 2774 | "version": "4.0.1", 2775 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", 2776 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" 2777 | } 2778 | } 2779 | }, 2780 | "regexpp": { 2781 | "version": "3.2.0", 2782 | "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", 2783 | "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", 2784 | "dev": true 2785 | }, 2786 | "require-directory": { 2787 | "version": "2.1.1", 2788 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", 2789 | "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" 2790 | }, 2791 | "resolve-from": { 2792 | "version": "4.0.0", 2793 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", 2794 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", 2795 | "dev": true 2796 | }, 2797 | "rimraf": { 2798 | "version": "3.0.2", 2799 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", 2800 | "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", 2801 | "dev": true, 2802 | "requires": { 2803 | "glob": "^7.1.3" 2804 | } 2805 | }, 2806 | "safe-buffer": { 2807 | "version": "5.2.1", 2808 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 2809 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 2810 | "dev": true 2811 | }, 2812 | "semver": { 2813 | "version": "5.7.2", 2814 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", 2815 | "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==" 2816 | }, 2817 | "serialize-javascript": { 2818 | "version": "6.0.0", 2819 | "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", 2820 | "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", 2821 | "dev": true, 2822 | "requires": { 2823 | "randombytes": "^2.1.0" 2824 | } 2825 | }, 2826 | "shebang-command": { 2827 | "version": "2.0.0", 2828 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", 2829 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", 2830 | "dev": true, 2831 | "requires": { 2832 | "shebang-regex": "^3.0.0" 2833 | } 2834 | }, 2835 | "shebang-regex": { 2836 | "version": "3.0.0", 2837 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", 2838 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", 2839 | "dev": true 2840 | }, 2841 | "source-map": { 2842 | "version": "0.6.1", 2843 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 2844 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" 2845 | }, 2846 | "string-width": { 2847 | "version": "4.2.3", 2848 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", 2849 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", 2850 | "requires": { 2851 | "emoji-regex": "^8.0.0", 2852 | "is-fullwidth-code-point": "^3.0.0", 2853 | "strip-ansi": "^6.0.1" 2854 | } 2855 | }, 2856 | "strip-ansi": { 2857 | "version": "6.0.1", 2858 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 2859 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 2860 | "requires": { 2861 | "ansi-regex": "^5.0.1" 2862 | } 2863 | }, 2864 | "strip-json-comments": { 2865 | "version": "3.1.1", 2866 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", 2867 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", 2868 | "dev": true 2869 | }, 2870 | "supports-color": { 2871 | "version": "7.2.0", 2872 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 2873 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 2874 | "dev": true, 2875 | "requires": { 2876 | "has-flag": "^4.0.0" 2877 | } 2878 | }, 2879 | "text-table": { 2880 | "version": "0.2.0", 2881 | "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", 2882 | "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", 2883 | "dev": true 2884 | }, 2885 | "to-regex-range": { 2886 | "version": "5.0.1", 2887 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 2888 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 2889 | "dev": true, 2890 | "requires": { 2891 | "is-number": "^7.0.0" 2892 | } 2893 | }, 2894 | "tslib": { 2895 | "version": "2.3.1", 2896 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", 2897 | "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" 2898 | }, 2899 | "type-check": { 2900 | "version": "0.4.0", 2901 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", 2902 | "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", 2903 | "dev": true, 2904 | "requires": { 2905 | "prelude-ls": "^1.2.1" 2906 | } 2907 | }, 2908 | "type-detect": { 2909 | "version": "4.0.8", 2910 | "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", 2911 | "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", 2912 | "dev": true 2913 | }, 2914 | "type-fest": { 2915 | "version": "0.20.2", 2916 | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", 2917 | "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", 2918 | "dev": true 2919 | }, 2920 | "underscore": { 2921 | "version": "1.13.2", 2922 | "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.2.tgz", 2923 | "integrity": "sha512-ekY1NhRzq0B08g4bGuX4wd2jZx5GnKz6mKSqFL4nqBlfyMGiG10gDFhDTMEfYmDL6Jy0FUIZp7wiRB+0BP7J2g==" 2924 | }, 2925 | "uri-js": { 2926 | "version": "4.4.1", 2927 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", 2928 | "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", 2929 | "dev": true, 2930 | "requires": { 2931 | "punycode": "^2.1.0" 2932 | } 2933 | }, 2934 | "v8-compile-cache": { 2935 | "version": "2.3.0", 2936 | "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", 2937 | "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", 2938 | "dev": true 2939 | }, 2940 | "vm2": { 2941 | "version": "3.9.19", 2942 | "resolved": "https://registry.npmjs.org/vm2/-/vm2-3.9.19.tgz", 2943 | "integrity": "sha512-J637XF0DHDMV57R6JyVsTak7nIL8gy5KH4r1HiwWLf/4GBbb5MKL5y7LpmF4A8E2nR6XmzpmMFQ7V7ppPTmUQg==", 2944 | "requires": { 2945 | "acorn": "^8.7.0", 2946 | "acorn-walk": "^8.2.0" 2947 | } 2948 | }, 2949 | "which": { 2950 | "version": "2.0.2", 2951 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 2952 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 2953 | "dev": true, 2954 | "requires": { 2955 | "isexe": "^2.0.0" 2956 | } 2957 | }, 2958 | "word-wrap": { 2959 | "version": "1.2.4", 2960 | "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz", 2961 | "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==", 2962 | "dev": true 2963 | }, 2964 | "workerpool": { 2965 | "version": "6.2.0", 2966 | "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", 2967 | "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", 2968 | "dev": true 2969 | }, 2970 | "wrap-ansi": { 2971 | "version": "7.0.0", 2972 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", 2973 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", 2974 | "requires": { 2975 | "ansi-styles": "^4.0.0", 2976 | "string-width": "^4.1.0", 2977 | "strip-ansi": "^6.0.0" 2978 | } 2979 | }, 2980 | "wrappy": { 2981 | "version": "1.0.2", 2982 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 2983 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 2984 | "dev": true 2985 | }, 2986 | "y18n": { 2987 | "version": "5.0.8", 2988 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", 2989 | "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" 2990 | }, 2991 | "yargs": { 2992 | "version": "17.4.0", 2993 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.4.0.tgz", 2994 | "integrity": "sha512-WJudfrk81yWFSOkZYpAZx4Nt7V4xp7S/uJkX0CnxovMCt1wCE8LNftPpNuF9X/u9gN5nsD7ycYtRcDf2pL3UiA==", 2995 | "requires": { 2996 | "cliui": "^7.0.2", 2997 | "escalade": "^3.1.1", 2998 | "get-caller-file": "^2.0.5", 2999 | "require-directory": "^2.1.1", 3000 | "string-width": "^4.2.3", 3001 | "y18n": "^5.0.5", 3002 | "yargs-parser": "^21.0.0" 3003 | }, 3004 | "dependencies": { 3005 | "yargs-parser": { 3006 | "version": "21.0.1", 3007 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz", 3008 | "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==" 3009 | } 3010 | } 3011 | }, 3012 | "yargs-parser": { 3013 | "version": "20.2.4", 3014 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", 3015 | "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", 3016 | "dev": true 3017 | }, 3018 | "yargs-unparser": { 3019 | "version": "2.0.0", 3020 | "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", 3021 | "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", 3022 | "dev": true, 3023 | "requires": { 3024 | "camelcase": "^6.0.0", 3025 | "decamelize": "^4.0.0", 3026 | "flat": "^5.0.2", 3027 | "is-plain-obj": "^2.1.0" 3028 | } 3029 | }, 3030 | "yocto-queue": { 3031 | "version": "0.1.0", 3032 | "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", 3033 | "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", 3034 | "dev": true 3035 | } 3036 | } 3037 | } 3038 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@openfn/core", 3 | "version": "1.5.1", 4 | "description": "The central job processing program used by OpenFn integration tools.", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/openfn/core.git" 8 | }, 9 | "main": "./lib/index.js", 10 | "bin": { 11 | "core": "./bin/core" 12 | }, 13 | "scripts": { 14 | "test": "mocha --recursive", 15 | "test:watch": "mocha -w --recursive" 16 | }, 17 | "files": [ 18 | "lib/", 19 | "bin/" 20 | ], 21 | "author": "Open Function Group", 22 | "license": "LGPL-3.0", 23 | "dependencies": { 24 | "@openfn/doclet-query": "^0.0.3", 25 | "acorn": "^8.0.5", 26 | "ast-types": "^0.14.2", 27 | "estemplate": "^0.5.1", 28 | "fast-safe-stringify": "^2.0.7", 29 | "mitm": "^1.3.2", 30 | "recast": "0.20.5", 31 | "vm2": "3.9.19", 32 | "yargs": "^17.4.0" 33 | }, 34 | "engines": { 35 | "node": ">= 12.17.0" 36 | }, 37 | "devDependencies": { 38 | "deep-eql": "4.0.1", 39 | "eslint": ">=4.18.2", 40 | "mocha": "^9.2.2", 41 | "prettier": "^2.2.1" 42 | }, 43 | "bugs": { 44 | "url": "https://github.com/OpenFn/core/issues" 45 | }, 46 | "homepage": "https://github.com/OpenFn/core#readme" 47 | } 48 | -------------------------------------------------------------------------------- /test/compile/index.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | const Compile = require('../../lib/compile'); 3 | const { 4 | verify, 5 | wrapRootExpressions, 6 | callFunction, 7 | wrapIIFE, 8 | banClasses, 9 | } = require('../../lib/compile/transforms'); 10 | 11 | describe('Compile', () => { 12 | it("throws an error when a transform doesn't return the ast", () => { 13 | assert.throws(() => { 14 | new Compile('', [function () {}]); 15 | }, /A transform unexpectedly returned undefined/); 16 | }); 17 | }); 18 | 19 | describe('Transforms', () => { 20 | function assertCodeEqual(compile, expected) { 21 | return assert.equal(compile.toString(), expected); 22 | } 23 | 24 | describe('verify', () => { 25 | it('checks the scope of all call expressions', () => { 26 | let result; 27 | 28 | result = new Compile(`noExist()`, [verify({ sandbox: {} })]); 29 | assert(result.errors.length > 0); 30 | 31 | result = new Compile(`exist()`, [verify({ sandbox: { exist: null } })]); 32 | assert(result.errors.length == 0); 33 | }); 34 | 35 | it('returns the code unmodified', () => { 36 | result = new Compile(`foo()`, [verify({ sandbox: { foo: null } })]); 37 | assertCodeEqual(result, 'foo()'); 38 | }); 39 | 40 | it('specifies missing functions', () => { 41 | result = new Compile(`noExist()`, [verify({ sandbox: {} })]); 42 | assert(result.errors.length > 0); 43 | assert(result.errors[0].message == 'Function not available.'); 44 | }); 45 | }); 46 | 47 | describe('wrapRootExpresssions', () => { 48 | it('wraps all root expressions in a function', () => { 49 | result = new Compile(`foo();bar();baz();`, [ 50 | wrapRootExpressions('execute'), 51 | ]); 52 | assertCodeEqual(result, 'execute(foo(), bar(), baz());'); 53 | }); 54 | 55 | it("won't break if the last character is a space", () => { 56 | const code = `each() `; 57 | result = new Compile(code, [wrapRootExpressions('execute')]); 58 | assertCodeEqual(result, 'execute(each());'); 59 | }); 60 | }); 61 | 62 | describe('callFunction', () => { 63 | it('calls callExpression with indentifer', () => { 64 | result = new Compile(`execute(foo(), bar(), baz())`, [ 65 | callFunction('execute', 'state'), 66 | ]); 67 | assertCodeEqual(result, 'execute(foo(), bar(), baz())(state)'); 68 | }); 69 | }); 70 | 71 | describe('wrapIIFE', () => { 72 | it('wraps the body in an IIFE', () => { 73 | result = new Compile(`execute(foo(), bar(), baz())`, [wrapIIFE()]); 74 | assertCodeEqual( 75 | result, 76 | [ 77 | '(function() {', 78 | ' return execute(foo(), bar(), baz());', 79 | '})();', 80 | ].join('\n') 81 | ); 82 | }); 83 | }); 84 | 85 | describe('banClasses', () => { 86 | it('throws an error if a class statement is detected', () => { 87 | assert.throws(() => { 88 | new Compile('class Naughty {}', [banClasses()]); 89 | }, /Illegal class statement/); 90 | }); 91 | }); 92 | }); 93 | -------------------------------------------------------------------------------- /test/execute.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | const Execute = require('../lib/execute'); 3 | 4 | describe('Execute', () => { 5 | it('expects an expression', () => { 6 | assert.throws(() => { 7 | Execute({}); 8 | }, /Cannot execute without an expression./); 9 | }); 10 | 11 | it('expects an initial state', () => { 12 | assert.throws(() => { 13 | Execute({ expression: 'foo' }); 14 | }, /Cannot execute without an initial state./); 15 | }); 16 | 17 | describe('when given an expression and state', () => { 18 | it('returns', () => { 19 | let result = Execute({ 20 | expression: `add(1)(state)`, 21 | state: 1, 22 | sandbox: { 23 | add: num => state => { 24 | return state + num; 25 | }, 26 | }, 27 | }); 28 | assert.equal(result, 2); 29 | }); 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | 3 | it('should complete this test', function () { 4 | return new Promise(function (resolve) { 5 | assert.ok(true); 6 | resolve(); 7 | }) 8 | }); 9 | -------------------------------------------------------------------------------- /test/security.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | const Execute = require('../lib/execute'); 3 | const Compile = require('../lib/compile'); 4 | const { defaultTransforms } = require('../lib/compile/transforms') 5 | 6 | describe('security', () => { 7 | it('should allow access to the console object', () => { 8 | const result = Execute({ 9 | expression: 'fn(() => { console.log(">> jam"); return 1 });', 10 | state: {}, 11 | sandbox: { 12 | fn: f => f(), 13 | }, 14 | }); 15 | assert.equal(result, 1); 16 | }); 17 | 18 | it('should not allow access to the process object', () => { 19 | assert.throws( 20 | () => Execute({ expression: 'process.env', state: {} }), 21 | /process is not defined/ 22 | ); 23 | }); 24 | 25 | it('should not allow access to require', () => { 26 | assert.throws( 27 | () => Execute({ expression: 'require("node:fs")', state: {} }), 28 | /require is not defined/ 29 | ); 30 | }); 31 | 32 | it('should not compile a job with a class', () => { 33 | const code = `fn(() => { 34 | class Naughty {} 35 | })` 36 | assert.throws(() => { 37 | new Compile(code, [ 38 | ...defaultTransforms, 39 | ]); 40 | }, /Illegal class statement/); 41 | }) 42 | }); 43 | -------------------------------------------------------------------------------- /test/utils.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | const { 3 | writeJSON, 4 | readFile, 5 | formatCompileError, 6 | } = require('../lib/utils'); 7 | 8 | describe('Utils', () => { 9 | it('.writeJSON', () => { 10 | return writeJSON('/tmp/output.json', { a: 1 }) 11 | .then(() => readFile('/tmp/output.json')) 12 | .then(str => assert.deepStrictEqual({ a: 1 }, JSON.parse(str))); 13 | }); 14 | 15 | it('.formatCompileError', () => { 16 | let expected = ['Line 1: foo()', ' ^^^^^', 'Bad!'].join('\n'); 17 | 18 | let result = formatCompileError('foo()', { 19 | node: { 20 | loc: { start: { line: 1, column: 0 }, end: { line: 1, column: 5 } }, 21 | }, 22 | message: 'Bad!', 23 | }); 24 | 25 | assert.strictEqual(expected, result); 26 | }); 27 | }); 28 | --------------------------------------------------------------------------------