dev-api: add developer portal, OpenAPI spec, and Flatenbadet case study

- New /developers/ page with API docs, SDKs, pricing, use cases
- OpenAPI 3.0 spec for Orders, Missions, Photos, Analytics
- Case study: Glasskiosken i Flatenbadet — complete ROI analysis
- Updated /order/ with recurring missions and frequency dropdown
This commit is contained in:
Bernt
2026-07-14 15:27:33 +00:00
parent 3c522e39f0
commit 1a12fb870b
6296 changed files with 911440 additions and 55607 deletions
+1530
View File
@@ -0,0 +1,1530 @@
# Vitest core license
Vitest is released under the MIT license:
MIT License
Copyright (c) 2021-Present Vitest Team
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
# Licenses of bundled dependencies
The published Vitest artifact additionally contains code with the following licenses:
Apache-2.0, BSD-3-Clause, ISC, MIT
# Bundled dependencies:
## @antfu/install-pkg
License: MIT
By: Anthony Fu
Repository: git+https://github.com/antfu/install-pkg.git
> MIT License
>
> Copyright (c) 2021 Anthony Fu <https://github.com/antfu>
>
> Permission is hereby granted, free of charge, to any person obtaining a copy
> of this software and associated documentation files (the "Software"), to deal
> in the Software without restriction, including without limitation the rights
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> copies of the Software, and to permit persons to whom the Software is
> furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in all
> copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
> SOFTWARE.
---------------------------------------
## @nodelib/fs.scandir
License: MIT
Repository: https://github.com/nodelib/nodelib/tree/master/packages/fs/fs.scandir
> The MIT License (MIT)
>
> Copyright (c) Denis Malinochkin
>
> Permission is hereby granted, free of charge, to any person obtaining a copy
> of this software and associated documentation files (the "Software"), to deal
> in the Software without restriction, including without limitation the rights
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> copies of the Software, and to permit persons to whom the Software is
> furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in all
> copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
> SOFTWARE.
---------------------------------------
## @nodelib/fs.stat
License: MIT
Repository: https://github.com/nodelib/nodelib/tree/master/packages/fs/fs.stat
> The MIT License (MIT)
>
> Copyright (c) Denis Malinochkin
>
> Permission is hereby granted, free of charge, to any person obtaining a copy
> of this software and associated documentation files (the "Software"), to deal
> in the Software without restriction, including without limitation the rights
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> copies of the Software, and to permit persons to whom the Software is
> furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in all
> copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
> SOFTWARE.
---------------------------------------
## @nodelib/fs.walk
License: MIT
Repository: https://github.com/nodelib/nodelib/tree/master/packages/fs/fs.walk
> The MIT License (MIT)
>
> Copyright (c) Denis Malinochkin
>
> Permission is hereby granted, free of charge, to any person obtaining a copy
> of this software and associated documentation files (the "Software"), to deal
> in the Software without restriction, including without limitation the rights
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> copies of the Software, and to permit persons to whom the Software is
> furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in all
> copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
> SOFTWARE.
---------------------------------------
## @sinonjs/commons
License: BSD-3-Clause
Repository: git+https://github.com/sinonjs/commons.git
> BSD 3-Clause License
>
> Copyright (c) 2018, Sinon.JS
> All rights reserved.
>
> Redistribution and use in source and binary forms, with or without
> modification, are permitted provided that the following conditions are met:
>
> * Redistributions of source code must retain the above copyright notice, this
> list of conditions and the following disclaimer.
>
> * Redistributions in binary form must reproduce the above copyright notice,
> this list of conditions and the following disclaimer in the documentation
> and/or other materials provided with the distribution.
>
> * Neither the name of the copyright holder nor the names of its
> contributors may be used to endorse or promote products derived from
> this software without specific prior written permission.
>
> THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
> AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
> FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
> DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
> SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
> CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
> OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------
## @sinonjs/fake-timers
License: BSD-3-Clause
By: Christian Johansen
Repository: https://github.com/sinonjs/fake-timers.git
> Copyright (c) 2010-2014, Christian Johansen, christian@cjohansen.no. All rights reserved.
>
> Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
>
> 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
>
> 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
>
> 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
>
> THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------
## ansi-escapes
License: MIT
By: Sindre Sorhus
Repository: sindresorhus/ansi-escapes
> MIT License
>
> Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
>
> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------
## ansi-regex
License: MIT
By: Sindre Sorhus
Repository: chalk/ansi-regex
> MIT License
>
> Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
>
> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------
## ansi-styles
License: MIT
By: Sindre Sorhus
Repository: chalk/ansi-styles
> MIT License
>
> Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
>
> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------
## birpc
License: MIT
By: Anthony Fu
Repository: git+https://github.com/antfu/birpc.git
> MIT License
>
> Copyright (c) 2021 Anthony Fu <https://github.com/antfu>
>
> Permission is hereby granted, free of charge, to any person obtaining a copy
> of this software and associated documentation files (the "Software"), to deal
> in the Software without restriction, including without limitation the rights
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> copies of the Software, and to permit persons to whom the Software is
> furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in all
> copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
> SOFTWARE.
---------------------------------------
## braces
License: MIT
By: Jon Schlinkert, Brian Woodward, Elan Shanker, Eugene Sharygin, hemanth.hm
Repository: micromatch/braces
> The MIT License (MIT)
>
> Copyright (c) 2014-2018, Jon Schlinkert.
>
> Permission is hereby granted, free of charge, to any person obtaining a copy
> of this software and associated documentation files (the "Software"), to deal
> in the Software without restriction, including without limitation the rights
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> copies of the Software, and to permit persons to whom the Software is
> furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in
> all copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> THE SOFTWARE.
---------------------------------------
## cac
License: MIT
By: egoist
Repository: egoist/cac
> The MIT License (MIT)
>
> Copyright (c) EGOIST <0x142857@gmail.com> (https://github.com/egoist)
>
> Permission is hereby granted, free of charge, to any person obtaining a copy
> of this software and associated documentation files (the "Software"), to deal
> in the Software without restriction, including without limitation the rights
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> copies of the Software, and to permit persons to whom the Software is
> furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in
> all copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> THE SOFTWARE.
---------------------------------------
## chai-subset
License: MIT
By: Andrii Shumada, Robert Herhold
Repository: https://github.com/debitoor/chai-subset.git
> The MIT License (MIT)
>
> Copyright (c) 2014
>
> Permission is hereby granted, free of charge, to any person obtaining a copy
> of this software and associated documentation files (the "Software"), to deal
> in the Software without restriction, including without limitation the rights
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> copies of the Software, and to permit persons to whom the Software is
> furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in all
> copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
> SOFTWARE.
---------------------------------------
## cli-cursor
License: MIT
By: Sindre Sorhus
Repository: sindresorhus/cli-cursor
> MIT License
>
> Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
>
> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------
## cli-truncate
License: MIT
By: Sindre Sorhus
Repository: sindresorhus/cli-truncate
> MIT License
>
> Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
>
> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------
## eastasianwidth
License: MIT
By: Masaki Komagata
Repository: git://github.com/komagata/eastasianwidth.git
---------------------------------------
## emoji-regex
License: MIT
By: Mathias Bynens
Repository: https://github.com/mathiasbynens/emoji-regex.git
> Copyright Mathias Bynens <https://mathiasbynens.be/>
>
> Permission is hereby granted, free of charge, to any person obtaining
> a copy of this software and associated documentation files (the
> "Software"), to deal in the Software without restriction, including
> without limitation the rights to use, copy, modify, merge, publish,
> distribute, sublicense, and/or sell copies of the Software, and to
> permit persons to whom the Software is furnished to do so, subject to
> the following conditions:
>
> The above copyright notice and this permission notice shall be
> included in all copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
> NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
> LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
> OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
> WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------
## expect-type
License: Apache-2.0
Repository: https://github.com/mmkal/expect-type.git
> Apache License
> Version 2.0, January 2004
> http://www.apache.org/licenses/
>
> TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
>
> 1. Definitions.
>
> "License" shall mean the terms and conditions for use, reproduction,
> and distribution as defined by Sections 1 through 9 of this document.
>
> "Licensor" shall mean the copyright owner or entity authorized by
> the copyright owner that is granting the License.
>
> "Legal Entity" shall mean the union of the acting entity and all
> other entities that control, are controlled by, or are under common
> control with that entity. For the purposes of this definition,
> "control" means (i) the power, direct or indirect, to cause the
> direction or management of such entity, whether by contract or
> otherwise, or (ii) ownership of fifty percent (50%) or more of the
> outstanding shares, or (iii) beneficial ownership of such entity.
>
> "You" (or "Your") shall mean an individual or Legal Entity
> exercising permissions granted by this License.
>
> "Source" form shall mean the preferred form for making modifications,
> including but not limited to software source code, documentation
> source, and configuration files.
>
> "Object" form shall mean any form resulting from mechanical
> transformation or translation of a Source form, including but
> not limited to compiled object code, generated documentation,
> and conversions to other media types.
>
> "Work" shall mean the work of authorship, whether in Source or
> Object form, made available under the License, as indicated by a
> copyright notice that is included in or attached to the work
> (an example is provided in the Appendix below).
>
> "Derivative Works" shall mean any work, whether in Source or Object
> form, that is based on (or derived from) the Work and for which the
> editorial revisions, annotations, elaborations, or other modifications
> represent, as a whole, an original work of authorship. For the purposes
> of this License, Derivative Works shall not include works that remain
> separable from, or merely link (or bind by name) to the interfaces of,
> the Work and Derivative Works thereof.
>
> "Contribution" shall mean any work of authorship, including
> the original version of the Work and any modifications or additions
> to that Work or Derivative Works thereof, that is intentionally
> submitted to Licensor for inclusion in the Work by the copyright owner
> or by an individual or Legal Entity authorized to submit on behalf of
> the copyright owner. For the purposes of this definition, "submitted"
> means any form of electronic, verbal, or written communication sent
> to the Licensor or its representatives, including but not limited to
> communication on electronic mailing lists, source code control systems,
> and issue tracking systems that are managed by, or on behalf of, the
> Licensor for the purpose of discussing and improving the Work, but
> excluding communication that is conspicuously marked or otherwise
> designated in writing by the copyright owner as "Not a Contribution."
>
> "Contributor" shall mean Licensor and any individual or Legal Entity
> on behalf of whom a Contribution has been received by Licensor and
> subsequently incorporated within the Work.
>
> 2. Grant of Copyright License. Subject to the terms and conditions of
> this License, each Contributor hereby grants to You a perpetual,
> worldwide, non-exclusive, no-charge, royalty-free, irrevocable
> copyright license to reproduce, prepare Derivative Works of,
> publicly display, publicly perform, sublicense, and distribute the
> Work and such Derivative Works in Source or Object form.
>
> 3. Grant of Patent License. Subject to the terms and conditions of
> this License, each Contributor hereby grants to You a perpetual,
> worldwide, non-exclusive, no-charge, royalty-free, irrevocable
> (except as stated in this section) patent license to make, have made,
> use, offer to sell, sell, import, and otherwise transfer the Work,
> where such license applies only to those patent claims licensable
> by such Contributor that are necessarily infringed by their
> Contribution(s) alone or by combination of their Contribution(s)
> with the Work to which such Contribution(s) was submitted. If You
> institute patent litigation against any entity (including a
> cross-claim or counterclaim in a lawsuit) alleging that the Work
> or a Contribution incorporated within the Work constitutes direct
> or contributory patent infringement, then any patent licenses
> granted to You under this License for that Work shall terminate
> as of the date such litigation is filed.
>
> 4. Redistribution. You may reproduce and distribute copies of the
> Work or Derivative Works thereof in any medium, with or without
> modifications, and in Source or Object form, provided that You
> meet the following conditions:
>
> (a) You must give any other recipients of the Work or
> Derivative Works a copy of this License; and
>
> (b) You must cause any modified files to carry prominent notices
> stating that You changed the files; and
>
> (c) You must retain, in the Source form of any Derivative Works
> that You distribute, all copyright, patent, trademark, and
> attribution notices from the Source form of the Work,
> excluding those notices that do not pertain to any part of
> the Derivative Works; and
>
> (d) If the Work includes a "NOTICE" text file as part of its
> distribution, then any Derivative Works that You distribute must
> include a readable copy of the attribution notices contained
> within such NOTICE file, excluding those notices that do not
> pertain to any part of the Derivative Works, in at least one
> of the following places: within a NOTICE text file distributed
> as part of the Derivative Works; within the Source form or
> documentation, if provided along with the Derivative Works; or,
> within a display generated by the Derivative Works, if and
> wherever such third-party notices normally appear. The contents
> of the NOTICE file are for informational purposes only and
> do not modify the License. You may add Your own attribution
> notices within Derivative Works that You distribute, alongside
> or as an addendum to the NOTICE text from the Work, provided
> that such additional attribution notices cannot be construed
> as modifying the License.
>
> You may add Your own copyright statement to Your modifications and
> may provide additional or different license terms and conditions
> for use, reproduction, or distribution of Your modifications, or
> for any such Derivative Works as a whole, provided Your use,
> reproduction, and distribution of the Work otherwise complies with
> the conditions stated in this License.
>
> 5. Submission of Contributions. Unless You explicitly state otherwise,
> any Contribution intentionally submitted for inclusion in the Work
> by You to the Licensor shall be under the terms and conditions of
> this License, without any additional terms or conditions.
> Notwithstanding the above, nothing herein shall supersede or modify
> the terms of any separate license agreement you may have executed
> with Licensor regarding such Contributions.
>
> 6. Trademarks. This License does not grant permission to use the trade
> names, trademarks, service marks, or product names of the Licensor,
> except as required for reasonable and customary use in describing the
> origin of the Work and reproducing the content of the NOTICE file.
>
> 7. Disclaimer of Warranty. Unless required by applicable law or
> agreed to in writing, Licensor provides the Work (and each
> Contributor provides its Contributions) on an "AS IS" BASIS,
> WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied, including, without limitation, any warranties or conditions
> of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
> PARTICULAR PURPOSE. You are solely responsible for determining the
> appropriateness of using or redistributing the Work and assume any
> risks associated with Your exercise of permissions under this License.
>
> 8. Limitation of Liability. In no event and under no legal theory,
> whether in tort (including negligence), contract, or otherwise,
> unless required by applicable law (such as deliberate and grossly
> negligent acts) or agreed to in writing, shall any Contributor be
> liable to You for damages, including any direct, indirect, special,
> incidental, or consequential damages of any character arising as a
> result of this License or out of the use or inability to use the
> Work (including but not limited to damages for loss of goodwill,
> work stoppage, computer failure or malfunction, or any and all
> other commercial damages or losses), even if such Contributor
> has been advised of the possibility of such damages.
>
> 9. Accepting Warranty or Additional Liability. While redistributing
> the Work or Derivative Works thereof, You may choose to offer,
> and charge a fee for, acceptance of support, warranty, indemnity,
> or other liability obligations and/or rights consistent with this
> License. However, in accepting such obligations, You may act only
> on Your own behalf and on Your sole responsibility, not on behalf
> of any other Contributor, and only if You agree to indemnify,
> defend, and hold each Contributor harmless for any liability
> incurred by, or claims asserted against, such Contributor by reason
> of your accepting any such warranty or additional liability.
>
> END OF TERMS AND CONDITIONS
>
> APPENDIX: How to apply the Apache License to your work.
>
> To apply the Apache License to your work, attach the following
> boilerplate notice, with the fields enclosed by brackets "[]"
> replaced with your own identifying information. (Don't include
> the brackets!) The text should be enclosed in the appropriate
> comment syntax for the file format. We also recommend that a
> file or class name and description of purpose be included on the
> same "printed page" as the copyright notice for easier
> identification within third-party archives.
>
> Copyright [yyyy] [name of copyright owner]
>
> Licensed under the Apache License, Version 2.0 (the "License");
> you may not use this file except in compliance with the License.
> You may obtain a copy of the License at
>
> http://www.apache.org/licenses/LICENSE-2.0
>
> Unless required by applicable law or agreed to in writing, software
> distributed under the License is distributed on an "AS IS" BASIS,
> WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> See the License for the specific language governing permissions and
> limitations under the License.
---------------------------------------
## fast-glob
License: MIT
By: Denis Malinochkin
Repository: mrmlnc/fast-glob
> The MIT License (MIT)
>
> Copyright (c) Denis Malinochkin
>
> Permission is hereby granted, free of charge, to any person obtaining a copy
> of this software and associated documentation files (the "Software"), to deal
> in the Software without restriction, including without limitation the rights
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> copies of the Software, and to permit persons to whom the Software is
> furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in all
> copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
> SOFTWARE.
---------------------------------------
## fastq
License: ISC
By: Matteo Collina
Repository: git+https://github.com/mcollina/fastq.git
> Copyright (c) 2015-2020, Matteo Collina <matteo.collina@gmail.com>
>
> Permission to use, copy, modify, and/or distribute this software for any
> purpose with or without fee is hereby granted, provided that the above
> copyright notice and this permission notice appear in all copies.
>
> THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
> WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
> MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
> ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
> WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
> OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
---------------------------------------
## fill-range
License: MIT
By: Jon Schlinkert, Edo Rivai, Paul Miller, Rouven Weßling
Repository: jonschlinkert/fill-range
> The MIT License (MIT)
>
> Copyright (c) 2014-present, Jon Schlinkert.
>
> Permission is hereby granted, free of charge, to any person obtaining a copy
> of this software and associated documentation files (the "Software"), to deal
> in the Software without restriction, including without limitation the rights
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> copies of the Software, and to permit persons to whom the Software is
> furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in
> all copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> THE SOFTWARE.
---------------------------------------
## find-up
License: MIT
By: Sindre Sorhus
Repository: sindresorhus/find-up
> MIT License
>
> Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
>
> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------
## flatted
License: ISC
By: Andrea Giammarchi
Repository: git+https://github.com/WebReflection/flatted.git
> ISC License
>
> Copyright (c) 2018-2020, Andrea Giammarchi, @WebReflection
>
> Permission to use, copy, modify, and/or distribute this software for any
> purpose with or without fee is hereby granted, provided that the above
> copyright notice and this permission notice appear in all copies.
>
> THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
> REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
> AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
> INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
> LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
> OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
> PERFORMANCE OF THIS SOFTWARE.
---------------------------------------
## get-east-asian-width
License: MIT
By: Sindre Sorhus
Repository: sindresorhus/get-east-asian-width
> MIT License
>
> Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
>
> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------
## get-tsconfig
License: MIT
By: Hiroki Osame
Repository: privatenumber/get-tsconfig
> MIT License
>
> Copyright (c) Hiroki Osame <hiroki.osame@gmail.com>
>
> Permission is hereby granted, free of charge, to any person obtaining a copy
> of this software and associated documentation files (the "Software"), to deal
> in the Software without restriction, including without limitation the rights
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> copies of the Software, and to permit persons to whom the Software is
> furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in all
> copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
> SOFTWARE.
---------------------------------------
## glob-parent
License: ISC
By: Gulp Team, Elan Shanker, Blaine Bublitz
Repository: gulpjs/glob-parent
> The ISC License
>
> Copyright (c) 2015, 2019 Elan Shanker
>
> Permission to use, copy, modify, and/or distribute this software for any
> purpose with or without fee is hereby granted, provided that the above
> copyright notice and this permission notice appear in all copies.
>
> THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
> WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
> MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
> ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
> WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
> IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
---------------------------------------
## is-extglob
License: MIT
By: Jon Schlinkert
Repository: jonschlinkert/is-extglob
> The MIT License (MIT)
>
> Copyright (c) 2014-2016, Jon Schlinkert
>
> Permission is hereby granted, free of charge, to any person obtaining a copy
> of this software and associated documentation files (the "Software"), to deal
> in the Software without restriction, including without limitation the rights
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> copies of the Software, and to permit persons to whom the Software is
> furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in
> all copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> THE SOFTWARE.
---------------------------------------
## is-fullwidth-code-point
License: MIT
By: Sindre Sorhus
Repository: sindresorhus/is-fullwidth-code-point
> MIT License
>
> Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
>
> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------
## is-glob
License: MIT
By: Jon Schlinkert, Brian Woodward, Daniel Perez
Repository: micromatch/is-glob
> The MIT License (MIT)
>
> Copyright (c) 2014-2017, Jon Schlinkert.
>
> Permission is hereby granted, free of charge, to any person obtaining a copy
> of this software and associated documentation files (the "Software"), to deal
> in the Software without restriction, including without limitation the rights
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> copies of the Software, and to permit persons to whom the Software is
> furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in
> all copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> THE SOFTWARE.
---------------------------------------
## is-number
License: MIT
By: Jon Schlinkert, Olsten Larck, Rouven Weßling
Repository: jonschlinkert/is-number
> The MIT License (MIT)
>
> Copyright (c) 2014-present, Jon Schlinkert.
>
> Permission is hereby granted, free of charge, to any person obtaining a copy
> of this software and associated documentation files (the "Software"), to deal
> in the Software without restriction, including without limitation the rights
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> copies of the Software, and to permit persons to whom the Software is
> furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in
> all copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> THE SOFTWARE.
---------------------------------------
## kleur
License: MIT
By: Luke Edwards
Repository: lukeed/kleur
> The MIT License (MIT)
>
> Copyright (c) Luke Edwards <luke.edwards05@gmail.com> (lukeed.com)
>
> Permission is hereby granted, free of charge, to any person obtaining a copy
> of this software and associated documentation files (the "Software"), to deal
> in the Software without restriction, including without limitation the rights
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> copies of the Software, and to permit persons to whom the Software is
> furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in
> all copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> THE SOFTWARE.
---------------------------------------
## locate-path
License: MIT
By: Sindre Sorhus
Repository: sindresorhus/locate-path
> MIT License
>
> Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
>
> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------
## log-update
License: MIT
By: Sindre Sorhus
Repository: sindresorhus/log-update
> MIT License
>
> Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
>
> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------
## merge2
License: MIT
Repository: git@github.com:teambition/merge2.git
> The MIT License (MIT)
>
> Copyright (c) 2014-2020 Teambition
>
> Permission is hereby granted, free of charge, to any person obtaining a copy
> of this software and associated documentation files (the "Software"), to deal
> in the Software without restriction, including without limitation the rights
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> copies of the Software, and to permit persons to whom the Software is
> furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in all
> copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
> SOFTWARE.
---------------------------------------
## micromatch
License: MIT
By: Jon Schlinkert, Amila Welihinda, Bogdan Chadkin, Brian Woodward, Devon Govett, Elan Shanker, Fabrício Matté, Martin Kolárik, Olsten Larck, Paul Miller, Tom Byrer, Tyler Akins, Peter Bright, Kuba Juszczyk
Repository: micromatch/micromatch
> The MIT License (MIT)
>
> Copyright (c) 2014-present, Jon Schlinkert.
>
> Permission is hereby granted, free of charge, to any person obtaining a copy
> of this software and associated documentation files (the "Software"), to deal
> in the Software without restriction, including without limitation the rights
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> copies of the Software, and to permit persons to whom the Software is
> furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in
> all copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> THE SOFTWARE.
---------------------------------------
## mimic-fn
License: MIT
By: Sindre Sorhus
Repository: sindresorhus/mimic-fn
> MIT License
>
> Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
>
> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------
## onetime
License: MIT
By: Sindre Sorhus
Repository: sindresorhus/onetime
> MIT License
>
> Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
>
> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------
## p-limit
License: MIT
By: Sindre Sorhus
Repository: sindresorhus/p-limit
> MIT License
>
> Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
>
> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------
## p-locate
License: MIT
By: Sindre Sorhus
Repository: sindresorhus/p-locate
> MIT License
>
> Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
>
> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------
## picomatch
License: MIT
By: Jon Schlinkert
Repository: micromatch/picomatch
> The MIT License (MIT)
>
> Copyright (c) 2017-present, Jon Schlinkert.
>
> Permission is hereby granted, free of charge, to any person obtaining a copy
> of this software and associated documentation files (the "Software"), to deal
> in the Software without restriction, including without limitation the rights
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> copies of the Software, and to permit persons to whom the Software is
> furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in
> all copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> THE SOFTWARE.
---------------------------------------
## prompts
License: MIT
By: Terkel Gjervig
Repository: terkelg/prompts
> MIT License
>
> Copyright (c) 2018 Terkel Gjervig Nielsen
>
> Permission is hereby granted, free of charge, to any person obtaining a copy
> of this software and associated documentation files (the "Software"), to deal
> in the Software without restriction, including without limitation the rights
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> copies of the Software, and to permit persons to whom the Software is
> furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in all
> copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
> SOFTWARE.
---------------------------------------
## queue-microtask
License: MIT
By: Feross Aboukhadijeh
Repository: git://github.com/feross/queue-microtask.git
> The MIT License (MIT)
>
> Copyright (c) Feross Aboukhadijeh
>
> Permission is hereby granted, free of charge, to any person obtaining a copy of
> this software and associated documentation files (the "Software"), to deal in
> the Software without restriction, including without limitation the rights to
> use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
> the Software, and to permit persons to whom the Software is furnished to do so,
> subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in all
> copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
> FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
> COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
> IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
> CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------
## resolve-pkg-maps
License: MIT
By: Hiroki Osame
Repository: privatenumber/resolve-pkg-maps
> MIT License
>
> Copyright (c) Hiroki Osame <hiroki.osame@gmail.com>
>
> Permission is hereby granted, free of charge, to any person obtaining a copy
> of this software and associated documentation files (the "Software"), to deal
> in the Software without restriction, including without limitation the rights
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> copies of the Software, and to permit persons to whom the Software is
> furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in all
> copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
> SOFTWARE.
---------------------------------------
## restore-cursor
License: MIT
By: Sindre Sorhus
Repository: sindresorhus/restore-cursor
> MIT License
>
> Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
>
> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------
## reusify
License: MIT
By: Matteo Collina
Repository: git+https://github.com/mcollina/reusify.git
> The MIT License (MIT)
>
> Copyright (c) 2015 Matteo Collina
>
> Permission is hereby granted, free of charge, to any person obtaining a copy
> of this software and associated documentation files (the "Software"), to deal
> in the Software without restriction, including without limitation the rights
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> copies of the Software, and to permit persons to whom the Software is
> furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in all
> copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
> SOFTWARE.
---------------------------------------
## run-parallel
License: MIT
By: Feross Aboukhadijeh
Repository: git://github.com/feross/run-parallel.git
> The MIT License (MIT)
>
> Copyright (c) Feross Aboukhadijeh
>
> Permission is hereby granted, free of charge, to any person obtaining a copy of
> this software and associated documentation files (the "Software"), to deal in
> the Software without restriction, including without limitation the rights to
> use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
> the Software, and to permit persons to whom the Software is furnished to do so,
> subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in all
> copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
> FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
> COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
> IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
> CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------
## signal-exit
License: ISC
By: Ben Coe
Repository: https://github.com/tapjs/signal-exit.git
> The ISC License
>
> Copyright (c) 2015, Contributors
>
> Permission to use, copy, modify, and/or distribute this software
> for any purpose with or without fee is hereby granted, provided
> that the above copyright notice and this permission notice
> appear in all copies.
>
> THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
> WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
> OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
> LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
> OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
> WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
> ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
---------------------------------------
## sisteransi
License: MIT
By: Terkel Gjervig
Repository: https://github.com/terkelg/sisteransi
> MIT License
>
> Copyright (c) 2018 Terkel Gjervig Nielsen
>
> Permission is hereby granted, free of charge, to any person obtaining a copy
> of this software and associated documentation files (the "Software"), to deal
> in the Software without restriction, including without limitation the rights
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> copies of the Software, and to permit persons to whom the Software is
> furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in all
> copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
> SOFTWARE.
---------------------------------------
## slice-ansi
License: MIT
Repository: chalk/slice-ansi
> MIT License
>
> Copyright (c) DC <threedeecee@gmail.com>
> Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
>
> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------
## string-width
License: MIT
By: Sindre Sorhus
Repository: sindresorhus/string-width
> MIT License
>
> Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
>
> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------
## strip-ansi
License: MIT
By: Sindre Sorhus
Repository: chalk/strip-ansi
> MIT License
>
> Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
>
> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------
## to-regex-range
License: MIT
By: Jon Schlinkert, Rouven Weßling
Repository: micromatch/to-regex-range
> The MIT License (MIT)
>
> Copyright (c) 2015-present, Jon Schlinkert.
>
> Permission is hereby granted, free of charge, to any person obtaining a copy
> of this software and associated documentation files (the "Software"), to deal
> in the Software without restriction, including without limitation the rights
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> copies of the Software, and to permit persons to whom the Software is
> furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in
> all copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> THE SOFTWARE.
---------------------------------------
## type-detect
License: MIT
By: Jake Luer, Keith Cirkel, David Losert, Aleksey Shvayka, Lucas Fernandes da Costa, Grant Snodgrass, Jeremy Tice, Edward Betts, dvlsg, Amila Welihinda, Jake Champion, Miroslav Bajtoš
Repository: git+ssh://git@github.com/chaijs/type-detect.git
> Copyright (c) 2013 Jake Luer <jake@alogicalparadox.com> (http://alogicalparadox.com)
>
> Permission is hereby granted, free of charge, to any person obtaining a copy
> of this software and associated documentation files (the "Software"), to deal
> in the Software without restriction, including without limitation the rights
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> copies of the Software, and to permit persons to whom the Software is
> furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in
> all copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> THE SOFTWARE.
---------------------------------------
## wrap-ansi
License: MIT
By: Sindre Sorhus
Repository: chalk/wrap-ansi
> MIT License
>
> Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
>
> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------
## ws
License: MIT
By: Einar Otto Stangvik
Repository: git+https://github.com/websockets/ws.git
> Copyright (c) 2011 Einar Otto Stangvik <einaros@gmail.com>
> Copyright (c) 2013 Arnout Kazemier and contributors
> Copyright (c) 2016 Luigi Pinca and contributors
>
> Permission is hereby granted, free of charge, to any person obtaining a copy of
> this software and associated documentation files (the "Software"), to deal in
> the Software without restriction, including without limitation the rights to
> use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
> the Software, and to permit persons to whom the Software is furnished to do so,
> subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in all
> copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
> FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
> COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
> IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
> CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------
## yocto-queue
License: MIT
By: Sindre Sorhus
Repository: sindresorhus/yocto-queue
> MIT License
>
> Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
>
> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+7
View File
@@ -0,0 +1,7 @@
# vitest
[![NPM version](https://img.shields.io/npm/v/vitest?color=a1b858&label=)](https://www.npmjs.com/package/vitest)
Next generation testing framework powered by Vite.
[GitHub](https://github.com/vitest-dev/vitest) | [Documentation](https://vitest.dev/)
+1
View File
@@ -0,0 +1 @@
export * from './dist/browser.js'
+1
View File
@@ -0,0 +1 @@
export * from './dist/config.js'
+1
View File
@@ -0,0 +1 @@
export * from './dist/coverage.js'
+60
View File
@@ -0,0 +1,60 @@
export { processError, startTests } from '@vitest/runner';
import { R as ResolvedConfig, C as CoverageOptions, b as CoverageProvider, c as CoverageProviderModule } from './reporters-w_64AS5f.js';
import { VitestExecutor } from './execute.js';
import 'vite';
import 'vite-node';
import '@vitest/snapshot';
import '@vitest/expect';
import '@vitest/runner/utils';
import '@vitest/utils';
import 'tinybench';
import 'node:stream';
import 'vite-node/client';
import '@vitest/snapshot/manager';
import 'vite-node/server';
import 'node:worker_threads';
import 'node:fs';
import 'chai';
import 'node:vm';
type Formatter = (input: string | number | null | undefined) => string;
interface DiffOptions {
aAnnotation?: string;
aColor?: Formatter;
aIndicator?: string;
bAnnotation?: string;
bColor?: Formatter;
bIndicator?: string;
changeColor?: Formatter;
changeLineTrailingSpaceColor?: Formatter;
commonColor?: Formatter;
commonIndicator?: string;
commonLineTrailingSpaceColor?: Formatter;
contextLines?: number;
emptyFirstOrLastLinePlaceholder?: string;
expand?: boolean;
includeChangeCounts?: boolean;
omitAnnotationLines?: boolean;
patchColor?: Formatter;
compareKeys?: any;
truncateThreshold?: number;
truncateAnnotation?: string;
truncateAnnotationColor?: Formatter;
}
declare function setupCommonEnv(config: ResolvedConfig): Promise<void>;
declare function loadDiffConfig(config: ResolvedConfig, executor: VitestExecutor): Promise<DiffOptions | undefined>;
declare function loadSnapshotSerializers(config: ResolvedConfig, executor: VitestExecutor): Promise<void>;
interface Loader {
executeId: (id: string) => Promise<{
default: CoverageProviderModule;
}>;
}
declare function getCoverageProvider(options: CoverageOptions | undefined, loader: Loader): Promise<CoverageProvider | null>;
declare function startCoverageInsideWorker(options: CoverageOptions | undefined, loader: Loader): Promise<unknown>;
declare function takeCoverageInsideWorker(options: CoverageOptions | undefined, loader: Loader): Promise<unknown>;
declare function stopCoverageInsideWorker(options: CoverageOptions | undefined, loader: Loader): Promise<unknown>;
export { getCoverageProvider, loadDiffConfig, loadSnapshotSerializers, setupCommonEnv, startCoverageInsideWorker, stopCoverageInsideWorker, takeCoverageInsideWorker };
+7
View File
@@ -0,0 +1,7 @@
export { processError, startTests } from '@vitest/runner';
export { l as loadDiffConfig, a as loadSnapshotSerializers, s as setupCommonEnv } from './vendor/setup-common.8nJLd4ay.js';
export { g as getCoverageProvider, a as startCoverageInsideWorker, s as stopCoverageInsideWorker, t as takeCoverageInsideWorker } from './vendor/coverage.E7sG1b3r.js';
import '@vitest/utils';
import '@vitest/snapshot';
import './vendor/run-once.Olz_Zkd8.js';
import './vendor/global.CkGT_TMy.js';
@@ -0,0 +1,19 @@
import { NodeSnapshotEnvironment } from '@vitest/snapshot/environment';
import 'pathe';
import '@vitest/runner/utils';
import '@vitest/utils';
import { g as getWorkerState } from '../vendor/global.CkGT_TMy.js';
import '../vendor/env.AtSIuHFg.js';
import 'std-env';
class VitestNodeSnapshotEnvironment extends NodeSnapshotEnvironment {
getHeader() {
return `// Vitest Snapshot v${this.getVersion()}, https://vitest.dev/guide/snapshot.html`;
}
resolvePath(filepath) {
const rpc = getWorkerState().rpc;
return rpc.resolveSnapshotPath(filepath);
}
}
export { VitestNodeSnapshotEnvironment };
@@ -0,0 +1,319 @@
import require$$0, { promises } from 'fs';
import p from 'path';
import process from 'process';
import { fileURLToPath } from 'url';
import { execa } from 'execa';
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
var __accessCheck = (obj, member, msg) => {
if (!member.has(obj))
throw TypeError("Cannot " + msg);
};
var __privateGet = (obj, member, getter) => {
__accessCheck(obj, member, "read from private field");
return getter ? getter.call(obj) : member.get(obj);
};
var __privateAdd = (obj, member, value) => {
if (member.has(obj))
throw TypeError("Cannot add the same private member more than once");
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
};
var __privateSet = (obj, member, value, setter) => {
__accessCheck(obj, member, "write to private field");
setter ? setter.call(obj, value) : member.set(obj, value);
return value;
};
var __privateWrapper = (obj, member, setter, getter) => ({
set _(value) {
__privateSet(obj, member, value, setter);
},
get _() {
return __privateGet(obj, member, getter);
}
});
// node_modules/.pnpm/yocto-queue@1.0.0/node_modules/yocto-queue/index.js
var Node = class {
constructor(value) {
__publicField(this, "value");
__publicField(this, "next");
this.value = value;
}
};
var _head, _tail, _size;
var Queue = class {
constructor() {
__privateAdd(this, _head, void 0);
__privateAdd(this, _tail, void 0);
__privateAdd(this, _size, void 0);
this.clear();
}
enqueue(value) {
const node = new Node(value);
if (__privateGet(this, _head)) {
__privateGet(this, _tail).next = node;
__privateSet(this, _tail, node);
} else {
__privateSet(this, _head, node);
__privateSet(this, _tail, node);
}
__privateWrapper(this, _size)._++;
}
dequeue() {
const current = __privateGet(this, _head);
if (!current) {
return;
}
__privateSet(this, _head, __privateGet(this, _head).next);
__privateWrapper(this, _size)._--;
return current.value;
}
clear() {
__privateSet(this, _head, void 0);
__privateSet(this, _tail, void 0);
__privateSet(this, _size, 0);
}
get size() {
return __privateGet(this, _size);
}
*[Symbol.iterator]() {
let current = __privateGet(this, _head);
while (current) {
yield current.value;
current = current.next;
}
}
};
_head = new WeakMap();
_tail = new WeakMap();
_size = new WeakMap();
// node_modules/.pnpm/p-limit@4.0.0/node_modules/p-limit/index.js
function pLimit(concurrency) {
if (!((Number.isInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency > 0)) {
throw new TypeError("Expected `concurrency` to be a number from 1 and up");
}
const queue = new Queue();
let activeCount = 0;
const next = () => {
activeCount--;
if (queue.size > 0) {
queue.dequeue()();
}
};
const run = async (fn, resolve, args) => {
activeCount++;
const result = (async () => fn(...args))();
resolve(result);
try {
await result;
} catch {
}
next();
};
const enqueue = (fn, resolve, args) => {
queue.enqueue(run.bind(void 0, fn, resolve, args));
(async () => {
await Promise.resolve();
if (activeCount < concurrency && queue.size > 0) {
queue.dequeue()();
}
})();
};
const generator = (fn, ...args) => new Promise((resolve) => {
enqueue(fn, resolve, args);
});
Object.defineProperties(generator, {
activeCount: {
get: () => activeCount
},
pendingCount: {
get: () => queue.size
},
clearQueue: {
value: () => {
queue.clear();
}
}
});
return generator;
}
// node_modules/.pnpm/p-locate@6.0.0/node_modules/p-locate/index.js
var EndError = class extends Error {
constructor(value) {
super();
this.value = value;
}
};
var testElement = async (element, tester) => tester(await element);
var finder = async (element) => {
const values = await Promise.all(element);
if (values[1] === true) {
throw new EndError(values[0]);
}
return false;
};
async function pLocate(iterable, tester, {
concurrency = Number.POSITIVE_INFINITY,
preserveOrder = true
} = {}) {
const limit = pLimit(concurrency);
const items = [...iterable].map((element) => [element, limit(testElement, element, tester)]);
const checkLimit = pLimit(preserveOrder ? 1 : Number.POSITIVE_INFINITY);
try {
await Promise.all(items.map((element) => checkLimit(finder, element)));
} catch (error) {
if (error instanceof EndError) {
return error.value;
}
throw error;
}
}
// node_modules/.pnpm/locate-path@7.2.0/node_modules/locate-path/index.js
var typeMappings = {
directory: "isDirectory",
file: "isFile"
};
function checkType(type) {
if (Object.hasOwnProperty.call(typeMappings, type)) {
return;
}
throw new Error(`Invalid type specified: ${type}`);
}
var matchType = (type, stat) => stat[typeMappings[type]]();
var toPath = (urlOrPath) => urlOrPath instanceof URL ? fileURLToPath(urlOrPath) : urlOrPath;
async function locatePath(paths, {
cwd = process.cwd(),
type = "file",
allowSymlinks = true,
concurrency,
preserveOrder
} = {}) {
checkType(type);
cwd = toPath(cwd);
const statFunction = allowSymlinks ? promises.stat : promises.lstat;
return pLocate(paths, async (path_) => {
try {
const stat = await statFunction(p.resolve(cwd, path_));
return matchType(type, stat);
} catch {
return false;
}
}, { concurrency, preserveOrder });
}
function toPath2(urlOrPath) {
return urlOrPath instanceof URL ? fileURLToPath(urlOrPath) : urlOrPath;
}
// node_modules/.pnpm/find-up@7.0.0/node_modules/find-up/index.js
var findUpStop = Symbol("findUpStop");
async function findUpMultiple(name, options = {}) {
let directory = p.resolve(toPath2(options.cwd) ?? "");
const { root } = p.parse(directory);
const stopAt = p.resolve(directory, toPath2(options.stopAt ?? root));
const limit = options.limit ?? Number.POSITIVE_INFINITY;
const paths = [name].flat();
const runMatcher = async (locateOptions) => {
if (typeof name !== "function") {
return locatePath(paths, locateOptions);
}
const foundPath = await name(locateOptions.cwd);
if (typeof foundPath === "string") {
return locatePath([foundPath], locateOptions);
}
return foundPath;
};
const matches = [];
while (true) {
const foundPath = await runMatcher({ ...options, cwd: directory });
if (foundPath === findUpStop) {
break;
}
if (foundPath) {
matches.push(p.resolve(directory, foundPath));
}
if (directory === stopAt || matches.length >= limit) {
break;
}
directory = p.dirname(directory);
}
return matches;
}
async function findUp(name, options = {}) {
const matches = await findUpMultiple(name, { ...options, limit: 1 });
return matches[0];
}
// src/detect.ts
var AGENTS = ["pnpm", "yarn", "npm", "pnpm@6", "yarn@berry", "bun"];
var LOCKS = {
"bun.lockb": "bun",
"pnpm-lock.yaml": "pnpm",
"yarn.lock": "yarn",
"package-lock.json": "npm",
"npm-shrinkwrap.json": "npm"
};
async function detectPackageManager(cwd = process.cwd()) {
let agent = null;
const lockPath = await findUp(Object.keys(LOCKS), { cwd });
let packageJsonPath;
if (lockPath)
packageJsonPath = p.resolve(lockPath, "../package.json");
else
packageJsonPath = await findUp("package.json", { cwd });
if (packageJsonPath && require$$0.existsSync(packageJsonPath)) {
try {
const pkg = JSON.parse(require$$0.readFileSync(packageJsonPath, "utf8"));
if (typeof pkg.packageManager === "string") {
const [name, version] = pkg.packageManager.split("@");
if (name === "yarn" && Number.parseInt(version) > 1)
agent = "yarn@berry";
else if (name === "pnpm" && Number.parseInt(version) < 7)
agent = "pnpm@6";
else if (AGENTS.includes(name))
agent = name;
else
console.warn("[ni] Unknown packageManager:", pkg.packageManager);
}
} catch {
}
}
if (!agent && lockPath)
agent = LOCKS[p.basename(lockPath)];
return agent;
}
async function installPackage(names, options = {}) {
const detectedAgent = options.packageManager || await detectPackageManager(options.cwd) || "npm";
const [agent] = detectedAgent.split("@");
if (!Array.isArray(names))
names = [names];
const args = options.additionalArgs || [];
if (options.preferOffline) {
if (detectedAgent === "yarn@berry")
args.unshift("--cached");
else
args.unshift("--prefer-offline");
}
return execa(
agent,
[
agent === "yarn" ? "add" : "install",
options.dev ? "-D" : "",
...args,
...names
].filter(Boolean),
{
stdio: options.silent ? "ignore" : "inherit",
cwd: options.cwd
}
);
}
export { detectPackageManager, installPackage };
@@ -0,0 +1,31 @@
import { g as globalApis } from '../vendor/constants.5J7I254_.js';
import { V as VitestIndex } from '../vendor/index.dI9lHwVn.js';
import '@vitest/runner';
import '../vendor/benchmark.yGkUTKnC.js';
import '@vitest/runner/utils';
import '@vitest/utils';
import '../vendor/index.SMVOaj7F.js';
import 'pathe';
import '../vendor/global.CkGT_TMy.js';
import '../vendor/env.AtSIuHFg.js';
import 'std-env';
import '../vendor/run-once.Olz_Zkd8.js';
import '../vendor/vi.YFlodzP_.js';
import 'chai';
import '../vendor/_commonjsHelpers.jjO7Zipk.js';
import '@vitest/expect';
import '@vitest/snapshot';
import '@vitest/utils/error';
import '../vendor/tasks.IknbGB2n.js';
import '@vitest/utils/source-map';
import '../vendor/base.5NT-gWu5.js';
import '../vendor/date.Ns1pGd_X.js';
import '@vitest/spy';
function registerApiGlobally() {
globalApis.forEach((api) => {
globalThis[api] = VitestIndex[api];
});
}
export { registerApiGlobally };
@@ -0,0 +1,70 @@
import { resolve } from 'pathe';
import { execa } from 'execa';
class VitestGit {
constructor(cwd) {
this.cwd = cwd;
}
root;
async resolveFilesWithGitCommand(args) {
let result;
try {
result = await execa("git", args, { cwd: this.root });
} catch (e) {
e.message = e.stderr;
throw e;
}
return result.stdout.split("\n").filter((s) => s !== "").map((changedPath) => resolve(this.root, changedPath));
}
async findChangedFiles(options) {
const root = await this.getRoot(this.cwd);
if (!root)
return null;
this.root = root;
const changedSince = options.changedSince;
if (typeof changedSince === "string") {
const [committed, staged2, unstaged2] = await Promise.all([
this.getFilesSince(changedSince),
this.getStagedFiles(),
this.getUnstagedFiles()
]);
return [...committed, ...staged2, ...unstaged2];
}
const [staged, unstaged] = await Promise.all([
this.getStagedFiles(),
this.getUnstagedFiles()
]);
return [...staged, ...unstaged];
}
getFilesSince(hash) {
return this.resolveFilesWithGitCommand(
["diff", "--name-only", `${hash}...HEAD`]
);
}
getStagedFiles() {
return this.resolveFilesWithGitCommand(
["diff", "--cached", "--name-only"]
);
}
getUnstagedFiles() {
return this.resolveFilesWithGitCommand(
[
"ls-files",
"--other",
"--modified",
"--exclude-standard"
]
);
}
async getRoot(cwd) {
const options = ["rev-parse", "--show-cdup"];
try {
const result = await execa("git", options, { cwd });
return resolve(cwd, result.stdout);
} catch {
return null;
}
}
}
export { VitestGit };
@@ -0,0 +1,131 @@
import { Writable } from 'node:stream';
import { Console } from 'node:console';
import { relative } from 'node:path';
import { getSafeTimers, getColors } from '@vitest/utils';
import { R as RealDate } from '../vendor/date.Ns1pGd_X.js';
import 'pathe';
import '@vitest/runner/utils';
import { g as getWorkerState } from '../vendor/global.CkGT_TMy.js';
import '../vendor/env.AtSIuHFg.js';
import 'std-env';
const UNKNOWN_TEST_ID = "__vitest__unknown_test__";
function getTaskIdByStack(root) {
var _a, _b;
const stack = (_a = new Error("STACK_TRACE_ERROR").stack) == null ? void 0 : _a.split("\n");
if (!stack)
return UNKNOWN_TEST_ID;
const index = stack.findIndex((line2) => line2.includes("at Console.value"));
const line = index === -1 ? null : stack[index + 2];
if (!line)
return UNKNOWN_TEST_ID;
const filepath = (_b = line.match(/at\s(.*)\s?/)) == null ? void 0 : _b[1];
if (filepath)
return relative(root, filepath);
return UNKNOWN_TEST_ID;
}
function createCustomConsole() {
const stdoutBuffer = /* @__PURE__ */ new Map();
const stderrBuffer = /* @__PURE__ */ new Map();
const timers = /* @__PURE__ */ new Map();
const { setTimeout, clearTimeout } = getSafeTimers();
const state = () => getWorkerState();
function schedule(taskId) {
const timer = timers.get(taskId);
const { stdoutTime, stderrTime } = timer;
clearTimeout(timer.timer);
timer.timer = setTimeout(() => {
if (stderrTime < stdoutTime) {
sendStderr(taskId);
sendStdout(taskId);
} else {
sendStdout(taskId);
sendStderr(taskId);
}
});
}
function sendStdout(taskId) {
const buffer = stdoutBuffer.get(taskId);
if (!buffer)
return;
const content = buffer.map((i) => String(i)).join("");
const timer = timers.get(taskId);
state().rpc.onUserConsoleLog({
type: "stdout",
content: content || "<empty line>",
taskId,
time: timer.stdoutTime || RealDate.now(),
size: buffer.length
});
stdoutBuffer.set(taskId, []);
timer.stdoutTime = 0;
}
function sendStderr(taskId) {
const buffer = stderrBuffer.get(taskId);
if (!buffer)
return;
const content = buffer.map((i) => String(i)).join("");
const timer = timers.get(taskId);
state().rpc.onUserConsoleLog({
type: "stderr",
content: content || "<empty line>",
taskId,
time: timer.stderrTime || RealDate.now(),
size: buffer.length
});
stderrBuffer.set(taskId, []);
timer.stderrTime = 0;
}
const stdout = new Writable({
write(data, encoding, callback) {
var _a, _b, _c;
const s = state();
const id = ((_a = s == null ? void 0 : s.current) == null ? void 0 : _a.id) || ((_c = (_b = s == null ? void 0 : s.current) == null ? void 0 : _b.file) == null ? void 0 : _c.id) || getTaskIdByStack(s.config.root);
let timer = timers.get(id);
if (timer) {
timer.stdoutTime = timer.stdoutTime || RealDate.now();
} else {
timer = { stdoutTime: RealDate.now(), stderrTime: RealDate.now(), timer: 0 };
timers.set(id, timer);
}
let buffer = stdoutBuffer.get(id);
if (!buffer) {
buffer = [];
stdoutBuffer.set(id, buffer);
}
buffer.push(data);
schedule(id);
callback();
}
});
const stderr = new Writable({
write(data, encoding, callback) {
var _a, _b, _c;
const s = state();
const id = ((_a = s == null ? void 0 : s.current) == null ? void 0 : _a.id) || ((_c = (_b = s == null ? void 0 : s.current) == null ? void 0 : _b.file) == null ? void 0 : _c.id) || getTaskIdByStack(s.config.root);
let timer = timers.get(id);
if (timer) {
timer.stderrTime = timer.stderrTime || RealDate.now();
} else {
timer = { stderrTime: RealDate.now(), stdoutTime: RealDate.now(), timer: 0 };
timers.set(id, timer);
}
let buffer = stderrBuffer.get(id);
if (!buffer) {
buffer = [];
stderrBuffer.set(id, buffer);
}
buffer.push(data);
schedule(id);
callback();
}
});
return new Console({
stdout,
stderr,
colorMode: getColors().isColorSupported,
groupIndentation: 2
});
}
export { UNKNOWN_TEST_ID, createCustomConsole };
@@ -0,0 +1,125 @@
import { performance } from 'node:perf_hooks';
import { startTests } from '@vitest/runner';
import 'pathe';
import '@vitest/runner/utils';
import { setupColors, createColors, getSafeTimers } from '@vitest/utils';
import { g as getWorkerState } from '../vendor/global.CkGT_TMy.js';
import '../vendor/env.AtSIuHFg.js';
import { a as globalExpect, r as resetModules, v as vi } from '../vendor/vi.YFlodzP_.js';
import { a as startCoverageInsideWorker, s as stopCoverageInsideWorker } from '../vendor/coverage.E7sG1b3r.js';
import { a as resolveSnapshotEnvironment, s as setupChaiConfig, r as resolveTestRunner } from '../vendor/index.DpVgvm2P.js';
import { createRequire } from 'node:module';
import util from 'node:util';
import timers from 'node:timers';
import { isatty } from 'node:tty';
import { installSourcemapsSupport } from 'vite-node/source-map';
import { V as VitestIndex } from '../vendor/index.dI9lHwVn.js';
import { s as setupCommonEnv } from '../vendor/setup-common.8nJLd4ay.js';
import { c as closeInspector } from '../vendor/inspector.IgLX3ur5.js';
import 'std-env';
import 'chai';
import '../vendor/_commonjsHelpers.jjO7Zipk.js';
import '@vitest/expect';
import '@vitest/snapshot';
import '@vitest/utils/error';
import '../vendor/tasks.IknbGB2n.js';
import '@vitest/utils/source-map';
import '../vendor/base.5NT-gWu5.js';
import '../vendor/date.Ns1pGd_X.js';
import '@vitest/spy';
import '../path.js';
import 'node:url';
import '../vendor/rpc.joBhAkyK.js';
import '../vendor/index.8bPxjt7g.js';
import '../vendor/benchmark.yGkUTKnC.js';
import '../vendor/index.SMVOaj7F.js';
import '../vendor/run-once.Olz_Zkd8.js';
let globalSetup = false;
async function setupGlobalEnv(config, { environment }, executor) {
await setupCommonEnv(config);
Object.defineProperty(globalThis, "__vitest_index__", {
value: VitestIndex,
enumerable: false
});
const state = getWorkerState();
if (!state.config.snapshotOptions.snapshotEnvironment)
state.config.snapshotOptions.snapshotEnvironment = await resolveSnapshotEnvironment(config, executor);
if (globalSetup)
return;
globalSetup = true;
setupColors(createColors(isatty(1)));
if (environment.transformMode === "web") {
const _require = createRequire(import.meta.url);
_require.extensions[".css"] = () => ({});
_require.extensions[".scss"] = () => ({});
_require.extensions[".sass"] = () => ({});
_require.extensions[".less"] = () => ({});
process.env.SSR = "";
} else {
process.env.SSR = "1";
}
globalThis.__vitest_required__ = {
util,
timers
};
installSourcemapsSupport({
getSourceMap: (source) => state.moduleCache.getSourceMap(source)
});
if (!config.disableConsoleIntercept)
await setupConsoleLogSpy();
}
async function setupConsoleLogSpy() {
const { createCustomConsole } = await import('./runtime-console.EO5ha7qv.js');
globalThis.console = createCustomConsole();
}
async function withEnv({ environment }, options, fn) {
globalThis.__vitest_environment__ = environment.name;
globalExpect.setState({
environment: environment.name
});
const env = await environment.setup(globalThis, options);
try {
await fn();
} finally {
const { setTimeout } = getSafeTimers();
await new Promise((resolve) => setTimeout(resolve));
await env.teardown(globalThis);
}
}
async function run(files, config, environment, executor) {
const workerState = getWorkerState();
await setupGlobalEnv(config, environment, executor);
await startCoverageInsideWorker(config.coverage, executor);
if (config.chaiConfig)
setupChaiConfig(config.chaiConfig);
const runner = await resolveTestRunner(config, executor);
workerState.onCancel.then((reason) => {
var _a;
closeInspector(config);
(_a = runner.onCancel) == null ? void 0 : _a.call(runner, reason);
});
workerState.durations.prepare = performance.now() - workerState.durations.prepare;
workerState.durations.environment = performance.now();
await withEnv(environment, environment.options || config.environmentOptions || {}, async () => {
var _a, _b, _c, _d;
workerState.durations.environment = performance.now() - workerState.durations.environment;
for (const file of files) {
const isIsolatedThreads = config.pool === "threads" && (((_b = (_a = config.poolOptions) == null ? void 0 : _a.threads) == null ? void 0 : _b.isolate) ?? true);
const isIsolatedForks = config.pool === "forks" && (((_d = (_c = config.poolOptions) == null ? void 0 : _c.forks) == null ? void 0 : _d.isolate) ?? true);
if (isIsolatedThreads || isIsolatedForks) {
workerState.mockMap.clear();
resetModules(workerState.moduleCache, true);
}
workerState.filepath = file;
await startTests([file], runner);
vi.resetConfig();
vi.restoreAllMocks();
}
await stopCoverageInsideWorker(config.coverage, executor);
});
workerState.environmentTeardownRun = true;
}
export { run };
+119
View File
@@ -0,0 +1,119 @@
import { fileURLToPath } from 'node:url';
import c from 'picocolors';
import { execa } from 'execa';
import { E as EXIT_CODE_RESTART } from './vendor/constants.5J7I254_.js';
const ENTRY = new URL("./cli.js", import.meta.url);
const NODE_ARGS = [
"--trace-deprecation",
"--experimental-wasm-threads",
"--wasm-atomics-on-non-shared-memory"
];
const SegfaultErrors = [
{
trigger: "Check failed: result.second.",
url: "https://github.com/nodejs/node/issues/43617"
},
{
trigger: "FATAL ERROR: v8::FromJust Maybe value is Nothing.",
url: "https://github.com/vitest-dev/vitest/issues/1191"
},
{
trigger: "FATAL ERROR: v8::ToLocalChecked Empty MaybeLocal.",
url: "https://github.com/nodejs/node/issues/42407"
}
];
main();
async function main() {
var _a;
let retries = 0;
const args = process.argv.slice(2);
if (process.env.VITEST_SEGFAULT_RETRY) {
retries = +process.env.VITEST_SEGFAULT_RETRY;
} else {
for (let i = 0; i < args.length; i++) {
if (args[i].startsWith("--segfault-retry=") || args[i].startsWith("--segfaultRetry=")) {
retries = +args[i].split("=")[1];
break;
} else if ((args[i] === "--segfault-retry" || args[i] === "--segfaultRetry") && ((_a = args[i + 1]) == null ? void 0 : _a.match(/^\d+$/))) {
retries = +args[i + 1];
break;
}
}
}
if (retries <= 0) {
await import('./cli.js');
return;
}
const nodeArgs = [];
const vitestArgs = [];
for (let i = 0; i < args.length; i++) {
let matched = false;
for (const nodeArg of NODE_ARGS) {
if (args[i] === nodeArg || args[i].startsWith(`${nodeArg}=`)) {
matched = true;
nodeArgs.push(args[i]);
break;
}
}
if (!matched)
vitestArgs.push(args[i]);
}
retries = Math.max(1, retries || 1);
for (let i = 1; i <= retries; i++) {
const result = await start(nodeArgs, vitestArgs);
if (result === "restart") {
i -= 1;
continue;
}
if (i === 1 && retries === 1) {
console.log(c.yellow(`It seems to be an upstream bug of Node.js. To improve the test stability,
you could pass ${c.bold(c.green("--segfault-retry=3"))} or set env ${c.bold(c.green("VITEST_SEGFAULT_RETRY=3"))} to
have Vitest auto retries on flaky segfaults.
`));
}
if (i !== retries)
console.log(`${c.inverse(c.bold(c.magenta(" Retrying ")))} vitest ${args.join(" ")} ${c.gray(`(${i + 1} of ${retries})`)}`);
}
process.exit(1);
}
async function start(preArgs, postArgs) {
var _a;
const child = execa(
"node",
[
...preArgs,
fileURLToPath(ENTRY),
...postArgs
],
{
reject: false,
stderr: "pipe",
stdout: "inherit",
stdin: "inherit",
env: {
...process.env,
VITEST_CLI_WRAPPER: "true"
}
}
);
(_a = child.stderr) == null ? void 0 : _a.pipe(process.stderr);
const { stderr = "" } = await child;
if (child.exitCode === EXIT_CODE_RESTART)
return "restart";
for (const error of SegfaultErrors) {
if (stderr.includes(error.trigger)) {
if (process.env.GITHUB_ACTIONS)
console.log(`::warning:: Segmentfault Error Detected: ${error.trigger}
Refer to ${error.url}`);
const RED_BLOCK = c.inverse(c.red(" "));
console.log(`
${c.inverse(c.bold(c.red(" Segmentfault Error Detected ")))}
${RED_BLOCK} ${c.red(error.trigger)}
${RED_BLOCK} ${c.red(`Refer to ${error.url}`)}
`);
return "error";
}
}
process.exit(child.exitCode);
}
+9
View File
@@ -0,0 +1,9 @@
import { c as createCLI } from './vendor/cac.cdAtVkJZ.js';
import 'pathe';
import 'events';
import 'picocolors';
import './vendor/base.5NT-gWu5.js';
import '@vitest/utils';
import './vendor/constants.5J7I254_.js';
createCLI().parse();
+135
View File
@@ -0,0 +1,135 @@
'use strict';
var os = require('node:os');
var stdEnv = require('std-env');
var vite = require('vite');
var _a$1;
const isNode = typeof process < "u" && typeof process.stdout < "u" && !((_a$1 = process.versions) == null ? void 0 : _a$1.deno) && !globalThis.window;
isNode && process.platform === "win32";
var _a, _b;
const defaultInclude = ["**/*.{test,spec}.?(c|m)[jt]s?(x)"];
const defaultExclude = ["**/node_modules/**", "**/dist/**", "**/cypress/**", "**/.{idea,git,cache,output,temp}/**", "**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build,eslint,prettier}.config.*"];
const defaultCoverageExcludes = [
"coverage/**",
"dist/**",
"**/[.]**",
"packages/*/test?(s)/**",
"**/*.d.ts",
"**/virtual:*",
"**/__x00__*",
"**/\0*",
"cypress/**",
"test?(s)/**",
"test?(-*).?(c|m)[jt]s?(x)",
"**/*{.,-}{test,spec}?(-d).?(c|m)[jt]s?(x)",
"**/__tests__/**",
"**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build}.config.*",
"**/vitest.{workspace,projects}.[jt]s?(on)",
"**/.{eslint,mocha,prettier}rc.{?(c|m)js,yml}"
];
const coverageConfigDefaults = {
provider: "v8",
enabled: false,
all: true,
clean: true,
cleanOnRerun: true,
reportsDirectory: "./coverage",
exclude: defaultCoverageExcludes,
reportOnFailure: false,
reporter: [["text", {}], ["html", {}], ["clover", {}], ["json", {}]],
extension: [".js", ".cjs", ".mjs", ".ts", ".mts", ".cts", ".tsx", ".jsx", ".vue", ".svelte", ".marko"],
allowExternal: false,
ignoreEmptyLines: false,
processingConcurrency: Math.min(20, ((_b = (_a = os).availableParallelism) == null ? void 0 : _b.call(_a)) ?? os.cpus().length)
};
const fakeTimersDefaults = {
loopLimit: 1e4,
shouldClearNativeTimers: true,
toFake: [
"setTimeout",
"clearTimeout",
"setInterval",
"clearInterval",
"setImmediate",
"clearImmediate",
"Date"
]
};
const config = {
allowOnly: !stdEnv.isCI,
isolate: true,
watch: !stdEnv.isCI,
globals: false,
environment: "node",
pool: "threads",
clearMocks: false,
restoreMocks: false,
mockReset: false,
include: defaultInclude,
exclude: defaultExclude,
testTimeout: 5e3,
hookTimeout: 1e4,
teardownTimeout: 1e4,
watchExclude: ["**/node_modules/**", "**/dist/**"],
forceRerunTriggers: [
"**/package.json/**",
"**/{vitest,vite}.config.*/**"
],
update: false,
reporters: [],
silent: false,
hideSkippedTests: false,
api: false,
ui: false,
uiBase: "/__vitest__/",
open: !stdEnv.isCI,
css: {
include: []
},
coverage: coverageConfigDefaults,
fakeTimers: fakeTimersDefaults,
maxConcurrency: 5,
dangerouslyIgnoreUnhandledErrors: false,
typecheck: {
checker: "tsc",
include: ["**/*.{test,spec}-d.?(c|m)[jt]s?(x)"],
exclude: defaultExclude
},
slowTestThreshold: 300,
disableConsoleIntercept: false
};
const configDefaults = Object.freeze(config);
const extraInlineDeps = [
/^(?!.*(?:node_modules)).*\.mjs$/,
/^(?!.*(?:node_modules)).*\.cjs\.js$/,
// Vite client
/vite\w*\/dist\/client\/env.mjs/,
// Nuxt
"@nuxt/test-utils"
];
function defineConfig(config) {
return config;
}
function defineProject(config) {
return config;
}
function defineWorkspace(config) {
return config;
}
Object.defineProperty(exports, "mergeConfig", {
enumerable: true,
get: function () { return vite.mergeConfig; }
});
exports.configDefaults = configDefaults;
exports.coverageConfigDefaults = coverageConfigDefaults;
exports.defaultExclude = defaultExclude;
exports.defaultInclude = defaultInclude;
exports.defineConfig = defineConfig;
exports.defineProject = defineProject;
exports.defineWorkspace = defineWorkspace;
exports.extraInlineDeps = extraInlineDeps;
+16
View File
@@ -0,0 +1,16 @@
export { ConfigEnv, UserConfig, mergeConfig } from 'vite';
export { ax as UserConfigExport, aw as UserConfigFn, au as UserConfigFnObject, av as UserConfigFnPromise, az as UserProjectConfigExport, ay as UserProjectConfigFn, a1 as UserWorkspaceConfig, aD as configDefaults, aG as coverageConfigDefaults, aF as defaultExclude, aE as defaultInclude, aA as defineConfig, aB as defineProject, aC as defineWorkspace, aH as extraInlineDeps } from './reporters-w_64AS5f.js';
import '@vitest/runner';
import 'vite-node';
import '@vitest/snapshot';
import '@vitest/expect';
import '@vitest/runner/utils';
import '@vitest/utils';
import 'tinybench';
import 'node:stream';
import 'vite-node/client';
import '@vitest/snapshot/manager';
import 'vite-node/server';
import 'node:worker_threads';
import 'node:fs';
import 'chai';
+122
View File
@@ -0,0 +1,122 @@
import os from 'node:os';
import { isCI } from 'std-env';
export { mergeConfig } from 'vite';
var _a$1;
const isNode = typeof process < "u" && typeof process.stdout < "u" && !((_a$1 = process.versions) == null ? void 0 : _a$1.deno) && !globalThis.window;
isNode && process.platform === "win32";
var _a, _b;
const defaultInclude = ["**/*.{test,spec}.?(c|m)[jt]s?(x)"];
const defaultExclude = ["**/node_modules/**", "**/dist/**", "**/cypress/**", "**/.{idea,git,cache,output,temp}/**", "**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build,eslint,prettier}.config.*"];
const defaultCoverageExcludes = [
"coverage/**",
"dist/**",
"**/[.]**",
"packages/*/test?(s)/**",
"**/*.d.ts",
"**/virtual:*",
"**/__x00__*",
"**/\0*",
"cypress/**",
"test?(s)/**",
"test?(-*).?(c|m)[jt]s?(x)",
"**/*{.,-}{test,spec}?(-d).?(c|m)[jt]s?(x)",
"**/__tests__/**",
"**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build}.config.*",
"**/vitest.{workspace,projects}.[jt]s?(on)",
"**/.{eslint,mocha,prettier}rc.{?(c|m)js,yml}"
];
const coverageConfigDefaults = {
provider: "v8",
enabled: false,
all: true,
clean: true,
cleanOnRerun: true,
reportsDirectory: "./coverage",
exclude: defaultCoverageExcludes,
reportOnFailure: false,
reporter: [["text", {}], ["html", {}], ["clover", {}], ["json", {}]],
extension: [".js", ".cjs", ".mjs", ".ts", ".mts", ".cts", ".tsx", ".jsx", ".vue", ".svelte", ".marko"],
allowExternal: false,
ignoreEmptyLines: false,
processingConcurrency: Math.min(20, ((_b = (_a = os).availableParallelism) == null ? void 0 : _b.call(_a)) ?? os.cpus().length)
};
const fakeTimersDefaults = {
loopLimit: 1e4,
shouldClearNativeTimers: true,
toFake: [
"setTimeout",
"clearTimeout",
"setInterval",
"clearInterval",
"setImmediate",
"clearImmediate",
"Date"
]
};
const config = {
allowOnly: !isCI,
isolate: true,
watch: !isCI,
globals: false,
environment: "node",
pool: "threads",
clearMocks: false,
restoreMocks: false,
mockReset: false,
include: defaultInclude,
exclude: defaultExclude,
testTimeout: 5e3,
hookTimeout: 1e4,
teardownTimeout: 1e4,
watchExclude: ["**/node_modules/**", "**/dist/**"],
forceRerunTriggers: [
"**/package.json/**",
"**/{vitest,vite}.config.*/**"
],
update: false,
reporters: [],
silent: false,
hideSkippedTests: false,
api: false,
ui: false,
uiBase: "/__vitest__/",
open: !isCI,
css: {
include: []
},
coverage: coverageConfigDefaults,
fakeTimers: fakeTimersDefaults,
maxConcurrency: 5,
dangerouslyIgnoreUnhandledErrors: false,
typecheck: {
checker: "tsc",
include: ["**/*.{test,spec}-d.?(c|m)[jt]s?(x)"],
exclude: defaultExclude
},
slowTestThreshold: 300,
disableConsoleIntercept: false
};
const configDefaults = Object.freeze(config);
const extraInlineDeps = [
/^(?!.*(?:node_modules)).*\.mjs$/,
/^(?!.*(?:node_modules)).*\.cjs\.js$/,
// Vite client
/vite\w*\/dist\/client\/env.mjs/,
// Nuxt
"@nuxt/test-utils"
];
function defineConfig(config) {
return config;
}
function defineProject(config) {
return config;
}
function defineWorkspace(config) {
return config;
}
export { configDefaults, coverageConfigDefaults, defaultExclude, defaultInclude, defineConfig, defineProject, defineWorkspace, extraInlineDeps };
+164
View File
@@ -0,0 +1,164 @@
import { B as BaseCoverageOptions, a as ResolvedCoverageOptions } from './reporters-w_64AS5f.js';
import 'vite';
import '@vitest/runner';
import 'vite-node';
import '@vitest/snapshot';
import '@vitest/expect';
import '@vitest/runner/utils';
import '@vitest/utils';
import 'tinybench';
import 'node:stream';
import 'vite-node/client';
import '@vitest/snapshot/manager';
import 'vite-node/server';
import 'node:worker_threads';
import 'node:fs';
import 'chai';
interface CoverageSummaryData {
lines: Totals;
statements: Totals;
branches: Totals;
functions: Totals;
}
declare class CoverageSummary {
constructor(data: CoverageSummary | CoverageSummaryData);
merge(obj: CoverageSummary): CoverageSummary;
toJSON(): CoverageSummaryData;
isEmpty(): boolean;
data: CoverageSummaryData;
lines: Totals;
statements: Totals;
branches: Totals;
functions: Totals;
}
interface CoverageMapData {
[key: string]: FileCoverage | FileCoverageData;
}
declare class CoverageMap {
constructor(data: CoverageMapData | CoverageMap);
addFileCoverage(pathOrObject: string | FileCoverage | FileCoverageData): void;
files(): string[];
fileCoverageFor(filename: string): FileCoverage;
filter(callback: (key: string) => boolean): void;
getCoverageSummary(): CoverageSummary;
merge(data: CoverageMapData | CoverageMap): void;
toJSON(): CoverageMapData;
data: CoverageMapData;
}
interface Location {
line: number;
column: number;
}
interface Range {
start: Location;
end: Location;
}
interface BranchMapping {
loc: Range;
type: string;
locations: Range[];
line: number;
}
interface FunctionMapping {
name: string;
decl: Range;
loc: Range;
line: number;
}
interface FileCoverageData {
path: string;
statementMap: { [key: string]: Range };
fnMap: { [key: string]: FunctionMapping };
branchMap: { [key: string]: BranchMapping };
s: { [key: string]: number };
f: { [key: string]: number };
b: { [key: string]: number[] };
}
interface Totals {
total: number;
covered: number;
skipped: number;
pct: number;
}
interface Coverage {
covered: number;
total: number;
coverage: number;
}
declare class FileCoverage implements FileCoverageData {
constructor(data: string | FileCoverage | FileCoverageData);
merge(other: FileCoverageData): void;
getBranchCoverageByLine(): { [line: number]: Coverage };
getLineCoverage(): { [line: number]: number };
getUncoveredLines(): number[];
resetHits(): void;
computeBranchTotals(): Totals;
computeSimpleTotals(): Totals;
toSummary(): CoverageSummary;
toJSON(): object;
data: FileCoverageData;
path: string;
statementMap: { [key: string]: Range };
fnMap: { [key: string]: FunctionMapping };
branchMap: { [key: string]: BranchMapping };
s: { [key: string]: number };
f: { [key: string]: number };
b: { [key: string]: number[] };
}
type Threshold = 'lines' | 'functions' | 'statements' | 'branches';
interface ResolvedThreshold {
coverageMap: CoverageMap;
name: string;
thresholds: Partial<Record<Threshold, number | undefined>>;
}
declare class BaseCoverageProvider {
/**
* Check if current coverage is above configured thresholds and bump the thresholds if needed
*/
updateThresholds({ thresholds: allThresholds, perFile, configurationFile, onUpdate }: {
thresholds: ResolvedThreshold[];
perFile?: boolean;
configurationFile: unknown;
onUpdate: () => void;
}): void;
/**
* Check collected coverage against configured thresholds. Sets exit code to 1 when thresholds not reached.
*/
checkThresholds({ thresholds: allThresholds, perFile }: {
thresholds: ResolvedThreshold[];
perFile?: boolean;
}): void;
/**
* Constructs collected coverage and users' threshold options into separate sets
* where each threshold set holds their own coverage maps. Threshold set is either
* for specific files defined by glob pattern or global for all other files.
*/
resolveThresholds({ coverageMap, thresholds, createCoverageMap, root }: {
coverageMap: CoverageMap;
thresholds: NonNullable<BaseCoverageOptions['thresholds']>;
createCoverageMap: () => CoverageMap;
root: string;
}): ResolvedThreshold[];
/**
* Resolve reporters from various configuration options
*/
resolveReporters(configReporters: NonNullable<BaseCoverageOptions['reporter']>): ResolvedCoverageOptions['reporter'];
hasTerminalReporter(reporters: ResolvedCoverageOptions['reporter']): boolean;
toSlices<T>(array: T[], size: number): T[][];
}
export { BaseCoverageProvider };
+186
View File
@@ -0,0 +1,186 @@
import { relative } from 'pathe';
import { m as mm } from './vendor/index.xL8XjTLv.js';
import './vendor/_commonjsHelpers.jjO7Zipk.js';
import 'util';
import 'path';
const THRESHOLD_KEYS = ["lines", "functions", "statements", "branches"];
const GLOBAL_THRESHOLDS_KEY = "global";
class BaseCoverageProvider {
/**
* Check if current coverage is above configured thresholds and bump the thresholds if needed
*/
updateThresholds({ thresholds: allThresholds, perFile, configurationFile, onUpdate }) {
let updatedThresholds = false;
const config = resolveConfig(configurationFile);
assertConfigurationModule(config);
for (const { coverageMap, thresholds, name } of allThresholds) {
const summaries = perFile ? coverageMap.files().map((file) => coverageMap.fileCoverageFor(file).toSummary()) : [coverageMap.getCoverageSummary()];
const thresholdsToUpdate = [];
for (const key of THRESHOLD_KEYS) {
const threshold = thresholds[key] ?? 100;
const actual = Math.min(...summaries.map((summary) => summary[key].pct));
if (actual > threshold)
thresholdsToUpdate.push([key, actual]);
}
if (thresholdsToUpdate.length === 0)
continue;
updatedThresholds = true;
for (const [threshold, newValue] of thresholdsToUpdate) {
if (name === GLOBAL_THRESHOLDS_KEY) {
config.test.coverage.thresholds[threshold] = newValue;
} else {
const glob = config.test.coverage.thresholds[name];
glob[threshold] = newValue;
}
}
}
if (updatedThresholds) {
console.log("Updating thresholds to configuration file. You may want to push with updated coverage thresholds.");
onUpdate();
}
}
/**
* Check collected coverage against configured thresholds. Sets exit code to 1 when thresholds not reached.
*/
checkThresholds({ thresholds: allThresholds, perFile }) {
for (const { coverageMap, thresholds, name } of allThresholds) {
if (thresholds.branches === void 0 && thresholds.functions === void 0 && thresholds.lines === void 0 && thresholds.statements === void 0)
continue;
const summaries = perFile ? coverageMap.files().map((file) => ({
file,
summary: coverageMap.fileCoverageFor(file).toSummary()
})) : [{
file: null,
summary: coverageMap.getCoverageSummary()
}];
for (const { summary, file } of summaries) {
for (const thresholdKey of ["lines", "functions", "statements", "branches"]) {
const threshold = thresholds[thresholdKey];
if (threshold !== void 0) {
const coverage = summary.data[thresholdKey].pct;
if (coverage < threshold) {
process.exitCode = 1;
let errorMessage = `ERROR: Coverage for ${thresholdKey} (${coverage}%) does not meet ${name === GLOBAL_THRESHOLDS_KEY ? name : `"${name}"`} threshold (${threshold}%)`;
if (perFile && file)
errorMessage += ` for ${relative("./", file).replace(/\\/g, "/")}`;
console.error(errorMessage);
}
}
}
}
}
}
/**
* Constructs collected coverage and users' threshold options into separate sets
* where each threshold set holds their own coverage maps. Threshold set is either
* for specific files defined by glob pattern or global for all other files.
*/
resolveThresholds({ coverageMap, thresholds, createCoverageMap, root }) {
const resolvedThresholds = [];
const files = coverageMap.files();
const filesMatchedByGlobs = [];
const globalCoverageMap = createCoverageMap();
for (const key of Object.keys(thresholds)) {
if (key === "perFile" || key === "autoUpdate" || key === "100" || THRESHOLD_KEYS.includes(key))
continue;
const glob = key;
const globThresholds = resolveGlobThresholds(thresholds[glob]);
const globCoverageMap = createCoverageMap();
const matchingFiles = files.filter((file) => mm.isMatch(relative(root, file), glob));
filesMatchedByGlobs.push(...matchingFiles);
for (const file of matchingFiles) {
const fileCoverage = coverageMap.fileCoverageFor(file);
globCoverageMap.addFileCoverage(fileCoverage);
}
resolvedThresholds.push({
name: glob,
coverageMap: globCoverageMap,
thresholds: globThresholds
});
}
for (const file of files.filter((file2) => !filesMatchedByGlobs.includes(file2))) {
const fileCoverage = coverageMap.fileCoverageFor(file);
globalCoverageMap.addFileCoverage(fileCoverage);
}
resolvedThresholds.unshift({
name: GLOBAL_THRESHOLDS_KEY,
coverageMap: globalCoverageMap,
thresholds: {
branches: thresholds.branches,
functions: thresholds.functions,
lines: thresholds.lines,
statements: thresholds.statements
}
});
return resolvedThresholds;
}
/**
* Resolve reporters from various configuration options
*/
resolveReporters(configReporters) {
if (!Array.isArray(configReporters))
return [[configReporters, {}]];
const resolvedReporters = [];
for (const reporter of configReporters) {
if (Array.isArray(reporter)) {
resolvedReporters.push([reporter[0], reporter[1] || {}]);
} else {
resolvedReporters.push([reporter, {}]);
}
}
return resolvedReporters;
}
hasTerminalReporter(reporters) {
return reporters.some(([reporter]) => reporter === "text" || reporter === "text-summary" || reporter === "text-lcov" || reporter === "teamcity");
}
toSlices(array, size) {
return array.reduce((chunks, item) => {
const index = Math.max(0, chunks.length - 1);
const lastChunk = chunks[index] || [];
chunks[index] = lastChunk;
if (lastChunk.length >= size)
chunks.push([item]);
else
lastChunk.push(item);
return chunks;
}, []);
}
}
function resolveGlobThresholds(thresholds) {
if (!thresholds || typeof thresholds !== "object")
return {};
return {
lines: "lines" in thresholds && typeof thresholds.lines === "number" ? thresholds.lines : void 0,
branches: "branches" in thresholds && typeof thresholds.branches === "number" ? thresholds.branches : void 0,
functions: "functions" in thresholds && typeof thresholds.functions === "number" ? thresholds.functions : void 0,
statements: "statements" in thresholds && typeof thresholds.statements === "number" ? thresholds.statements : void 0
};
}
function assertConfigurationModule(config) {
try {
if (typeof config.test.coverage.thresholds !== "object")
throw new Error("Expected config.test.coverage.thresholds to be an object");
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
throw new Error(`Unable to parse thresholds from configuration file: ${message}`);
}
}
function resolveConfig(configModule) {
const mod = configModule.exports.default;
try {
if (mod.$type === "object")
return mod;
if (mod.$type === "function-call") {
if (mod.$args[0].$type === "object")
return mod.$args[0];
if (mod.$args[0].$type === "arrow-function-expression" && mod.$args[0].$body.$type === "object")
return mod.$args[0].$body;
}
} catch (error) {
throw new Error(error instanceof Error ? error.message : String(error));
}
throw new Error("Failed to update coverage thresholds. Configuration file is too complex.");
}
export { BaseCoverageProvider };
+35
View File
@@ -0,0 +1,35 @@
import { E as Environment } from './reporters-w_64AS5f.js';
import 'vite';
import '@vitest/runner';
import 'vite-node';
import '@vitest/snapshot';
import '@vitest/expect';
import '@vitest/runner/utils';
import '@vitest/utils';
import 'tinybench';
import 'node:stream';
import 'vite-node/client';
import '@vitest/snapshot/manager';
import 'vite-node/server';
import 'node:worker_threads';
import 'node:fs';
import 'chai';
declare const environments: {
node: Environment;
jsdom: Environment;
'happy-dom': Environment;
'edge-runtime': Environment;
};
interface PopulateOptions {
bindFunctions?: boolean;
additionalKeys?: string[];
}
declare function populateGlobal(global: any, win: any, options?: PopulateOptions): {
keys: Set<string>;
skipKeys: string[];
originals: Map<string | symbol, any>;
};
export { environments as builtinEnvironments, populateGlobal };
+2
View File
@@ -0,0 +1,2 @@
export { e as builtinEnvironments, p as populateGlobal } from './vendor/index.GVFv9dZ0.js';
import 'node:console';
+151
View File
@@ -0,0 +1,151 @@
import vm from 'node:vm';
import { ViteNodeRunner } from 'vite-node/client';
import { ViteNodeRunnerOptions } from 'vite-node';
import { ar as PendingSuiteMock, as as MockFactory, e as RuntimeRPC, W as WorkerGlobalState, at as MockMap } from './reporters-w_64AS5f.js';
import 'vite';
import '@vitest/runner';
import '@vitest/snapshot';
import '@vitest/expect';
import '@vitest/runner/utils';
import '@vitest/utils';
import 'tinybench';
import 'node:stream';
import '@vitest/snapshot/manager';
import 'vite-node/server';
import 'node:worker_threads';
import 'node:fs';
import 'chai';
type Key = string | symbol;
interface MockContext {
/**
* When mocking with a factory, this refers to the module that imported the mock.
*/
callstack: null | string[];
}
declare class VitestMocker {
executor: VitestExecutor;
static pendingIds: PendingSuiteMock[];
private spyModule?;
private resolveCache;
private primitives;
private filterPublicKeys;
private mockContext;
constructor(executor: VitestExecutor);
private get root();
private get mockMap();
private get moduleCache();
private get moduleDirectories();
initializeSpyModule(): Promise<void>;
private deleteCachedItem;
private isAModuleDirectory;
getSuiteFilepath(): string;
private createError;
getMocks(): {
[x: string]: string | MockFactory | null;
};
private resolvePath;
resolveMocks(): Promise<void>;
private callFunctionMock;
getMockContext(): MockContext;
getMockPath(dep: string): string;
getDependencyMock(id: string): string | MockFactory | null;
normalizePath(path: string): string;
resolveMockPath(mockPath: string, external: string | null): string | null;
mockObject(object: Record<Key, any>, mockExports?: Record<Key, any>): Record<Key, any>;
unmockPath(path: string): void;
mockPath(originalId: string, path: string, external: string | null, factory: MockFactory | undefined): void;
importActual<T>(rawId: string, importer: string, callstack?: string[] | null): Promise<T>;
importMock(rawId: string, importee: string): Promise<any>;
requestWithMock(url: string, callstack: string[]): Promise<any>;
queueMock(id: string, importer: string, factory?: MockFactory, throwIfCached?: boolean): void;
queueUnmock(id: string, importer: string, throwIfCached?: boolean): void;
}
interface ModuleEvaluateOptions {
timeout?: vm.RunningScriptOptions['timeout'] | undefined;
breakOnSigint?: vm.RunningScriptOptions['breakOnSigint'] | undefined;
}
type ModuleLinker = (specifier: string, referencingModule: VMModule, extra: {
assert: Object;
}) => VMModule | Promise<VMModule>;
type ModuleStatus = 'unlinked' | 'linking' | 'linked' | 'evaluating' | 'evaluated' | 'errored';
declare class VMModule {
dependencySpecifiers: readonly string[];
error: any;
identifier: string;
context: vm.Context;
namespace: Object;
status: ModuleStatus;
evaluate(options?: ModuleEvaluateOptions): Promise<void>;
link(linker: ModuleLinker): Promise<void>;
}
declare class FileMap {
private fsCache;
private fsBufferCache;
readFile(path: string): string;
readBuffer(path: string): Buffer;
}
interface ExternalModulesExecutorOptions {
context: vm.Context;
fileMap: FileMap;
packageCache: Map<string, any>;
transform: RuntimeRPC['transform'];
interopDefault?: boolean;
viteClientModule: Record<string, unknown>;
}
declare class ExternalModulesExecutor {
#private;
private options;
private cjs;
private esm;
private vite;
private context;
private fs;
private resolvers;
constructor(options: ExternalModulesExecutorOptions);
import(identifier: string): Promise<Object>;
require(identifier: string): any;
createRequire(identifier: string): NodeRequire;
importModuleDynamically: (specifier: string, referencer: VMModule) => Promise<VMModule>;
resolveModule: (specifier: string, referencer: string) => Promise<VMModule>;
resolve(specifier: string, parent: string): string;
private findNearestPackageData;
private wrapCoreSynteticModule;
private wrapCommonJsSynteticModule;
private getModuleInformation;
private createModule;
private get isNetworkSupported();
}
interface ExecuteOptions extends ViteNodeRunnerOptions {
mockMap: MockMap;
moduleDirectories?: string[];
state: WorkerGlobalState;
context?: vm.Context;
externalModulesExecutor?: ExternalModulesExecutor;
}
declare class VitestExecutor extends ViteNodeRunner {
options: ExecuteOptions;
mocker: VitestMocker;
externalModules?: ExternalModulesExecutor;
private primitives;
constructor(options: ExecuteOptions);
protected getContextPrimitives(): {
Object: ObjectConstructor;
Reflect: typeof Reflect;
Symbol: SymbolConstructor;
};
get state(): WorkerGlobalState;
shouldResolveId(id: string, _importee?: string | undefined): boolean;
originalResolveUrl(id: string, importer?: string): Promise<[url: string, fsPath: string]>;
resolveUrl(id: string, importer?: string): Promise<[string, string]>;
protected runModule(context: Record<string, any>, transformed: string): Promise<void>;
importExternalModule(path: string): Promise<any>;
dependencyRequest(id: string, fsPath: string, callstack: string[]): Promise<any>;
prepareContext(context: Record<string, any>): Record<string, any>;
}
export { VitestExecutor };
+11
View File
@@ -0,0 +1,11 @@
export { V as VitestExecutor } from './vendor/execute.fL3szUAI.js';
import 'node:vm';
import 'node:url';
import 'node:fs';
import 'vite-node/client';
import 'vite-node/utils';
import 'pathe';
import '@vitest/utils/error';
import './path.js';
import '@vitest/utils';
import './vendor/base.5NT-gWu5.js';
+713
View File
@@ -0,0 +1,713 @@
import { TaskPopulated, File, TaskResultPack, CancelReason } from '@vitest/runner';
export { Custom, DoneCallback, ExtendedContext, File, HookCleanupCallback, HookListener, OnTestFailedHandler, RunMode, RuntimeContext, SequenceHooks, SequenceSetupFiles, Suite, SuiteAPI, SuiteCollector, SuiteFactory, SuiteHooks, Task, TaskBase, TaskContext, TaskCustomOptions, TaskMeta, TaskResult, TaskResultPack, TaskState, Test, TestAPI, TestContext, TestFunction, TestOptions, afterAll, afterEach, beforeAll, beforeEach, describe, it, onTestFailed, onTestFinished, suite, test } from '@vitest/runner';
export { b as bench } from './suite-dWqIFb_-.js';
import { ExpectStatic } from '@vitest/expect';
export { Assertion, AsymmetricMatchersContaining, ExpectStatic, JestAssertion } from '@vitest/expect';
import { F as FakeTimerInstallOpts, M as MockFactoryWithHelper, s as RuntimeConfig, P as ProvidedContext, A as AfterSuiteRunMeta, t as UserConsoleLog, R as ResolvedConfig, u as ModuleGraphData, v as Reporter } from './reporters-w_64AS5f.js';
export { Q as ApiConfig, aa as ArgumentsType, a9 as Arrayable, a7 as Awaitable, B as BaseCoverageOptions, ap as BenchFunction, an as Benchmark, aq as BenchmarkAPI, ao as BenchmarkResult, am as BenchmarkUserOptions, a0 as BrowserConfigOptions, r as BrowserScript, L as BuiltinEnvironment, O as CSSModuleScopeStrategy, y as CollectLineNumbers, z as CollectLines, ac as Constructable, G as Context, f as ContextRPC, a3 as ContextTestEnvironment, aj as CoverageIstanbulOptions, C as CoverageOptions, b as CoverageProvider, c as CoverageProviderModule, ai as CoverageReporter, ak as CoverageV8Options, al as CustomProviderOptions, X as DepsOptimizationOptions, E as Environment, S as EnvironmentOptions, ae as EnvironmentReturn, K as HappyDOMOptions, Z as InlineConfig, J as JSDOMOptions, ad as ModuleCache, ab as MutableArray, a8 as Nullable, ag as OnServerRestartHandler, H as Pool, I as PoolOptions, $ as ProjectConfig, w as RawErrsMap, ah as ReportContext, a5 as ResolveIdFunction, a as ResolvedCoverageOptions, a4 as ResolvedTestEnvironment, D as RootAndTarget, a2 as RunnerRPC, e as RuntimeRPC, Y as TransformModePatterns, x as TscErrorInfo, _ as TypecheckConfig, U as UserConfig, a1 as UserWorkspaceConfig, i as Vitest, N as VitestEnvironment, V as VitestRunMode, af as VmEnvironmentReturn, g as WorkerContext, W as WorkerGlobalState, a6 as WorkerRPC } from './reporters-w_64AS5f.js';
import { spyOn, fn, MaybeMockedDeep, MaybeMocked, MaybePartiallyMocked, MaybePartiallyMockedDeep, MockInstance } from '@vitest/spy';
export { Mock, MockContext, MockInstance, Mocked, MockedClass, MockedFunction, MockedObject, SpyInstance } from '@vitest/spy';
export { SnapshotEnvironment } from '@vitest/snapshot/environment';
import { SnapshotResult } from '@vitest/snapshot';
export { SnapshotData, SnapshotMatchOptions, SnapshotResult, SnapshotSerializer, SnapshotStateOptions, SnapshotSummary, SnapshotUpdateState, UncheckedSnapshot } from '@vitest/snapshot';
export { DiffOptions } from '@vitest/utils/diff';
import { TransformResult } from 'vite';
import * as chai from 'chai';
export { chai };
export { assert, should } from 'chai';
export { ErrorWithDiff, ParsedStack } from '@vitest/utils';
export { Bench as BenchFactory, Options as BenchOptions, Task as BenchTask, TaskResult as BenchTaskResult } from 'tinybench';
import '@vitest/runner/utils';
import 'vite-node';
import 'node:stream';
import 'vite-node/client';
import '@vitest/snapshot/manager';
import 'vite-node/server';
import 'node:worker_threads';
import 'node:fs';
declare type Not<T extends boolean> = T extends true ? false : true;
declare type And<Types extends boolean[]> = Types[number] extends true ? true : false;
declare type Eq<Left extends boolean, Right extends boolean> = Left extends true ? Right : Not<Right>;
declare const secret: unique symbol;
declare type Secret = typeof secret;
declare type IsNever<T> = [T] extends [never] ? true : false;
declare type IsAny<T> = [T] extends [Secret] ? Not<IsNever<T>> : false;
declare type IsUnknown<T> = [unknown] extends [T] ? Not<IsAny<T>> : false;
declare type PrintType<T> = IsUnknown<T> extends true ? 'unknown' : IsNever<T> extends true ? 'never' : IsAny<T> extends true ? never : boolean extends T ? 'boolean' : T extends boolean ? `literal boolean: ${T}` : string extends T ? 'string' : T extends string ? `literal string: ${T}` : number extends T ? 'number' : T extends number ? `literal number: ${T}` : T extends null ? 'null' : T extends undefined ? 'undefined' : T extends (...args: any[]) => any ? 'function' : '...';
/** Subjective "useful" keys from a type. For objects it's just `keyof` but for tuples/arrays it's the number keys
* @example
* UsefulKeys<{a: 1; b: 2}> // 'a' | 'b'
* UsefulKeys<['a', 'b']> // '0' | '1'
* UsefulKeys<string[]> // number
*/
declare type UsefulKeys<T> = T extends any[] ? {
[K in keyof T]: K;
}[number] : keyof T;
declare type MismatchInfo<Actual, Expected> = And<[Extends<PrintType<Actual>, '...'>, Not<IsAny<Actual>>]> extends true ? And<[Extends<any[], Actual>, Extends<any[], Expected>]> extends true ? Array<MismatchInfo<Extract<Actual, any[]>[number], Extract<Expected, any[]>[number]>> : {
[K in UsefulKeys<Actual> | UsefulKeys<Expected>]: MismatchInfo<K extends keyof Actual ? Actual[K] : never, K extends keyof Expected ? Expected[K] : never>;
} : StrictEqualUsingBranding<Actual, Expected> extends true ? Actual : `Expected: ${PrintType<Expected>}, Actual: ${PrintType<Exclude<Actual, Expected>>}`;
/**
* Recursively walk a type and replace it with a branded type related to the original. This is useful for
* equality-checking stricter than `A extends B ? B extends A ? true : false : false`, because it detects
* the difference between a few edge-case types that vanilla typescript doesn't by default:
* - `any` vs `unknown`
* - `{ readonly a: string }` vs `{ a: string }`
* - `{ a?: string }` vs `{ a: string | undefined }`
*
* Note: not very performant for complex types - this should only be used when you know you need it. If doing
* an equality check, it's almost always better to use `StrictEqualUsingTSInternalIdenticalToOperator`.
*/
declare type DeepBrand<T> = IsNever<T> extends true ? {
type: 'never';
} : IsAny<T> extends true ? {
type: 'any';
} : IsUnknown<T> extends true ? {
type: 'unknown';
} : T extends string | number | boolean | symbol | bigint | null | undefined | void ? {
type: 'primitive';
value: T;
} : T extends new (...args: any[]) => any ? {
type: 'constructor';
params: ConstructorParams<T>;
instance: DeepBrand<InstanceType<Extract<T, new (...args: any) => any>>>;
} : T extends (...args: infer P) => infer R ? {
type: 'function';
params: DeepBrand<P>;
return: DeepBrand<R>;
this: DeepBrand<ThisParameterType<T>>;
props: DeepBrand<Omit<T, keyof Function>>;
} : T extends any[] ? {
type: 'array';
items: {
[K in keyof T]: T[K];
};
} : {
type: 'object';
properties: {
[K in keyof T]: DeepBrand<T[K]>;
};
readonly: ReadonlyKeys<T>;
required: RequiredKeys<T>;
optional: OptionalKeys<T>;
constructorParams: DeepBrand<ConstructorParams<T>>;
};
declare type RequiredKeys<T> = Extract<{
[K in keyof T]-?: {} extends Pick<T, K> ? never : K;
}[keyof T], keyof T>;
declare type OptionalKeys<T> = Exclude<keyof T, RequiredKeys<T>>;
declare type ReadonlyKeys<T> = Extract<{
[K in keyof T]-?: ReadonlyEquivalent<{
[_K in K]: T[K];
}, {
-readonly [_K in K]: T[K];
}> extends true ? never : K;
}[keyof T], keyof T>;
declare type ReadonlyEquivalent<X, Y> = Extends<(<T>() => T extends X ? true : false), (<T>() => T extends Y ? true : false)>;
/** Returns true if `L extends R`. Explicitly checks for `never` since that can give unexpected results. */
declare type Extends<L, R> = IsNever<L> extends true ? IsNever<R> : [L] extends [R] ? true : false;
declare type ExtendsUsingBranding<L, R> = Extends<DeepBrand<L>, DeepBrand<R>>;
declare type ExtendsExcludingAnyOrNever<L, R> = IsAny<L> extends true ? IsAny<R> : Extends<L, R>;
declare type StrictEqualUsingTSInternalIdenticalToOperator<L, R> = (<T>() => T extends (L & T) | T ? true : false) extends <T>() => T extends (R & T) | T ? true : false ? IsNever<L> extends IsNever<R> ? true : false : false;
declare type StrictEqualUsingBranding<Left, Right> = And<[
ExtendsUsingBranding<Left, Right>,
ExtendsUsingBranding<Right, Left>
]>;
declare type Params<Actual> = Actual extends (...args: infer P) => any ? P : never;
declare type ConstructorParams<Actual> = Actual extends new (...args: infer P) => any ? Actual extends new () => any ? P | [] : P : never;
declare const mismatch: unique symbol;
declare type Mismatch = {
[mismatch]: 'mismatch';
};
/** A type which should match anything passed as a value but *doesn't* match `Mismatch` - helps TypeScript select the right overload for `toEqualTypeOf` and `toMatchTypeOf`. */
declare const avalue: unique symbol;
declare type AValue = {
[avalue]?: undefined;
} | string | number | boolean | symbol | bigint | null | undefined | void;
declare type MismatchArgs<ActualResult extends boolean, ExpectedResult extends boolean> = Eq<ActualResult, ExpectedResult> extends true ? [] : [Mismatch];
declare const inverted: unique symbol;
declare type Inverted<T> = {
[inverted]: T;
};
declare const expectNull: unique symbol;
declare type ExpectNull<T> = {
[expectNull]: T;
result: ExtendsExcludingAnyOrNever<T, null>;
};
declare const expectUndefined: unique symbol;
declare type ExpectUndefined<T> = {
[expectUndefined]: T;
result: ExtendsExcludingAnyOrNever<T, undefined>;
};
declare const expectNumber: unique symbol;
declare type ExpectNumber<T> = {
[expectNumber]: T;
result: ExtendsExcludingAnyOrNever<T, number>;
};
declare const expectString: unique symbol;
declare type ExpectString<T> = {
[expectString]: T;
result: ExtendsExcludingAnyOrNever<T, string>;
};
declare const expectBoolean: unique symbol;
declare type ExpectBoolean<T> = {
[expectBoolean]: T;
result: ExtendsExcludingAnyOrNever<T, boolean>;
};
declare const expectVoid: unique symbol;
declare type ExpectVoid<T> = {
[expectVoid]: T;
result: ExtendsExcludingAnyOrNever<T, void>;
};
declare const expectFunction: unique symbol;
declare type ExpectFunction<T> = {
[expectFunction]: T;
result: ExtendsExcludingAnyOrNever<T, (...args: any[]) => any>;
};
declare const expectObject: unique symbol;
declare type ExpectObject<T> = {
[expectObject]: T;
result: ExtendsExcludingAnyOrNever<T, object>;
};
declare const expectArray: unique symbol;
declare type ExpectArray<T> = {
[expectArray]: T;
result: ExtendsExcludingAnyOrNever<T, any[]>;
};
declare const expectSymbol: unique symbol;
declare type ExpectSymbol<T> = {
[expectSymbol]: T;
result: ExtendsExcludingAnyOrNever<T, symbol>;
};
declare const expectAny: unique symbol;
declare type ExpectAny<T> = {
[expectAny]: T;
result: IsAny<T>;
};
declare const expectUnknown: unique symbol;
declare type ExpectUnknown<T> = {
[expectUnknown]: T;
result: IsUnknown<T>;
};
declare const expectNever: unique symbol;
declare type ExpectNever<T> = {
[expectNever]: T;
result: IsNever<T>;
};
declare const expectNullable: unique symbol;
declare type ExpectNullable<T> = {
[expectNullable]: T;
result: Not<StrictEqualUsingBranding<T, NonNullable<T>>>;
};
declare type Scolder<Expecter extends {
result: boolean;
}, Options extends {
positive: boolean;
}> = Expecter['result'] extends Options['positive'] ? () => true : Options['positive'] extends true ? Expecter : Inverted<Expecter>;
interface PositiveExpectTypeOf<Actual> extends BaseExpectTypeOf<Actual, {
positive: true;
branded: false;
}> {
toEqualTypeOf: {
<Expected extends StrictEqualUsingTSInternalIdenticalToOperator<Actual, Expected> extends true ? unknown : MismatchInfo<Actual, Expected>>(value: Expected & AValue, // reason for `& AValue`: make sure this is only the selected overload when the end-user passes a value for an inferred typearg. The `Mismatch` type does match `AValue`.
...MISMATCH: MismatchArgs<StrictEqualUsingTSInternalIdenticalToOperator<Actual, Expected>, true>): true;
<Expected extends StrictEqualUsingTSInternalIdenticalToOperator<Actual, Expected> extends true ? unknown : MismatchInfo<Actual, Expected>>(...MISMATCH: MismatchArgs<StrictEqualUsingTSInternalIdenticalToOperator<Actual, Expected>, true>): true;
};
toMatchTypeOf: {
<Expected extends Extends<Actual, Expected> extends true ? unknown : MismatchInfo<Actual, Expected>>(value: Expected & AValue, // reason for `& AValue`: make sure this is only the selected overload when the end-user passes a value for an inferred typearg. The `Mismatch` type does match `AValue`.
...MISMATCH: MismatchArgs<Extends<Actual, Expected>, true>): true;
<Expected extends Extends<Actual, Expected> extends true ? unknown : MismatchInfo<Actual, Expected>>(...MISMATCH: MismatchArgs<Extends<Actual, Expected>, true>): true;
};
toHaveProperty: <K extends keyof Actual>(key: K, ...MISMATCH: MismatchArgs<Extends<K, keyof Actual>, true>) => K extends keyof Actual ? PositiveExpectTypeOf<Actual[K]> : true;
not: NegativeExpectTypeOf<Actual>;
branded: {
toEqualTypeOf: <Expected extends StrictEqualUsingBranding<Actual, Expected> extends true ? unknown : MismatchInfo<Actual, Expected>>(...MISMATCH: MismatchArgs<StrictEqualUsingBranding<Actual, Expected>, true>) => true;
};
}
interface NegativeExpectTypeOf<Actual> extends BaseExpectTypeOf<Actual, {
positive: false;
}> {
toEqualTypeOf: {
<Expected>(value: Expected & AValue, ...MISMATCH: MismatchArgs<StrictEqualUsingTSInternalIdenticalToOperator<Actual, Expected>, false>): true;
<Expected>(...MISMATCH: MismatchArgs<StrictEqualUsingTSInternalIdenticalToOperator<Actual, Expected>, false>): true;
};
toMatchTypeOf: {
<Expected>(value: Expected & AValue, // reason for `& AValue`: make sure this is only the selected overload when the end-user passes a value for an inferred typearg. The `Mismatch` type does match `AValue`.
...MISMATCH: MismatchArgs<Extends<Actual, Expected>, false>): true;
<Expected>(...MISMATCH: MismatchArgs<Extends<Actual, Expected>, false>): true;
};
toHaveProperty: <K extends string | number | symbol>(key: K, ...MISMATCH: MismatchArgs<Extends<K, keyof Actual>, false>) => true;
}
declare type ExpectTypeOf<Actual, Options extends {
positive: boolean;
}> = Options['positive'] extends true ? PositiveExpectTypeOf<Actual> : NegativeExpectTypeOf<Actual>;
interface BaseExpectTypeOf<Actual, Options extends {
positive: boolean;
}> {
toBeAny: Scolder<ExpectAny<Actual>, Options>;
toBeUnknown: Scolder<ExpectUnknown<Actual>, Options>;
toBeNever: Scolder<ExpectNever<Actual>, Options>;
toBeFunction: Scolder<ExpectFunction<Actual>, Options>;
toBeObject: Scolder<ExpectObject<Actual>, Options>;
toBeArray: Scolder<ExpectArray<Actual>, Options>;
toBeNumber: Scolder<ExpectNumber<Actual>, Options>;
toBeString: Scolder<ExpectString<Actual>, Options>;
toBeBoolean: Scolder<ExpectBoolean<Actual>, Options>;
toBeVoid: Scolder<ExpectVoid<Actual>, Options>;
toBeSymbol: Scolder<ExpectSymbol<Actual>, Options>;
toBeNull: Scolder<ExpectNull<Actual>, Options>;
toBeUndefined: Scolder<ExpectUndefined<Actual>, Options>;
toBeNullable: Scolder<ExpectNullable<Actual>, Options>;
toBeCallableWith: Options['positive'] extends true ? (...args: Params<Actual>) => true : never;
toBeConstructibleWith: Options['positive'] extends true ? (...args: ConstructorParams<Actual>) => true : never;
extract: <V>(v?: V) => ExpectTypeOf<Extract<Actual, V>, Options>;
exclude: <V>(v?: V) => ExpectTypeOf<Exclude<Actual, V>, Options>;
parameter: <K extends keyof Params<Actual>>(number: K) => ExpectTypeOf<Params<Actual>[K], Options>;
parameters: ExpectTypeOf<Params<Actual>, Options>;
constructorParameters: ExpectTypeOf<ConstructorParams<Actual>, Options>;
thisParameter: ExpectTypeOf<ThisParameterType<Actual>, Options>;
instance: Actual extends new (...args: any[]) => infer I ? ExpectTypeOf<I, Options> : never;
returns: Actual extends (...args: any[]) => infer R ? ExpectTypeOf<R, Options> : never;
resolves: Actual extends PromiseLike<infer R> ? ExpectTypeOf<R, Options> : never;
items: Actual extends ArrayLike<infer R> ? ExpectTypeOf<R, Options> : never;
guards: Actual extends (v: any, ...args: any[]) => v is infer T ? ExpectTypeOf<T, Options> : never;
asserts: Actual extends (v: any, ...args: any[]) => asserts v is infer T ? unknown extends T ? never : ExpectTypeOf<T, Options> : never;
}
declare type _ExpectTypeOf = {
<Actual>(actual: Actual): ExpectTypeOf<Actual, {
positive: true;
branded: false;
}>;
<Actual>(): ExpectTypeOf<Actual, {
positive: true;
branded: false;
}>;
};
/**
* Similar to Jest's `expect`, but with type-awareness.
* Gives you access to a number of type-matchers that let you make assertions about the
* form of a reference or generic type parameter.
*
* @example
* import {foo, bar} from '../foo'
* import {expectTypeOf} from 'expect-type'
*
* test('foo types', () => {
* // make sure `foo` has type {a: number}
* expectTypeOf(foo).toMatchTypeOf({a: 1})
* expectTypeOf(foo).toHaveProperty('a').toBeNumber()
*
* // make sure `bar` is a function taking a string:
* expectTypeOf(bar).parameter(0).toBeString()
* expectTypeOf(bar).returns.not.toBeAny()
* })
*
* @description
* See the [full docs](https://npmjs.com/package/expect-type#documentation) for lots more examples.
*/
declare const expectTypeOf: _ExpectTypeOf;
interface AssertType {
<T>(value: T): void;
}
declare const assertType: AssertType;
/**
* This utils allows computational intensive tasks to only be ran once
* across test reruns to improve the watch mode performance.
*
* Currently only works with `poolOptions.<pool>.isolate: false`
*
* @experimental
*/
declare function runOnce<T>(fn: (() => T), key?: string): T;
/**
* Get a boolean indicates whether the task is running in the first time.
* Could only be `false` in watch mode.
*
* Currently only works with `isolate: false`
*
* @experimental
*/
declare function isFirstRun(): boolean;
declare function createExpect(test?: TaskPopulated): ExpectStatic;
declare const globalExpect: ExpectStatic;
type WaitForCallback<T> = () => T | Promise<T>;
interface WaitForOptions {
/**
* @description Time in ms between each check callback
* @default 50ms
*/
interval?: number;
/**
* @description Time in ms after which the throw a timeout error
* @default 1000ms
*/
timeout?: number;
}
declare function waitFor<T>(callback: WaitForCallback<T>, options?: number | WaitForOptions): Promise<T>;
type WaitUntilCallback<T> = () => T | Promise<T>;
interface WaitUntilOptions extends Pick<WaitForOptions, 'interval' | 'timeout'> {
}
type Truthy<T> = T extends false | '' | 0 | null | undefined ? never : T;
declare function waitUntil<T>(callback: WaitUntilCallback<T>, options?: number | WaitUntilOptions): Promise<Truthy<T>>;
type ESModuleExports = Record<string, unknown>;
interface VitestUtils {
/**
* Checks if fake timers are enabled.
*/
isFakeTimers: () => boolean;
/**
* This method wraps all further calls to timers until [`vi.useRealTimers()`](https://vitest.dev/api/vi#vi-userealtimers) is called.
*/
useFakeTimers: (config?: FakeTimerInstallOpts) => VitestUtils;
/**
* Restores mocked timers to their original implementations. All timers that were scheduled before will be discarded.
*/
useRealTimers: () => VitestUtils;
/**
* This method will call every timer that was initiated after [`vi.useFakeTimers`](https://vitest.dev/api/vi#vi-usefaketimers) call.
* It will not fire any timer that was initiated during its call.
*/
runOnlyPendingTimers: () => VitestUtils;
/**
* This method will asynchronously call every timer that was initiated after [`vi.useFakeTimers`](https://vitest.dev/api/vi#vi-usefaketimers) call, even asynchronous ones.
* It will not fire any timer that was initiated during its call.
*/
runOnlyPendingTimersAsync: () => Promise<VitestUtils>;
/**
* This method will invoke every initiated timer until the timer queue is empty. It means that every timer called during `runAllTimers` will be fired.
* If you have an infinite interval, it will throw after 10,000 tries (can be configured with [`fakeTimers.loopLimit`](https://vitest.dev/config/#faketimers-looplimit)).
*/
runAllTimers: () => VitestUtils;
/**
* This method will asynchronously invoke every initiated timer until the timer queue is empty. It means that every timer called during `runAllTimersAsync` will be fired even asynchronous timers.
* If you have an infinite interval, it will throw after 10 000 tries (can be configured with [`fakeTimers.loopLimit`](https://vitest.dev/config/#faketimers-looplimit)).
*/
runAllTimersAsync: () => Promise<VitestUtils>;
/**
* Calls every microtask that was queued by `process.nextTick`. This will also run all microtasks scheduled by themselves.
*/
runAllTicks: () => VitestUtils;
/**
* This method will invoke every initiated timer until the specified number of milliseconds is passed or the queue is empty - whatever comes first.
*/
advanceTimersByTime: (ms: number) => VitestUtils;
/**
* This method will invoke every initiated timer until the specified number of milliseconds is passed or the queue is empty - whatever comes first. This will include and await asynchronously set timers.
*/
advanceTimersByTimeAsync: (ms: number) => Promise<VitestUtils>;
/**
* Will call next available timer. Useful to make assertions between each timer call. You can chain call it to manage timers by yourself.
*/
advanceTimersToNextTimer: () => VitestUtils;
/**
* Will call next available timer and wait until it's resolved if it was set asynchronously. Useful to make assertions between each timer call.
*/
advanceTimersToNextTimerAsync: () => Promise<VitestUtils>;
/**
* Get the number of waiting timers.
*/
getTimerCount: () => number;
/**
* If fake timers are enabled, this method simulates a user changing the system clock (will affect date related API like `hrtime`, `performance.now` or `new Date()`) - however, it will not fire any timers.
* If fake timers are not enabled, this method will only mock `Date.*` and `new Date()` calls.
*/
setSystemTime: (time: number | string | Date) => VitestUtils;
/**
* Returns mocked current date that was set using `setSystemTime`. If date is not mocked the method will return `null`.
*/
getMockedSystemTime: () => Date | null;
/**
* When using `vi.useFakeTimers`, `Date.now` calls are mocked. If you need to get real time in milliseconds, you can call this function.
*/
getRealSystemTime: () => number;
/**
* Removes all timers that are scheduled to run. These timers will never run in the future.
*/
clearAllTimers: () => VitestUtils;
/**
* Creates a spy on a method or getter/setter of an object similar to [`vi.fn()`](https://vitest.dev/api/vi#vi-fn). It returns a [mock function](https://vitest.dev/api/mock).
*
* @example
* const cart = {
* getApples: () => 42
* }
*
* const spy = vi.spyOn(cart, 'getApples').mockReturnValue(10)
*
* expect(cart.getApples()).toBe(10)
* expect(spy).toHaveBeenCalled()
* expect(spy).toHaveReturnedWith(10)
*/
spyOn: typeof spyOn;
/**
* Creates a spy on a function, though can be initiated without one. Every time a function is invoked, it stores its call arguments, returns, and instances. Also, you can manipulate its behavior with [methods](https://vitest.dev/api/mock).
*
* If no function is given, mock will return `undefined`, when invoked.
*
* @example
* const getApples = vi.fn(() => 0)
*
* getApples()
*
* expect(getApples).toHaveBeenCalled()
* expect(getApples).toHaveReturnedWith(0)
*
* getApples.mockReturnValueOnce(5)
*
* expect(getApples()).toBe(5)
* expect(getApples).toHaveNthReturnedWith(2, 5)
*/
fn: typeof fn;
/**
* Wait for the callback to execute successfully. If the callback throws an error or returns a rejected promise it will continue to wait until it succeeds or times out.
*
* This is very useful when you need to wait for some asynchronous action to complete, for example, when you start a server and need to wait for it to start.
*
* @example
* const server = createServer()
*
* await vi.waitFor(
* () => {
* if (!server.isReady)
* throw new Error('Server not started')
*
* console.log('Server started')
* }, {
* timeout: 500, // default is 1000
* interval: 20, // default is 50
* }
* )
*/
waitFor: typeof waitFor;
/**
* This is similar to [`vi.waitFor`](https://vitest.dev/api/vi#vi-waitfor), but if the callback throws any errors, execution is immediately interrupted and an error message is received.
*
* If the callback returns a falsy value, the next check will continue until a truthy value is returned. This is useful when you need to wait for something to exist before taking the next step.
*
* @example
* const element = await vi.waitUntil(
* () => document.querySelector('.element'),
* {
* timeout: 500, // default is 1000
* interval: 20, // default is 50
* }
* )
*
* // do something with the element
* expect(element.querySelector('.element-child')).toBeTruthy()
*/
waitUntil: typeof waitUntil;
/**
* Run the factory before imports are evaluated. You can return a value from the factory
* to reuse it inside your [`vi.mock`](https://vitest.dev/api/vi#vi-mock) factory and tests.
*
* If used with [`vi.mock`](https://vitest.dev/api/vi#vi-mock), both will be hoisted in the order they are defined in.
*/
hoisted: <T>(factory: () => T) => T;
/**
* Mocks every import call to the module even if it was already statically imported.
*
* The call to `vi.mock` is hoisted to the top of the file, so you don't have access to variables declared in the global file scope
* unless they are defined with [`vi.hoisted`](https://vitest.dev/api/vi#vi-hoisted) before this call.
*
* Mocking algorithm is described in [documentation](https://vitest.dev/guide/mocking#modules).
* @param path Path to the module. Can be aliased, if your Vitest config supports it
* @param factory Mocked module factory. The result of this function will be an exports object
*/
mock: (path: string, factory?: MockFactoryWithHelper) => void;
/**
* Removes module from mocked registry. All calls to import will return the original module even if it was mocked before.
*
* This call is hoisted to the top of the file, so it will only unmock modules that were defined in `setupFiles`, for example.
* @param path Path to the module. Can be aliased, if your Vitest config supports it
*/
unmock: (path: string) => void;
/**
* Mocks every subsequent [dynamic import](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import) call.
*
* Unlike [`vi.mock`](https://vitest.dev/api/vi#vi-mock), this method will not mock statically imported modules because it is not hoisted to the top of the file.
*
* Mocking algorithm is described in [documentation](https://vitest.dev/guide/mocking#modules).
* @param path Path to the module. Can be aliased, if your Vitest config supports it
* @param factory Mocked module factory. The result of this function will be an exports object
*/
doMock: (path: string, factory?: MockFactoryWithHelper) => void;
/**
* Removes module from mocked registry. All subsequent calls to import will return original module.
*
* Unlike [`vi.unmock`](https://vitest.dev/api/vi#vi-unmock), this method is not hoisted to the top of the file.
* @param path Path to the module. Can be aliased, if your Vitest config supports it
*/
doUnmock: (path: string) => void;
/**
* Imports module, bypassing all checks if it should be mocked.
* Can be useful if you want to mock module partially.
* @example
* vi.mock('./example.js', async () => {
* const axios = await vi.importActual<typeof import('./example.js')>('./example.js')
*
* return { ...axios, get: vi.fn() }
* })
* @param path Path to the module. Can be aliased, if your config supports it
*/
importActual: <T = ESModuleExports>(path: string) => Promise<T>;
/**
* Imports a module with all of its properties and nested properties mocked.
*
* Mocking algorithm is described in [documentation](https://vitest.dev/guide/mocking#modules).
* @example
* const example = await vi.importMock<typeof import('./example.js')>('./example.js')
* example.calc.mockReturnValue(10)
* expect(example.calc()).toBe(10)
* @param path Path to the module. Can be aliased, if your config supports it
* @returns Fully mocked module
*/
importMock: <T = ESModuleExports>(path: string) => Promise<MaybeMockedDeep<T>>;
/**
* Type helper for TypeScript. Just returns the object that was passed.
*
* When `partial` is `true` it will expect a `Partial<T>` as a return value. By default, this will only make TypeScript believe that
* the first level values are mocked. You can pass down `{ deep: true }` as a second argument to tell TypeScript that the whole object is mocked, if it actually is.
* @example
* import example from './example.js'
* vi.mock('./example.js')
*
* test('1 + 1 equals 10' async () => {
* vi.mocked(example.calc).mockReturnValue(10)
* expect(example.calc(1, '+', 1)).toBe(10)
* })
* @param item Anything that can be mocked
* @param deep If the object is deeply mocked
* @param options If the object is partially or deeply mocked
*/
mocked: (<T>(item: T, deep?: false) => MaybeMocked<T>) & (<T>(item: T, deep: true) => MaybeMockedDeep<T>) & (<T>(item: T, options: {
partial?: false;
deep?: false;
}) => MaybeMocked<T>) & (<T>(item: T, options: {
partial?: false;
deep: true;
}) => MaybeMockedDeep<T>) & (<T>(item: T, options: {
partial: true;
deep?: false;
}) => MaybePartiallyMocked<T>) & (<T>(item: T, options: {
partial: true;
deep: true;
}) => MaybePartiallyMockedDeep<T>) & (<T>(item: T) => MaybeMocked<T>);
/**
* Checks that a given parameter is a mock function. If you are using TypeScript, it will also narrow down its type.
*/
isMockFunction: (fn: any) => fn is MockInstance;
/**
* Calls [`.mockClear()`](https://vitest.dev/api/mock#mockclear) on every mocked function. This will only empty `.mock` state, it will not reset implementation.
*
* It is useful if you need to clean up mock between different assertions.
*/
clearAllMocks: () => VitestUtils;
/**
* Calls [`.mockReset()`](https://vitest.dev/api/mock#mockreset) on every mocked function. This will empty `.mock` state, reset "once" implementations and force the base implementation to return `undefined` when invoked.
*
* This is useful when you want to completely reset a mock to the default state.
*/
resetAllMocks: () => VitestUtils;
/**
* Calls [`.mockRestore()`](https://vitest.dev/api/mock#mockrestore) on every mocked function. This will restore all original implementations.
*/
restoreAllMocks: () => VitestUtils;
/**
* Makes value available on global namespace.
* Useful, if you want to have global variables available, like `IntersectionObserver`.
* You can return it back to original value with `vi.unstubAllGlobals`, or by enabling `unstubGlobals` config option.
*/
stubGlobal: (name: string | symbol | number, value: unknown) => VitestUtils;
/**
* Changes the value of `import.meta.env` and `process.env`.
* You can return it back to original value with `vi.unstubAllEnvs`, or by enabling `unstubEnvs` config option.
*/
stubEnv: <T extends string>(name: T, value: T extends 'PROD' | 'DEV' | 'SSR' ? boolean : string) => VitestUtils;
/**
* Reset the value to original value that was available before first `vi.stubGlobal` was called.
*/
unstubAllGlobals: () => VitestUtils;
/**
* Reset environmental variables to the ones that were available before first `vi.stubEnv` was called.
*/
unstubAllEnvs: () => VitestUtils;
/**
* Resets modules registry by clearing the cache of all modules. This allows modules to be reevaluated when reimported.
* Top-level imports cannot be re-evaluated. Might be useful to isolate modules where local state conflicts between tests.
*
* This method does not reset mocks registry. To clear mocks registry, use [`vi.unmock`](https://vitest.dev/api/vi#vi-unmock) or [`vi.doUnmock`](https://vitest.dev/api/vi#vi-dounmock).
*/
resetModules: () => VitestUtils;
/**
* Wait for all imports to load. Useful, if you have a synchronous call that starts
* importing a module that you cannot await otherwise.
* Will also wait for new imports, started during the wait.
*/
dynamicImportSettled: () => Promise<void>;
/**
* Updates runtime config. You can only change values that are used when executing tests.
*/
setConfig: (config: RuntimeConfig) => void;
/**
* If config was changed with `vi.setConfig`, this will reset it to the original state.
*/
resetConfig: () => void;
}
declare const vitest: VitestUtils;
declare const vi: VitestUtils;
declare function getRunningMode(): "run" | "watch";
declare function isWatchMode(): boolean;
/**
* Gives access to injected context provided from the main thread.
* This usually returns a value provided by `globalSetup` or an external library.
*/
declare function inject<T extends keyof ProvidedContext>(key: T): ProvidedContext[T];
interface TransformResultWithSource extends TransformResult {
source?: string;
}
interface WebSocketHandlers {
onUnhandledError: (error: unknown, type: string) => Promise<void>;
onCollected: (files?: File[]) => Promise<void>;
onTaskUpdate: (packs: TaskResultPack[]) => void;
onAfterSuiteRun: (meta: AfterSuiteRunMeta) => void;
onCancel: (reason: CancelReason) => void;
getCountOfFailedTests: () => number;
sendLog: (log: UserConsoleLog) => void;
getFiles: () => File[];
getTestFiles: () => Promise<[name: string, file: string][]>;
getPaths: () => string[];
getConfig: () => ResolvedConfig;
resolveSnapshotPath: (testPath: string) => string;
resolveSnapshotRawPath: (testPath: string, rawPath: string) => string;
getModuleGraph: (id: string) => Promise<ModuleGraphData>;
getBrowserFileSourceMap: (id: string) => Promise<TransformResult['map'] | undefined>;
getTransformResult: (id: string) => Promise<TransformResultWithSource | undefined>;
readSnapshotFile: (id: string) => Promise<string | null>;
readTestFile: (id: string) => Promise<string | null>;
saveTestFile: (id: string, content: string) => Promise<void>;
saveSnapshotFile: (id: string, content: string) => Promise<void>;
removeSnapshotFile: (id: string) => Promise<void>;
snapshotSaved: (snapshot: SnapshotResult) => void;
rerun: (files: string[]) => Promise<void>;
updateSnapshot: (file?: File) => Promise<void>;
getProvidedContext: () => ProvidedContext;
getUnhandledErrors: () => unknown[];
finishBrowserTests: () => void;
getBrowserFiles: () => string[];
debug: (...args: string[]) => void;
}
interface WebSocketEvents extends Pick<Reporter, 'onCollected' | 'onFinished' | 'onTaskUpdate' | 'onUserConsoleLog' | 'onPathsCollected'> {
onCancel: (reason: CancelReason) => void;
onFinishedReportCoverage: () => void;
}
export { AfterSuiteRunMeta, type AssertType, type ExpectTypeOf, ModuleGraphData, ProvidedContext, Reporter, ResolvedConfig, RuntimeConfig, type TransformResultWithSource, UserConsoleLog, type VitestUtils, type WebSocketEvents, type WebSocketHandlers, assertType, createExpect, globalExpect as expect, expectTypeOf, getRunningMode, inject, isFirstRun, isWatchMode, runOnce, vi, vitest };
+30
View File
@@ -0,0 +1,30 @@
export { afterAll, afterEach, beforeAll, beforeEach, describe, it, onTestFailed, onTestFinished, suite, test } from '@vitest/runner';
export { b as bench } from './vendor/benchmark.yGkUTKnC.js';
export { i as isFirstRun, a as runOnce } from './vendor/run-once.Olz_Zkd8.js';
export { c as createExpect, a as expect, v as vi, b as vitest } from './vendor/vi.YFlodzP_.js';
import { d as dist } from './vendor/index.dI9lHwVn.js';
export { b as assertType, g as getRunningMode, i as inject, a as isWatchMode } from './vendor/index.dI9lHwVn.js';
import * as chai from 'chai';
export { chai };
export { assert, should } from 'chai';
import '@vitest/runner/utils';
import '@vitest/utils';
import './vendor/index.SMVOaj7F.js';
import 'pathe';
import './vendor/global.CkGT_TMy.js';
import './vendor/env.AtSIuHFg.js';
import 'std-env';
import './vendor/_commonjsHelpers.jjO7Zipk.js';
import '@vitest/expect';
import '@vitest/snapshot';
import '@vitest/utils/error';
import './vendor/tasks.IknbGB2n.js';
import '@vitest/utils/source-map';
import './vendor/base.5NT-gWu5.js';
import './vendor/date.Ns1pGd_X.js';
import '@vitest/spy';
var expectTypeOf = dist.expectTypeOf;
export { expectTypeOf };
+68
View File
@@ -0,0 +1,68 @@
import { V as VitestRunMode, U as UserConfig, h as VitestOptions, i as Vitest, R as ResolvedConfig, P as ProvidedContext, j as WorkspaceProject, e as RuntimeRPC, T as TestSequencer, k as WorkspaceSpec } from './reporters-w_64AS5f.js';
export { p as BrowserProvider, o as BrowserProviderInitializationOptions, q as BrowserProviderOptions, r as BrowserScript, l as ProcessPool, n as TestSequencerConstructor, m as VitestPackageInstaller } from './reporters-w_64AS5f.js';
import { UserConfig as UserConfig$1, Plugin } from 'vite';
import { Writable } from 'node:stream';
import '@vitest/runner';
import 'vite-node';
import '@vitest/snapshot';
import '@vitest/expect';
import '@vitest/runner/utils';
import '@vitest/utils';
import 'tinybench';
import 'vite-node/client';
import '@vitest/snapshot/manager';
import 'vite-node/server';
import 'node:worker_threads';
import 'node:fs';
import 'chai';
declare function createVitest(mode: VitestRunMode, options: UserConfig, viteOverrides?: UserConfig$1, vitestOptions?: VitestOptions): Promise<Vitest>;
declare function VitestPlugin(options?: UserConfig, ctx?: Vitest): Promise<Plugin[]>;
interface CliOptions extends UserConfig {
/**
* Override the watch mode
*/
run?: boolean;
/**
* Retry the test suite if it crashes due to a segfault (default: true)
*/
segfaultRetry?: number;
/**
* Removes colors from the console output
*/
color?: boolean;
}
/**
* Start Vitest programmatically
*
* Returns a Vitest instance if initialized successfully.
*/
declare function startVitest(mode: VitestRunMode, cliFilters?: string[], options?: CliOptions, viteOverrides?: UserConfig$1, vitestOptions?: VitestOptions): Promise<Vitest | undefined>;
interface CLIOptions {
allowUnknownOptions?: boolean;
}
declare function parseCLI(argv: string | string[], config?: CLIOptions): {
filter: string[];
options: CliOptions;
};
declare function registerConsoleShortcuts(ctx: Vitest, stdin: NodeJS.ReadStream | undefined, stdout: NodeJS.WriteStream | Writable): () => void;
interface GlobalSetupContext {
config: ResolvedConfig;
provide: <T extends keyof ProvidedContext>(key: T, value: ProvidedContext[T]) => void;
}
declare function createMethodsRPC(project: WorkspaceProject): RuntimeRPC;
declare class BaseSequencer implements TestSequencer {
protected ctx: Vitest;
constructor(ctx: Vitest);
shard(files: WorkspaceSpec[]): Promise<WorkspaceSpec[]>;
sort(files: WorkspaceSpec[]): Promise<WorkspaceSpec[]>;
}
export { BaseSequencer, type GlobalSetupContext, TestSequencer, Vitest, VitestPlugin, WorkspaceProject, WorkspaceSpec, createMethodsRPC, createVitest, parseCLI, registerConsoleShortcuts, startVitest };
+68
View File
@@ -0,0 +1,68 @@
export { b as VitestPackageInstaller, V as VitestPlugin, a as createMethodsRPC, c as createVitest, r as registerConsoleShortcuts, s as startVitest } from './vendor/cli-api.OdDWuB7Y.js';
export { p as parseCLI } from './vendor/cac.cdAtVkJZ.js';
export { B as BaseSequencer } from './vendor/index.-xs08BYx.js';
import 'pathe';
import './vendor/constants.5J7I254_.js';
import './vendor/coverage.E7sG1b3r.js';
import './vendor/index.GVFv9dZ0.js';
import 'node:console';
import 'vite';
import 'node:path';
import 'node:url';
import 'node:process';
import 'node:fs';
import 'node:worker_threads';
import './vendor/_commonjsHelpers.jjO7Zipk.js';
import 'os';
import 'path';
import './vendor/index.xL8XjTLv.js';
import 'util';
import 'stream';
import 'events';
import 'fs';
import 'picocolors';
import 'vite-node/client';
import '@vitest/snapshot/manager';
import 'vite-node/server';
import '@vitest/runner/utils';
import './vendor/base.5NT-gWu5.js';
import '@vitest/utils';
import './vendor/env.AtSIuHFg.js';
import 'std-env';
import './path.js';
import './vendor/index.8bPxjt7g.js';
import 'zlib';
import 'buffer';
import 'crypto';
import 'https';
import 'http';
import 'net';
import 'tls';
import 'url';
import '@vitest/utils/source-map';
import 'node:crypto';
import 'node:v8';
import 'node:os';
import 'node:events';
import 'tinypool';
import 'node:fs/promises';
import 'local-pkg';
import 'vite-node/utils';
import 'magic-string';
import 'acorn-walk';
import '@vitest/utils/ast';
import 'strip-literal';
import './vendor/utils.dEtNIEgr.js';
import 'node:module';
import './vendor/index.SMVOaj7F.js';
import './vendor/global.CkGT_TMy.js';
import 'node:readline';
import 'readline';
import './vendor/tasks.IknbGB2n.js';
import 'node:perf_hooks';
import './chunks/runtime-console.EO5ha7qv.js';
import 'node:stream';
import './vendor/date.Ns1pGd_X.js';
import 'execa';
import 'module';
import 'assert';
+7
View File
@@ -0,0 +1,7 @@
import url from 'node:url';
import { resolve } from 'pathe';
const rootDir = resolve(url.fileURLToPath(import.meta.url), "../../");
const distDir = resolve(url.fileURLToPath(import.meta.url), "../../dist");
export { distDir, rootDir };
+2899
View File
@@ -0,0 +1,2899 @@
import * as vite from 'vite';
import { ViteDevServer, TransformResult as TransformResult$1, UserConfig as UserConfig$1, ConfigEnv, ServerOptions, DepOptimizationConfig, AliasOptions } from 'vite';
import * as _vitest_runner from '@vitest/runner';
import { File, Test as Test$1, Suite, TaskResultPack, Task, CancelReason, Custom, SequenceHooks, SequenceSetupFiles } from '@vitest/runner';
import { RawSourceMap, FetchResult, ViteNodeResolveId, ModuleCacheMap, ViteNodeServerOptions } from 'vite-node';
import { SnapshotResult, SnapshotStateOptions, SnapshotState } from '@vitest/snapshot';
import { ExpectStatic } from '@vitest/expect';
import { ChainableFunction } from '@vitest/runner/utils';
import { ParsedStack, Awaitable as Awaitable$1, Arrayable as Arrayable$1 } from '@vitest/utils';
import { TaskResult, Bench, Options as Options$1 } from 'tinybench';
import { Writable } from 'node:stream';
import { ViteNodeRunner } from 'vite-node/client';
import { SnapshotManager } from '@vitest/snapshot/manager';
import { ViteNodeServer } from 'vite-node/server';
import { MessagePort } from 'node:worker_threads';
import { Stats } from 'node:fs';
import * as chai from 'chai';
declare const Modifier: unique symbol;
declare const Hint: unique symbol;
declare const Kind: unique symbol;
type Evaluate<T> = T extends infer O ? {
[K in keyof O]: O[K];
} : never;
type TReadonly<T extends TSchema> = T & {
[Modifier]: 'Readonly';
};
type TOptional<T extends TSchema> = T & {
[Modifier]: 'Optional';
};
type TReadonlyOptional<T extends TSchema> = T & {
[Modifier]: 'ReadonlyOptional';
};
interface SchemaOptions {
$schema?: string;
/** Id for this schema */
$id?: string;
/** Title of this schema */
title?: string;
/** Description of this schema */
description?: string;
/** Default value for this schema */
default?: any;
/** Example values matching this schema */
examples?: any;
[prop: string]: any;
}
interface TKind {
[Kind]: string;
}
interface TSchema extends SchemaOptions, TKind {
[Modifier]?: string;
[Hint]?: string;
params: unknown[];
static: unknown;
}
interface NumericOptions<N extends number | bigint> extends SchemaOptions {
exclusiveMaximum?: N;
exclusiveMinimum?: N;
maximum?: N;
minimum?: N;
multipleOf?: N;
}
interface TBoolean extends TSchema {
[Kind]: 'Boolean';
static: boolean;
type: 'boolean';
}
interface TNull extends TSchema {
[Kind]: 'Null';
static: null;
type: 'null';
}
interface TNumber extends TSchema, NumericOptions<number> {
[Kind]: 'Number';
static: number;
type: 'number';
}
type ReadonlyOptionalPropertyKeys<T extends TProperties> = {
[K in keyof T]: T[K] extends TReadonlyOptional<TSchema> ? K : never;
}[keyof T];
type ReadonlyPropertyKeys<T extends TProperties> = {
[K in keyof T]: T[K] extends TReadonly<TSchema> ? K : never;
}[keyof T];
type OptionalPropertyKeys<T extends TProperties> = {
[K in keyof T]: T[K] extends TOptional<TSchema> ? K : never;
}[keyof T];
type RequiredPropertyKeys<T extends TProperties> = keyof Omit<T, ReadonlyOptionalPropertyKeys<T> | ReadonlyPropertyKeys<T> | OptionalPropertyKeys<T>>;
type PropertiesReducer<T extends TProperties, R extends Record<keyof any, unknown>> = Evaluate<(Readonly<Partial<Pick<R, ReadonlyOptionalPropertyKeys<T>>>> & Readonly<Pick<R, ReadonlyPropertyKeys<T>>> & Partial<Pick<R, OptionalPropertyKeys<T>>> & Required<Pick<R, RequiredPropertyKeys<T>>>)>;
type PropertiesReduce<T extends TProperties, P extends unknown[]> = PropertiesReducer<T, {
[K in keyof T]: Static<T[K], P>;
}>;
type TProperties = Record<keyof any, TSchema>;
type TAdditionalProperties = undefined | TSchema | boolean;
interface ObjectOptions extends SchemaOptions {
additionalProperties?: TAdditionalProperties;
minProperties?: number;
maxProperties?: number;
}
interface TObject<T extends TProperties = TProperties> extends TSchema, ObjectOptions {
[Kind]: 'Object';
static: PropertiesReduce<T, this['params']>;
additionalProperties?: TAdditionalProperties;
type: 'object';
properties: T;
required?: string[];
}
interface StringOptions<Format extends string> extends SchemaOptions {
minLength?: number;
maxLength?: number;
pattern?: string;
format?: Format;
contentEncoding?: '7bit' | '8bit' | 'binary' | 'quoted-printable' | 'base64';
contentMediaType?: string;
}
interface TString<Format extends string = string> extends TSchema, StringOptions<Format> {
[Kind]: 'String';
static: string;
type: 'string';
}
/** Creates a TypeScript static type from a TypeBox type */
type Static<T extends TSchema, P extends unknown[] = []> = (T & {
params: P;
})['static'];
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
declare const RawSnapshotFormat: TObject<{
callToJSON: TReadonlyOptional<TBoolean>;
compareKeys: TReadonlyOptional<TNull>;
escapeRegex: TReadonlyOptional<TBoolean>;
escapeString: TReadonlyOptional<TBoolean>;
highlight: TReadonlyOptional<TBoolean>;
indent: TReadonlyOptional<TNumber>;
maxDepth: TReadonlyOptional<TNumber>;
maxWidth: TReadonlyOptional<TNumber>;
min: TReadonlyOptional<TBoolean>;
printBasicPrototype: TReadonlyOptional<TBoolean>;
printFunctionName: TReadonlyOptional<TBoolean>;
theme: TReadonlyOptional<
TObject<{
comment: TReadonlyOptional<TString<string>>;
content: TReadonlyOptional<TString<string>>;
prop: TReadonlyOptional<TString<string>>;
tag: TReadonlyOptional<TString<string>>;
value: TReadonlyOptional<TString<string>>;
}>
>;
}>;
declare const SnapshotFormat: TObject<{
callToJSON: TReadonlyOptional<TBoolean>;
compareKeys: TReadonlyOptional<TNull>;
escapeRegex: TReadonlyOptional<TBoolean>;
escapeString: TReadonlyOptional<TBoolean>;
highlight: TReadonlyOptional<TBoolean>;
indent: TReadonlyOptional<TNumber>;
maxDepth: TReadonlyOptional<TNumber>;
maxWidth: TReadonlyOptional<TNumber>;
min: TReadonlyOptional<TBoolean>;
printBasicPrototype: TReadonlyOptional<TBoolean>;
printFunctionName: TReadonlyOptional<TBoolean>;
theme: TReadonlyOptional<
TObject<{
comment: TReadonlyOptional<TString<string>>;
content: TReadonlyOptional<TString<string>>;
prop: TReadonlyOptional<TString<string>>;
tag: TReadonlyOptional<TString<string>>;
value: TReadonlyOptional<TString<string>>;
}>
>;
}>;
declare type SnapshotFormat = Static<typeof RawSnapshotFormat>;
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
declare type Colors = {
comment: {
close: string;
open: string;
};
content: {
close: string;
open: string;
};
prop: {
close: string;
open: string;
};
tag: {
close: string;
open: string;
};
value: {
close: string;
open: string;
};
};
declare type CompareKeys =
| ((a: string, b: string) => number)
| null
| undefined;
declare type Config = {
callToJSON: boolean;
compareKeys: CompareKeys;
colors: Colors;
escapeRegex: boolean;
escapeString: boolean;
indent: string;
maxDepth: number;
maxWidth: number;
min: boolean;
plugins: Plugins;
printBasicPrototype: boolean;
printFunctionName: boolean;
spacingInner: string;
spacingOuter: string;
};
declare type Indent = (arg0: string) => string;
declare type NewPlugin = {
serialize: (
val: any,
config: Config,
indentation: string,
depth: number,
refs: Refs,
printer: Printer,
) => string;
test: Test;
};
declare type OldPlugin = {
print: (
val: unknown,
print: Print,
indent: Indent,
options: PluginOptions,
colors: Colors,
) => string;
test: Test;
};
declare type Plugin_2 = NewPlugin | OldPlugin;
declare type PluginOptions = {
edgeSpacing: string;
min: boolean;
spacing: string;
};
declare type Plugins = Array<Plugin_2>;
declare interface PrettyFormatOptions
extends Omit<SnapshotFormat, 'compareKeys'> {
compareKeys?: CompareKeys;
plugins?: Plugins;
}
declare type Print = (arg0: unknown) => string;
declare type Printer = (
val: unknown,
config: Config,
indentation: string,
depth: number,
refs: Refs,
hasCalledToJSON?: boolean,
) => string;
declare type Refs = Array<unknown>;
declare type Test = (arg0: any) => boolean;
/**
* Names of clock methods that may be faked by install.
*/
type FakeMethod =
| "setTimeout"
| "clearTimeout"
| "setImmediate"
| "clearImmediate"
| "setInterval"
| "clearInterval"
| "Date"
| "nextTick"
| "hrtime"
| "requestAnimationFrame"
| "cancelAnimationFrame"
| "requestIdleCallback"
| "cancelIdleCallback"
| "performance"
| "queueMicrotask";
interface FakeTimerInstallOpts {
/**
* Installs fake timers with the specified unix epoch (default: 0)
*/
now?: number | Date | undefined;
/**
* An array with names of global methods and APIs to fake.
* For instance, `vi.useFakeTimer({ toFake: ['setTimeout', 'performance'] })` will fake only `setTimeout()` and `performance.now()`
* @default ['setTimeout', 'clearTimeout', 'setImmediate', 'clearImmediate', 'setInterval', 'clearInterval', 'Date']
*/
toFake?: FakeMethod[] | undefined;
/**
* The maximum number of timers that will be run when calling runAll()
* @default 10000
*/
loopLimit?: number | undefined;
/**
* Tells @sinonjs/fake-timers to increment mocked time automatically based on the real system time shift (e.g. the mocked time will be incremented by
* 20ms for every 20ms change in the real system time) (default: false)
*/
shouldAdvanceTime?: boolean | undefined;
/**
* Relevant only when using with shouldAdvanceTime: true. increment mocked time by advanceTimeDelta ms every advanceTimeDelta ms change
* in the real system time (default: 20)
*/
advanceTimeDelta?: number | undefined;
/**
* Tells FakeTimers to clear 'native' (i.e. not fake) timers by delegating to their respective handlers.
* @default true
*/
shouldClearNativeTimers?: boolean | undefined;
}
type BuiltinPool = 'browser' | 'threads' | 'forks' | 'vmThreads' | 'vmForks' | 'typescript';
type Pool = BuiltinPool | (string & {});
interface PoolOptions extends Record<string, unknown> {
/**
* Run tests in `node:worker_threads`.
*
* Test isolation (when enabled) is done by spawning a new thread for each test file.
*
* This pool is used by default.
*/
threads?: ThreadsOptions & WorkerContextOptions;
/**
* Run tests in `node:child_process` using [`fork()`](https://nodejs.org/api/child_process.html#child_processforkmodulepath-args-options)
*
* Test isolation (when enabled) is done by spawning a new child process for each test file.
*/
forks?: ForksOptions & WorkerContextOptions;
/**
* Run tests in isolated `node:vm`.
* Test files are run parallel using `node:worker_threads`.
*
* This makes tests run faster, but VM module is unstable. Your tests might leak memory.
*/
vmThreads?: ThreadsOptions & VmOptions;
/**
* Run tests in isolated `node:vm`.
*
* Test files are run parallel using `node:child_process` [`fork()`](https://nodejs.org/api/child_process.html#child_processforkmodulepath-args-options)
*
* This makes tests run faster, but VM module is unstable. Your tests might leak memory.
*/
vmForks?: ForksOptions & VmOptions;
}
interface ThreadsOptions {
/** Minimum amount of threads to use */
minThreads?: number;
/** Maximum amount of threads to use */
maxThreads?: number;
/**
* Run tests inside a single thread.
*
* @default false
*/
singleThread?: boolean;
/**
* Use Atomics to synchronize threads
*
* This can improve performance in some cases, but might cause segfault in older Node versions.
*
* @default false
*/
useAtomics?: boolean;
}
interface ForksOptions {
/** Minimum amount of child processes to use */
minForks?: number;
/** Maximum amount of child processes to use */
maxForks?: number;
/**
* Run tests inside a single fork.
*
* @default false
*/
singleFork?: boolean;
}
interface WorkerContextOptions {
/**
* Isolate test environment by recycling `worker_threads` or `child_process` after each test
*
* @default true
*/
isolate?: boolean;
/**
* Pass additional arguments to `node` process when spawning `worker_threads` or `child_process`.
*
* See [Command-line API | Node.js](https://nodejs.org/docs/latest/api/cli.html) for more information.
*
* Set to `process.execArgv` to pass all arguments of the current process.
*
* Be careful when using, it as some options may crash worker, e.g. --prof, --title. See https://github.com/nodejs/node/issues/41103
*
* @default [] // no execution arguments are passed
*/
execArgv?: string[];
}
interface VmOptions {
/**
* Specifies the memory limit for `worker_thread` or `child_process` before they are recycled.
* If you see memory leaks, try to tinker this value.
*/
memoryLimit?: string | number;
/** Isolation is always enabled */
isolate?: true;
/**
* Pass additional arguments to `node` process when spawning `worker_threads` or `child_process`.
*
* See [Command-line API | Node.js](https://nodejs.org/docs/latest/api/cli.html) for more information.
*
* Set to `process.execArgv` to pass all arguments of the current process.
*
* Be careful when using, it as some options may crash worker, e.g. --prof, --title. See https://github.com/nodejs/node/issues/41103
*
* @default [] // no execution arguments are passed
*/
execArgv?: string[];
}
interface Options {
/**
Show the cursor. This can be useful when a CLI accepts input from a user.
@example
```
import {createLogUpdate} from 'log-update';
// Write output but don't hide the cursor
const log = createLogUpdate(process.stdout, {
showCursor: true
});
```
*/
readonly showCursor?: boolean;
}
type LogUpdateMethods = {
/**
Clear the logged output.
*/
clear(): void;
/**
Persist the logged output. Useful if you want to start a new log session below the current one.
*/
done(): void;
};
/**
Log to `stdout` by overwriting the previous output in the terminal.
@param text - The text to log to `stdout`.
@example
```
import logUpdate from 'log-update';
const frames = ['-', '\\', '|', '/'];
let index = 0;
setInterval(() => {
const frame = frames[index = ++index % frames.length];
logUpdate(
`
♥♥
${frame} unicorns ${frame}
♥♥
`
);
}, 80);
```
*/
declare const logUpdate: ((...text: string[]) => void) & LogUpdateMethods;
/**
Get a `logUpdate` method that logs to the specified stream.
@param stream - The stream to log to.
@example
```
import {createLogUpdate} from 'log-update';
// Write output but don't hide the cursor
const log = createLogUpdate(process.stdout);
```
*/
declare function createLogUpdate(
stream: NodeJS.WritableStream,
options?: Options
): typeof logUpdate;
interface ParsedFile extends File {
start: number;
end: number;
}
interface ParsedTest extends Test$1 {
start: number;
end: number;
}
interface ParsedSuite extends Suite {
start: number;
end: number;
}
interface LocalCallDefinition {
start: number;
end: number;
name: string;
type: 'suite' | 'test';
mode: 'run' | 'skip' | 'only' | 'todo';
task: ParsedSuite | ParsedFile | ParsedTest;
}
interface FileInformation {
file: File;
filepath: string;
parsed: string;
map: RawSourceMap | null;
definitions: LocalCallDefinition[];
}
declare class TypeCheckError extends Error {
message: string;
stacks: ParsedStack[];
name: string;
constructor(message: string, stacks: ParsedStack[]);
}
interface TypecheckResults {
files: File[];
sourceErrors: TypeCheckError[];
time: number;
}
type Callback<Args extends Array<any> = []> = (...args: Args) => Awaitable<void>;
declare class Typechecker {
protected ctx: WorkspaceProject;
private _onParseStart?;
private _onParseEnd?;
private _onWatcherRerun?;
private _result;
private _startTime;
private _output;
private _tests;
private tempConfigPath?;
private allowJs?;
private process?;
protected files: string[];
constructor(ctx: WorkspaceProject);
setFiles(files: string[]): void;
onParseStart(fn: Callback): void;
onParseEnd(fn: Callback<[TypecheckResults]>): void;
onWatcherRerun(fn: Callback): void;
protected collectFileTests(filepath: string): Promise<FileInformation | null>;
protected getFiles(): string[];
collectTests(): Promise<Record<string, FileInformation>>;
protected markPassed(file: File): void;
protected prepareResults(output: string): Promise<{
files: File[];
sourceErrors: TypeCheckError[];
time: number;
}>;
protected parseTscLikeOutput(output: string): Promise<Map<string, {
error: TypeCheckError;
originalError: TscErrorInfo;
}[]>>;
clear(): Promise<void>;
stop(): Promise<void>;
protected ensurePackageInstalled(ctx: Vitest, checker: string): Promise<void>;
prepare(): Promise<void>;
getExitCode(): number | false;
getOutput(): string;
start(): Promise<void>;
getResult(): TypecheckResults;
getTestFiles(): File[];
getTestPacks(): TaskResultPack[];
}
interface ErrorOptions {
type?: string;
fullStack?: boolean;
project?: WorkspaceProject;
}
declare class Logger {
ctx: Vitest;
outputStream: NodeJS.WriteStream | Writable;
errorStream: NodeJS.WriteStream | Writable;
logUpdate: ReturnType<typeof createLogUpdate>;
private _clearScreenPending;
private _highlights;
console: Console;
constructor(ctx: Vitest, outputStream?: NodeJS.WriteStream | Writable, errorStream?: NodeJS.WriteStream | Writable);
log(...args: any[]): void;
error(...args: any[]): void;
warn(...args: any[]): void;
clearFullScreen(message: string): void;
clearScreen(message: string, force?: boolean): void;
private _clearScreen;
printError(err: unknown, options?: ErrorOptions): Promise<void>;
clearHighlightCache(filename?: string): void;
highlight(filename: string, source: string): string;
printNoTestFound(filters?: string[]): void;
printBanner(): void;
printUnhandledErrors(errors: unknown[]): Promise<void>;
printSourceTypeErrors(errors: TypeCheckError[]): Promise<void>;
}
interface BrowserProviderInitializationOptions {
browser: string;
options?: BrowserProviderOptions;
}
interface BrowserProvider {
name: string;
getSupportedBrowsers: () => readonly string[];
openPage: (url: string) => Awaitable$1<void>;
close: () => Awaitable$1<void>;
initialize(ctx: WorkspaceProject, options: BrowserProviderInitializationOptions): Awaitable$1<void>;
}
interface BrowserProviderOptions {
}
interface BrowserConfigOptions {
/**
* if running tests in the browser should be the default
*
* @default false
*/
enabled?: boolean;
/**
* Name of the browser
*/
name: string;
/**
* Browser provider
*
* @default 'webdriverio'
*/
provider?: 'webdriverio' | 'playwright' | 'none' | (string & {});
/**
* Options that are passed down to a browser provider.
* To support type hinting, add one of the types to your tsconfig.json "compilerOptions.types" field:
*
* - for webdriverio: `@vitest/browser/providers/webdriverio`
* - for playwright: `@vitest/browser/providers/playwright`
*
* @example
* { playwright: { launch: { devtools: true } }
*/
providerOptions?: BrowserProviderOptions;
/**
* enable headless mode
*
* @default process.env.CI
*/
headless?: boolean;
/**
* Serve API options.
*
* The default port is 63315.
*/
api?: ApiConfig | number;
/**
* Update ESM imports so they can be spied/stubbed with vi.spyOn.
* Enabled by default when running in browser.
*
* @default false
* @experimental
*/
slowHijackESM?: boolean;
/**
* Isolate test environment after each test
*
* @default true
*/
isolate?: boolean;
/**
* Run test files in parallel. Fallbacks to `test.fileParallelism`.
*
* @default test.fileParallelism
*/
fileParallelism?: boolean;
/**
* Scripts injected into the tester iframe.
*/
testerScripts?: BrowserScript[];
/**
* Scripts injected into the main window.
*/
indexScripts?: BrowserScript[];
}
interface BrowserScript {
/**
* If "content" is provided and type is "module", this will be its identifier.
*
* If you are using TypeScript, you can add `.ts` extension here for example.
* @default `injected-${index}.js`
*/
id?: string;
/**
* JavaScript content to be injected. This string is processed by Vite plugins if type is "module".
*
* You can use `id` to give Vite a hint about the file extension.
*/
content?: string;
/**
* Path to the script. This value is resolved by Vite so it can be a node module or a file path.
*/
src?: string;
/**
* If the script should be loaded asynchronously.
*/
async?: boolean;
/**
* Script type.
* @default 'module'
*/
type?: string;
}
interface ResolvedBrowserOptions extends BrowserConfigOptions {
enabled: boolean;
headless: boolean;
isolate: boolean;
api: ApiConfig;
}
interface InitializeProjectOptions extends UserWorkspaceConfig {
workspaceConfigPath: string;
extends?: string;
}
declare class WorkspaceProject {
path: string | number;
ctx: Vitest;
options?: InitializeProjectOptions | undefined;
configOverride: Partial<ResolvedConfig> | undefined;
config: ResolvedConfig;
server: ViteDevServer;
vitenode: ViteNodeServer;
runner: ViteNodeRunner;
browser?: ViteDevServer;
typechecker?: Typechecker;
closingPromise: Promise<unknown> | undefined;
browserProvider: BrowserProvider | undefined;
browserState: {
files: string[];
resolve: () => void;
reject: (v: unknown) => void;
} | undefined;
testFilesList: string[] | null;
readonly id: string;
readonly tmpDir: string;
private _globalSetups;
private _provided;
constructor(path: string | number, ctx: Vitest, options?: InitializeProjectOptions | undefined);
getName(): string;
isCore(): boolean;
provide: <T extends never>(key: T, value: ProvidedContext[T]) => void;
getProvidedContext(): ProvidedContext;
initializeGlobalSetup(): Promise<void>;
teardownGlobalSetup(): Promise<void>;
get logger(): Logger;
getModulesByFilepath(file: string): Set<vite.ModuleNode>;
getModuleById(id: string): vite.ModuleNode | undefined;
getSourceMapModuleById(id: string): TransformResult$1['map'] | undefined;
getBrowserSourceMapModuleById(id: string): TransformResult$1['map'] | undefined;
get reporters(): Reporter[];
globTestFiles(filters?: string[]): Promise<string[]>;
globAllTestFiles(include: string[], exclude: string[], includeSource: string[] | undefined, cwd: string): Promise<string[]>;
isTestFile(id: string): boolean | null;
globFiles(include: string[], exclude: string[], cwd: string): Promise<string[]>;
isTargetFile(id: string, source?: string): Promise<boolean>;
isInSourceTestFile(code: string): boolean;
filterFiles(testFiles: string[], filters: string[], dir: string): string[];
initBrowserServer(configFile: string | undefined): Promise<void>;
static createBasicProject(ctx: Vitest): WorkspaceProject;
static createCoreProject(ctx: Vitest): Promise<WorkspaceProject>;
setServer(options: UserConfig, server: ViteDevServer): Promise<void>;
isBrowserEnabled(): boolean;
getSerializableConfig(): ResolvedConfig;
close(): Promise<unknown>;
private clearTmpDir;
initBrowserProvider(): Promise<void>;
}
type WorkspaceSpec = [project: WorkspaceProject, testFile: string];
type RunWithFiles = (files: WorkspaceSpec[], invalidates?: string[]) => Awaitable$1<void>;
interface ProcessPool {
name: string;
runTests: RunWithFiles;
close?: () => Awaitable$1<void>;
}
type Awaitable<T> = T | PromiseLike<T>;
type Nullable<T> = T | null | undefined;
type Arrayable<T> = T | Array<T>;
type ArgumentsType$1<T> = T extends (...args: infer U) => any ? U : never;
type MutableArray<T extends readonly any[]> = {
-readonly [k in keyof T]: T[k];
};
interface Constructable {
new (...args: any[]): any;
}
interface ModuleCache {
promise?: Promise<any>;
exports?: any;
code?: string;
}
interface EnvironmentReturn {
teardown: (global: any) => Awaitable<void>;
}
interface VmEnvironmentReturn {
getVmContext: () => {
[key: string]: any;
};
teardown: () => Awaitable<void>;
}
interface Environment {
name: string;
transformMode: 'web' | 'ssr';
setupVM?: (options: Record<string, any>) => Awaitable<VmEnvironmentReturn>;
setup: (global: any, options: Record<string, any>) => Awaitable<EnvironmentReturn>;
}
interface UserConsoleLog {
content: string;
type: 'stdout' | 'stderr';
taskId?: string;
time: number;
size: number;
}
interface ModuleGraphData {
graph: Record<string, string[]>;
externalized: string[];
inlined: string[];
}
type OnServerRestartHandler = (reason?: string) => Promise<void> | void;
interface ProvidedContext {
}
declare class StateManager {
filesMap: Map<string, File[]>;
pathsSet: Set<string>;
idMap: Map<string, Task>;
taskFileMap: WeakMap<Task, File>;
errorsSet: Set<unknown>;
processTimeoutCauses: Set<string>;
catchError(err: unknown, type: string): void;
clearErrors(): void;
getUnhandledErrors(): unknown[];
addProcessTimeoutCause(cause: string): void;
getProcessTimeoutCauses(): string[];
getPaths(): string[];
getFiles(keys?: string[]): File[];
getFilepaths(): string[];
getFailedFilepaths(): string[];
collectPaths(paths?: string[]): void;
collectFiles(files?: File[]): void;
clearFiles(_project: {
config: {
name: string;
};
}, paths?: string[]): void;
updateId(task: Task): void;
updateTasks(packs: TaskResultPack[]): void;
updateUserLog(log: UserConsoleLog): void;
getCountOfFailedTests(): number;
cancelFiles(files: string[], root: string, projectName: string): void;
}
interface SuiteResultCache {
failed: boolean;
duration: number;
}
declare class ResultsCache {
private cache;
private workspacesKeyMap;
private cachePath;
private version;
private root;
getCachePath(): string | null;
setConfig(root: string, config: ResolvedConfig['cache']): void;
getResults(key: string): SuiteResultCache | undefined;
readFromCache(): Promise<void>;
updateResults(files: File[]): void;
removeFromCache(filepath: string): void;
writeToCache(): Promise<void>;
}
type FileStatsCache = Pick<Stats, 'size'>;
declare class FilesStatsCache {
cache: Map<string, FileStatsCache>;
getStats(key: string): FileStatsCache | undefined;
populateStats(root: string, specs: WorkspaceSpec[]): Promise<void>;
updateStats(fsPath: string, key: string): Promise<void>;
removeStats(fsPath: string): void;
}
declare class VitestCache {
results: ResultsCache;
stats: FilesStatsCache;
getFileTestResults(key: string): SuiteResultCache | undefined;
getFileStats(key: string): {
size: number;
} | undefined;
static resolveCacheDir(root: string, dir?: string, projectName?: string): string;
}
declare class VitestPackageInstaller {
ensureInstalled(dependency: string, root: string): Promise<boolean>;
}
interface VitestOptions {
packageInstaller?: VitestPackageInstaller;
stdin?: NodeJS.ReadStream;
stdout?: NodeJS.WriteStream | Writable;
stderr?: NodeJS.WriteStream | Writable;
}
declare class Vitest {
readonly mode: VitestRunMode;
config: ResolvedConfig;
configOverride: Partial<ResolvedConfig>;
server: ViteDevServer;
state: StateManager;
snapshot: SnapshotManager;
cache: VitestCache;
reporters: Reporter[];
coverageProvider: CoverageProvider | null | undefined;
logger: Logger;
pool: ProcessPool | undefined;
vitenode: ViteNodeServer;
invalidates: Set<string>;
changedTests: Set<string>;
watchedTests: Set<string>;
filenamePattern?: string;
runningPromise?: Promise<void>;
closingPromise?: Promise<void>;
isCancelling: boolean;
isFirstRun: boolean;
restartsCount: number;
runner: ViteNodeRunner;
packageInstaller: VitestPackageInstaller;
private coreWorkspaceProject;
private resolvedProjects;
projects: WorkspaceProject[];
private projectsTestFiles;
distPath: string;
constructor(mode: VitestRunMode, options?: VitestOptions);
private _onRestartListeners;
private _onClose;
private _onSetServer;
private _onCancelListeners;
setServer(options: UserConfig, server: ViteDevServer, cliOptions: UserConfig): Promise<void>;
private createCoreProject;
getCoreWorkspaceProject(): WorkspaceProject;
getProjectByTaskId(taskId: string): WorkspaceProject;
private getWorkspaceConfigPath;
private resolveWorkspace;
private initCoverageProvider;
private initBrowserProviders;
start(filters?: string[]): Promise<void>;
init(): Promise<void>;
private getTestDependencies;
filterTestsBySource(specs: WorkspaceSpec[]): Promise<WorkspaceSpec[]>;
getProjectsByTestFile(file: string): WorkspaceSpec[];
initializeGlobalSetup(paths: WorkspaceSpec[]): Promise<void>;
private initializeDistPath;
runFiles(paths: WorkspaceSpec[], allTestsRun: boolean): Promise<void>;
cancelCurrentRun(reason: CancelReason): Promise<void>;
rerunFiles(files?: string[], trigger?: string): Promise<void>;
changeProjectName(pattern: string): Promise<void>;
changeNamePattern(pattern: string, files?: string[], trigger?: string): Promise<void>;
changeFilenamePattern(pattern: string, files?: string[]): Promise<void>;
rerunFailed(): Promise<void>;
updateSnapshot(files?: string[]): Promise<void>;
private _rerunTimer;
private scheduleRerun;
getModuleProjects(filepath: string): WorkspaceProject[];
/**
* Watch only the specified tests. If no tests are provided, all tests will be watched.
*/
watchTests(tests: string[]): void;
private unregisterWatcher;
private registerWatcher;
/**
* @returns A value indicating whether rerun is needed (changedTests was mutated)
*/
private handleFileChanged;
private reportCoverage;
close(): Promise<void>;
/**
* Close the thread pool and exit the process
*/
exit(force?: boolean): Promise<void>;
report<T extends keyof Reporter>(name: T, ...args: ArgumentsType$1<Reporter[T]>): Promise<void>;
getTestFilepaths(): Promise<string[]>;
globTestFiles(filters?: string[]): Promise<WorkspaceSpec[]>;
shouldKeepServer(): boolean;
onServerRestart(fn: OnServerRestartHandler): void;
onAfterSetServer(fn: OnServerRestartHandler): void;
onCancel(fn: (reason: CancelReason) => void): void;
onClose(fn: () => void): void;
}
interface TestSequencer {
/**
* Slicing tests into shards. Will be run before `sort`.
* Only run, if `shard` is defined.
*/
shard: (files: WorkspaceSpec[]) => Awaitable<WorkspaceSpec[]>;
sort: (files: WorkspaceSpec[]) => Awaitable<WorkspaceSpec[]>;
}
interface TestSequencerConstructor {
new (ctx: Vitest): TestSequencer;
}
declare abstract class BaseReporter implements Reporter {
start: number;
end: number;
watchFilters?: string[];
isTTY: boolean;
ctx: Vitest;
private _filesInWatchMode;
private _lastRunTimeout;
private _lastRunTimer;
private _lastRunCount;
private _timeStart;
private _offUnhandledRejection?;
constructor();
get mode(): VitestRunMode;
onInit(ctx: Vitest): void;
relative(path: string): string;
onFinished(files?: File[], errors?: unknown[]): Promise<void>;
onTaskUpdate(packs: TaskResultPack[]): void;
onWatcherStart(files?: File[], errors?: unknown[]): Promise<void>;
private resetLastRunLog;
onWatcherRerun(files: string[], trigger?: string): Promise<void>;
onUserConsoleLog(log: UserConsoleLog): void;
shouldLog(log: UserConsoleLog): boolean;
onServerRestart(reason?: string): void;
reportSummary(files: File[], errors: unknown[]): Promise<void>;
reportTestSummary(files: File[], errors: unknown[]): Promise<void>;
private printErrorsSummary;
reportBenchmarkSummary(files: File[]): Promise<void>;
private printTaskErrors;
registerUnhandledRejection(): void;
}
declare class BasicReporter extends BaseReporter {
isTTY: boolean;
reportSummary(files: File[], errors: unknown[]): Promise<void>;
}
interface ListRendererOptions {
renderSucceed?: boolean;
logger: Logger;
showHeap: boolean;
slowTestThreshold: number;
mode: VitestRunMode;
}
declare function createListRenderer(_tasks: Task[], options: ListRendererOptions): {
start(): any;
update(_tasks: Task[]): any;
stop(): Promise<any>;
clear(): void;
};
declare class DefaultReporter extends BaseReporter {
renderer?: ReturnType<typeof createListRenderer>;
rendererOptions: ListRendererOptions;
private renderSucceedDefault?;
onPathsCollected(paths?: string[]): void;
onTestRemoved(trigger?: string): Promise<void>;
onCollected(): void;
onFinished(files?: _vitest_runner.File[], errors?: unknown[]): Promise<void>;
onWatcherStart(files?: _vitest_runner.File[], errors?: unknown[]): Promise<void>;
stopListRender(): Promise<void>;
onWatcherRerun(files: string[], trigger?: string): Promise<void>;
onUserConsoleLog(log: UserConsoleLog): void;
}
interface DotRendererOptions {
logger: Logger;
}
declare function createDotRenderer(_tasks: Task[], options: DotRendererOptions): {
start(): any;
update(_tasks: Task[]): any;
stop(): Promise<any>;
clear(): void;
};
declare class DotReporter extends BaseReporter {
renderer?: ReturnType<typeof createDotRenderer>;
onCollected(): void;
onFinished(files?: _vitest_runner.File[], errors?: unknown[]): Promise<void>;
onWatcherStart(): Promise<void>;
stopListRender(): Promise<void>;
onWatcherRerun(files: string[], trigger?: string): Promise<void>;
onUserConsoleLog(log: UserConsoleLog): void;
}
type Status = 'passed' | 'failed' | 'skipped' | 'pending' | 'todo' | 'disabled';
type Milliseconds = number;
interface Callsite {
line: number;
column: number;
}
interface JsonAssertionResult {
ancestorTitles: Array<string>;
fullName: string;
status: Status;
title: string;
duration?: Milliseconds | null;
failureMessages: Array<string>;
location?: Callsite | null;
}
interface JsonTestResult {
message: string;
name: string;
status: 'failed' | 'passed';
startTime: number;
endTime: number;
assertionResults: Array<JsonAssertionResult>;
}
interface JsonTestResults {
numFailedTests: number;
numFailedTestSuites: number;
numPassedTests: number;
numPassedTestSuites: number;
numPendingTests: number;
numPendingTestSuites: number;
numTodoTests: number;
numTotalTests: number;
numTotalTestSuites: number;
startTime: number;
success: boolean;
testResults: Array<JsonTestResult>;
}
interface JsonOptions$1 {
outputFile?: string;
}
declare class JsonReporter implements Reporter {
start: number;
ctx: Vitest;
options: JsonOptions$1;
constructor(options: JsonOptions$1);
onInit(ctx: Vitest): void;
protected logTasks(files: File[]): Promise<void>;
onFinished(files?: File[]): Promise<void>;
/**
* Writes the report to an output file if specified in the config,
* or logs it to the console otherwise.
* @param report
*/
writeReport(report: string): Promise<void>;
protected getFailureLocation(test: Task): Promise<Callsite | undefined>;
}
declare class VerboseReporter extends DefaultReporter {
constructor();
onTaskUpdate(packs: TaskResultPack[]): void;
}
interface Reporter {
onInit?: (ctx: Vitest) => void;
onPathsCollected?: (paths?: string[]) => Awaitable<void>;
onCollected?: (files?: File[]) => Awaitable<void>;
onFinished?: (files?: File[], errors?: unknown[]) => Awaitable<void>;
onTaskUpdate?: (packs: TaskResultPack[]) => Awaitable<void>;
onTestRemoved?: (trigger?: string) => Awaitable<void>;
onWatcherStart?: (files?: File[], errors?: unknown[]) => Awaitable<void>;
onWatcherRerun?: (files: string[], trigger?: string) => Awaitable<void>;
onServerRestart?: (reason?: string) => Awaitable<void>;
onUserConsoleLog?: (log: UserConsoleLog) => Awaitable<void>;
onProcessTimeout?: () => Awaitable<void>;
}
declare class TapReporter implements Reporter {
protected ctx: Vitest;
private logger;
onInit(ctx: Vitest): void;
static getComment(task: Task): string;
private logErrorDetails;
protected logTasks(tasks: Task[]): void;
onFinished(files?: _vitest_runner.File[]): Promise<void>;
}
interface JUnitOptions {
outputFile?: string;
classname?: string;
suiteName?: string;
/**
* Write <system-out> and <system-err> for console output
* @default true
*/
includeConsoleOutput?: boolean;
/**
* Add <testcase file="..."> attribute (validated on CIRCLE CI and GitLab CI)
* @default false
*/
addFileAttribute?: boolean;
}
declare class JUnitReporter implements Reporter {
private ctx;
private reportFile?;
private baseLog;
private logger;
private _timeStart;
private fileFd?;
private options;
constructor(options: JUnitOptions);
onInit(ctx: Vitest): Promise<void>;
writeElement(name: string, attrs: Record<string, any>, children: () => Promise<void>): Promise<void>;
writeLogs(task: Task, type: 'err' | 'out'): Promise<void>;
writeTasks(tasks: Task[], filename: string): Promise<void>;
onFinished(files?: _vitest_runner.File[]): Promise<void>;
}
declare class TapFlatReporter extends TapReporter {
onInit(ctx: Vitest): void;
onFinished(files?: _vitest_runner.File[]): Promise<void>;
}
declare class HangingProcessReporter implements Reporter {
whyRunning: (() => void) | undefined;
onInit(): void;
onProcessTimeout(): void;
}
declare class GithubActionsReporter implements Reporter {
ctx: Vitest;
onInit(ctx: Vitest): void;
onFinished(files?: File[], errors?: unknown[]): Promise<void>;
}
interface TableRendererOptions {
renderSucceed?: boolean;
logger: Logger;
showHeap: boolean;
slowTestThreshold: number;
compare?: FlatBenchmarkReport;
}
declare function createTableRenderer(_tasks: Task[], options: TableRendererOptions): {
start(): any;
update(_tasks: Task[]): any;
stop(): Promise<any>;
clear(): void;
};
declare class TableReporter extends BaseReporter {
renderer?: ReturnType<typeof createTableRenderer>;
rendererOptions: TableRendererOptions;
onTestRemoved(trigger?: string): Promise<void>;
onCollected(): Promise<void>;
onTaskUpdate(packs: TaskResultPack[]): void;
onFinished(files?: File[], errors?: unknown[]): Promise<void>;
onWatcherStart(): Promise<void>;
stopListRender(): Promise<void>;
onWatcherRerun(files: string[], trigger?: string): Promise<void>;
onUserConsoleLog(log: UserConsoleLog): void;
}
interface FlatBenchmarkReport {
[id: string]: FormattedBenchmarkResult;
}
type FormattedBenchmarkResult = Omit<BenchmarkResult, 'samples'> & {
id: string;
sampleCount: number;
};
declare const BenchmarkReportsMap: {
default: typeof TableReporter;
verbose: typeof VerboseReporter;
};
type BenchmarkBuiltinReporters = keyof typeof BenchmarkReportsMap;
declare const ReportersMap: {
default: typeof DefaultReporter;
basic: typeof BasicReporter;
verbose: typeof VerboseReporter;
dot: typeof DotReporter;
json: typeof JsonReporter;
tap: typeof TapReporter;
'tap-flat': typeof TapFlatReporter;
junit: typeof JUnitReporter;
'hanging-process': typeof HangingProcessReporter;
'github-actions': typeof GithubActionsReporter;
};
type BuiltinReporters = keyof typeof ReportersMap;
interface BuiltinReporterOptions {
'default': never;
'basic': never;
'verbose': never;
'dot': never;
'json': JsonOptions$1;
'tap': never;
'tap-flat': never;
'junit': JUnitOptions;
'hanging-process': never;
'html': {
outputFile?: string;
};
}
type ChaiConfig = Omit<Partial<typeof chai.config>, 'useProxy' | 'proxyExcludedKeys'>;
interface Node {
isRoot(): boolean;
visit(visitor: Visitor, state: any): void;
}
interface Visitor<N extends Node = Node> {
onStart(root: N, state: any): void;
onSummary(root: N, state: any): void;
onDetail(root: N, state: any): void;
onSummaryEnd(root: N, state: any): void;
onEnd(root: N, state: any): void;
}
interface FileOptions {
file: string;
}
interface ProjectOptions {
projectRoot: string;
}
interface ReportOptions {
clover: CloverOptions;
cobertura: CoberturaOptions;
"html-spa": HtmlSpaOptions;
html: HtmlOptions;
json: JsonOptions;
"json-summary": JsonSummaryOptions;
lcov: LcovOptions;
lcovonly: LcovOnlyOptions;
none: never;
teamcity: TeamcityOptions;
text: TextOptions;
"text-lcov": TextLcovOptions;
"text-summary": TextSummaryOptions;
}
interface CloverOptions extends FileOptions, ProjectOptions {}
interface CoberturaOptions extends FileOptions, ProjectOptions {}
interface HtmlSpaOptions extends HtmlOptions {
metricsToShow: Array<"lines" | "branches" | "functions" | "statements">;
}
interface HtmlOptions {
verbose: boolean;
skipEmpty: boolean;
subdir: string;
linkMapper: LinkMapper;
}
type JsonOptions = FileOptions;
type JsonSummaryOptions = FileOptions;
interface LcovOptions extends FileOptions, ProjectOptions {}
interface LcovOnlyOptions extends FileOptions, ProjectOptions {}
interface TeamcityOptions extends FileOptions {
blockName: string;
}
interface TextOptions extends FileOptions {
maxCols: number;
skipEmpty: boolean;
skipFull: boolean;
}
type TextLcovOptions = ProjectOptions;
type TextSummaryOptions = FileOptions;
interface LinkMapper {
getPath(node: string | Node): string;
relativePath(source: string | Node, target: string | Node): string;
assetPath(node: Node, name: string): string;
}
type ArgumentsType<T> = T extends (...args: infer A) => any ? A : never;
type ReturnType$1<T> = T extends (...args: any) => infer R ? R : never;
type PromisifyFn<T> = ReturnType$1<T> extends Promise<any> ? T : (...args: ArgumentsType<T>) => Promise<Awaited<ReturnType$1<T>>>;
type BirpcResolver = (name: string, resolved: (...args: unknown[]) => unknown) => ((...args: unknown[]) => unknown) | undefined;
interface ChannelOptions {
/**
* Function to post raw message
*/
post: (data: any, ...extras: any[]) => any | Promise<any>;
/**
* Listener to receive raw message
*/
on: (fn: (data: any, ...extras: any[]) => void) => any | Promise<any>;
/**
* Custom function to serialize data
*
* by default it passes the data as-is
*/
serialize?: (data: any) => any;
/**
* Custom function to deserialize data
*
* by default it passes the data as-is
*/
deserialize?: (data: any) => any;
}
interface EventOptions<Remote> {
/**
* Names of remote functions that do not need response.
*/
eventNames?: (keyof Remote)[];
/**
* Maximum timeout for waiting for response, in milliseconds.
*
* @default 60_000
*/
timeout?: number;
/**
* Custom resolver to resolve function to be called
*
* For advanced use cases only
*/
resolver?: BirpcResolver;
/**
* Custom error handler
*/
onError?: (error: Error, functionName: string, args: any[]) => boolean | void;
/**
* Custom error handler for timeouts
*/
onTimeoutError?: (functionName: string, args: any[]) => boolean | void;
}
type BirpcOptions<Remote> = EventOptions<Remote> & ChannelOptions;
type BirpcFn<T> = PromisifyFn<T> & {
/**
* Send event without asking for response
*/
asEvent(...args: ArgumentsType<T>): void;
};
type BirpcReturn<RemoteFunctions, LocalFunctions = Record<string, never>> = {
[K in keyof RemoteFunctions]: BirpcFn<RemoteFunctions[K]>;
} & {
$functions: LocalFunctions;
};
type MockFactoryWithHelper = (importOriginal: <T = unknown>() => Promise<T>) => any;
type MockFactory = () => any;
type MockMap = Map<string, Record<string, string | null | MockFactory>>;
interface PendingSuiteMock {
id: string;
importer: string;
type: 'mock' | 'unmock';
throwIfCached: boolean;
factory?: MockFactory;
}
type TransformMode = 'web' | 'ssr';
interface RuntimeRPC {
fetch: (id: string, environment: TransformMode) => Promise<{
externalize?: string;
id?: string;
}>;
transform: (id: string, environment: TransformMode) => Promise<FetchResult>;
resolveId: (id: string, importer: string | undefined, environment: TransformMode) => Promise<ViteNodeResolveId | null>;
getSourceMap: (id: string, force?: boolean) => Promise<RawSourceMap | undefined>;
onFinished: (files: File[], errors?: unknown[]) => void;
onPathsCollected: (paths: string[]) => void;
onUserConsoleLog: (log: UserConsoleLog) => void;
onUnhandledError: (err: unknown, type: string) => void;
onCollected: (files: File[]) => Promise<void>;
onAfterSuiteRun: (meta: AfterSuiteRunMeta) => void;
onTaskUpdate: (pack: TaskResultPack[]) => Promise<void>;
onCancel: (reason: CancelReason) => void;
getCountOfFailedTests: () => number;
snapshotSaved: (snapshot: SnapshotResult) => void;
resolveSnapshotPath: (testPath: string) => string;
}
interface RunnerRPC {
onCancel: (reason: CancelReason) => void;
}
interface ContextTestEnvironment {
name: VitestEnvironment;
transformMode?: TransformMode;
options: EnvironmentOptions | null;
}
interface ResolvedTestEnvironment {
environment: Environment;
options: EnvironmentOptions | null;
}
interface ContextRPC {
pool: Pool;
worker: string;
workerId: number;
config: ResolvedConfig;
projectName: string;
files: string[];
environment: ContextTestEnvironment;
providedContext: Record<string, any>;
invalidates?: string[];
}
interface WorkerContext extends ContextRPC {
port: MessagePort;
}
type ResolveIdFunction = (id: string, importer?: string) => Promise<ViteNodeResolveId | null>;
interface AfterSuiteRunMeta {
coverage?: unknown;
transformMode: Environment['transformMode'];
projectName?: string;
}
type WorkerRPC = BirpcReturn<RuntimeRPC, RunnerRPC>;
interface WorkerGlobalState {
ctx: ContextRPC;
config: ResolvedConfig;
rpc: WorkerRPC;
current?: Task;
filepath?: string;
environment: Environment;
environmentTeardownRun?: boolean;
onCancel: Promise<CancelReason>;
moduleCache: ModuleCacheMap;
mockMap: MockMap;
providedContext: Record<string, any>;
durations: {
environment: number;
prepare: number;
};
}
type TransformResult = string | Partial<TransformResult$1> | undefined | null | void;
interface CoverageProvider {
name: string;
initialize: (ctx: Vitest) => Promise<void> | void;
resolveOptions: () => ResolvedCoverageOptions;
clean: (clean?: boolean) => void | Promise<void>;
onAfterSuiteRun: (meta: AfterSuiteRunMeta) => void | Promise<void>;
reportCoverage: (reportContext?: ReportContext) => void | Promise<void>;
onFileTransform?: (sourceCode: string, id: string, pluginCtx: any) => TransformResult | Promise<TransformResult>;
}
interface ReportContext {
/** Indicates whether all tests were run. False when only specific tests were run. */
allTestsRun?: boolean;
}
interface CoverageProviderModule {
/**
* Factory for creating a new coverage provider
*/
getProvider: () => CoverageProvider | Promise<CoverageProvider>;
/**
* Executed before tests are run in the worker thread.
*/
startCoverage?: () => unknown | Promise<unknown>;
/**
* Executed on after each run in the worker thread. Possible to return a payload passed to the provider
*/
takeCoverage?: () => unknown | Promise<unknown>;
/**
* Executed after all tests have been run in the worker thread.
*/
stopCoverage?: () => unknown | Promise<unknown>;
}
type CoverageReporter = keyof ReportOptions | (string & {});
type CoverageReporterWithOptions<ReporterName extends CoverageReporter = CoverageReporter> = ReporterName extends keyof ReportOptions ? ReportOptions[ReporterName] extends never ? [ReporterName, {}] : [ReporterName, Partial<ReportOptions[ReporterName]>] : [ReporterName, Record<string, unknown>];
type Provider = 'v8' | 'istanbul' | 'custom' | undefined;
type CoverageOptions<T extends Provider = Provider> = T extends 'istanbul' ? ({
provider: T;
} & CoverageIstanbulOptions) : T extends 'v8' ? ({
/**
* Provider to use for coverage collection.
*
* @default 'v8'
*/
provider: T;
} & CoverageV8Options) : T extends 'custom' ? ({
provider: T;
} & CustomProviderOptions) : ({
provider?: T;
} & (CoverageV8Options));
/** Fields that have default values. Internally these will always be defined. */
type FieldsWithDefaultValues = 'enabled' | 'clean' | 'cleanOnRerun' | 'reportsDirectory' | 'exclude' | 'extension' | 'reportOnFailure' | 'allowExternal' | 'processingConcurrency';
type ResolvedCoverageOptions<T extends Provider = Provider> = CoverageOptions<T> & Required<Pick<CoverageOptions<T>, FieldsWithDefaultValues>> & {
reporter: CoverageReporterWithOptions[];
};
interface BaseCoverageOptions {
/**
* Enables coverage collection. Can be overridden using `--coverage` CLI option.
*
* @default false
*/
enabled?: boolean;
/**
* List of files included in coverage as glob patterns
*
* @default ['**']
*/
include?: string[];
/**
* Extensions for files to be included in coverage
*
* @default ['.js', '.cjs', '.mjs', '.ts', '.tsx', '.jsx', '.vue', '.svelte', '.marko']
*/
extension?: string | string[];
/**
* List of files excluded from coverage as glob patterns
*
* @default ['coverage/**', 'dist/**', '**\/[.]**', 'packages/*\/test?(s)/**', '**\/*.d.ts', '**\/virtual:*', '**\/__x00__*', '**\/\x00*', 'cypress/**', 'test?(s)/**', 'test?(-*).?(c|m)[jt]s?(x)', '**\/*{.,-}{test,spec}?(-d).?(c|m)[jt]s?(x)', '**\/__tests__/**', '**\/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build}.config.*', '**\/vitest.{workspace,projects}.[jt]s?(on)', '**\/.{eslint,mocha,prettier}rc.{?(c|m)js,yml}']
*/
exclude?: string[];
/**
* Whether to include all files, including the untested ones into report
*
* @default true
*/
all?: boolean;
/**
* Clean coverage results before running tests
*
* @default true
*/
clean?: boolean;
/**
* Clean coverage report on watch rerun
*
* @default true
*/
cleanOnRerun?: boolean;
/**
* Directory to write coverage report to
*
* @default './coverage'
*/
reportsDirectory?: string;
/**
* Coverage reporters to use.
* See [istanbul documentation](https://istanbul.js.org/docs/advanced/alternative-reporters/) for detailed list of all reporters.
*
* @default ['text', 'html', 'clover', 'json']
*/
reporter?: Arrayable<CoverageReporter> | (CoverageReporter | [CoverageReporter] | CoverageReporterWithOptions)[];
/**
* Do not show files with 100% statement, branch, and function coverage
*
* @default false
*/
skipFull?: boolean;
/**
* Configurations for thresholds
*
* @example
*
* ```ts
* {
* // Thresholds for all files
* functions: 95,
* branches: 70,
* perFile: true,
* autoUpdate: true,
*
* // Thresholds for utilities
* 'src/utils/**.ts': {
* lines: 100,
* statements: 95,
* }
* }
* ```
*/
thresholds?: Thresholds | ({
[glob: string]: Pick<Thresholds, 'statements' | 'functions' | 'branches' | 'lines'>;
} & Thresholds);
/**
* Watermarks for statements, lines, branches and functions.
*
* Default value is `[50,80]` for each property.
*/
watermarks?: {
statements?: [number, number];
functions?: [number, number];
branches?: [number, number];
lines?: [number, number];
};
/**
* Generate coverage report even when tests fail.
*
* @default false
*/
reportOnFailure?: boolean;
/**
* Collect coverage of files outside the project `root`.
*
* @default false
*/
allowExternal?: boolean;
/**
* Concurrency limit used when processing the coverage results.
* Defaults to `Math.min(20, os.availableParallelism?.() ?? os.cpus().length)`
*/
processingConcurrency?: number;
}
interface CoverageIstanbulOptions extends BaseCoverageOptions {
/**
* Set to array of class method names to ignore for coverage
*
* @default []
*/
ignoreClassMethods?: string[];
}
interface CoverageV8Options extends BaseCoverageOptions {
/**
* Ignore empty lines, comments and other non-runtime code, e.g. Typescript types
*/
ignoreEmptyLines?: boolean;
}
interface CustomProviderOptions extends Pick<BaseCoverageOptions, FieldsWithDefaultValues> {
/** Name of the module or path to a file to load the custom provider from */
customProviderModule: string;
}
interface Thresholds {
/** Set global thresholds to `100` */
100?: boolean;
/** Check thresholds per file. */
perFile?: boolean;
/**
* Update threshold values automatically when current coverage is higher than earlier thresholds
*
* @default false
*/
autoUpdate?: boolean;
/** Thresholds for statements */
statements?: number;
/** Thresholds for functions */
functions?: number;
/** Thresholds for branches */
branches?: number;
/** Thresholds for lines */
lines?: number;
}
interface JSDOMOptions {
/**
* The html content for the test.
*
* @default '<!DOCTYPE html>'
*/
html?: string | Buffer | ArrayBufferLike;
/**
* referrer just affects the value read from document.referrer.
* It defaults to no referrer (which reflects as the empty string).
*/
referrer?: string;
/**
* userAgent affects the value read from navigator.userAgent, as well as the User-Agent header sent while fetching subresources.
*
* @default `Mozilla/5.0 (${process.platform}) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/${jsdomVersion}`
*/
userAgent?: string;
/**
* url sets the value returned by window.location, document.URL, and document.documentURI,
* and affects things like resolution of relative URLs within the document
* and the same-origin restrictions and referrer used while fetching subresources.
*
* @default 'http://localhost:3000'.
*/
url?: string;
/**
* contentType affects the value read from document.contentType, and how the document is parsed: as HTML or as XML.
* Values that are not "text/html" or an XML mime type will throw.
*
* @default 'text/html'.
*/
contentType?: string;
/**
* The maximum size in code units for the separate storage areas used by localStorage and sessionStorage.
* Attempts to store data larger than this limit will cause a DOMException to be thrown. By default, it is set
* to 5,000,000 code units per origin, as inspired by the HTML specification.
*
* @default 5_000_000
*/
storageQuota?: number;
/**
* Enable console?
*
* @default false
*/
console?: boolean;
/**
* jsdom does not have the capability to render visual content, and will act like a headless browser by default.
* It provides hints to web pages through APIs such as document.hidden that their content is not visible.
*
* When the `pretendToBeVisual` option is set to `true`, jsdom will pretend that it is rendering and displaying
* content.
*
* @default true
*/
pretendToBeVisual?: boolean;
/**
* `includeNodeLocations` preserves the location info produced by the HTML parser,
* allowing you to retrieve it with the nodeLocation() method (described below).
*
* It defaults to false to give the best performance,
* and cannot be used with an XML content type since our XML parser does not support location info.
*
* @default false
*/
includeNodeLocations?: boolean | undefined;
/**
* @default 'dangerously'
*/
runScripts?: 'dangerously' | 'outside-only';
/**
* Enable CookieJar
*
* @default false
*/
cookieJar?: boolean;
resources?: 'usable' | any;
}
/**
* Happy DOM options.
*/
interface HappyDOMOptions {
width?: number;
height?: number;
url?: string;
settings?: {
disableJavaScriptEvaluation?: boolean;
disableJavaScriptFileLoading?: boolean;
disableCSSFileLoading?: boolean;
disableIframePageLoading?: boolean;
disableComputedStyleRendering?: boolean;
enableFileSystemHttpRequests?: boolean;
navigator?: {
userAgent?: string;
};
device?: {
prefersColorScheme?: string;
mediaType?: string;
};
};
}
interface BenchmarkUserOptions {
/**
* Include globs for benchmark test files
*
* @default ['**\/*.{bench,benchmark}.?(c|m)[jt]s?(x)']
*/
include?: string[];
/**
* Exclude globs for benchmark test files
* @default ['**\/node_modules/**', '**\/dist/**', '**\/cypress/**', '**\/.{idea,git,cache,output,temp}/**', '**\/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build,eslint,prettier}.config.*']
*/
exclude?: string[];
/**
* Include globs for in-source benchmark test files
*
* @default []
*/
includeSource?: string[];
/**
* Custom reporter for output. Can contain one or more built-in report names, reporter instances,
* and/or paths to custom reporters
*
* @default ['default']
*/
reporters?: Arrayable$1<BenchmarkBuiltinReporters | Reporter>;
/**
* Write test results to a file when the `--reporter=json` option is also specified.
* Also definable individually per reporter by using an object instead.
*/
outputFile?: string | (Partial<Record<BenchmarkBuiltinReporters, string>> & Record<string, string>);
/**
* benchmark output file to compare against
*/
compare?: string;
/**
* benchmark output file
*/
outputJson?: string;
}
interface Benchmark extends Custom {
meta: {
benchmark: true;
result?: TaskResult;
};
}
interface BenchmarkResult extends TaskResult {
name: string;
rank: number;
}
type BenchFunction = (this: Bench) => Promise<void> | void;
type ChainableBenchmarkAPI = ChainableFunction<'skip' | 'only' | 'todo', (name: string | Function, fn?: BenchFunction, options?: Options$1) => void>;
type BenchmarkAPI = ChainableBenchmarkAPI & {
skipIf: (condition: any) => ChainableBenchmarkAPI;
runIf: (condition: any) => ChainableBenchmarkAPI;
};
declare const defaultInclude: string[];
declare const defaultExclude: string[];
declare const coverageConfigDefaults: ResolvedCoverageOptions;
declare const configDefaults: Readonly<{
allowOnly: boolean;
isolate: true;
watch: boolean;
globals: false;
environment: "node";
pool: "threads";
clearMocks: false;
restoreMocks: false;
mockReset: false;
include: string[];
exclude: string[];
testTimeout: number;
hookTimeout: number;
teardownTimeout: number;
watchExclude: string[];
forceRerunTriggers: string[];
update: false;
reporters: never[];
silent: false;
hideSkippedTests: false;
api: false;
ui: false;
uiBase: string;
open: boolean;
css: {
include: never[];
};
coverage: CoverageV8Options;
fakeTimers: {
loopLimit: number;
shouldClearNativeTimers: true;
toFake: ("setTimeout" | "setInterval" | "clearInterval" | "clearTimeout" | "setImmediate" | "clearImmediate" | "Date")[];
};
maxConcurrency: number;
dangerouslyIgnoreUnhandledErrors: false;
typecheck: {
checker: "tsc";
include: string[];
exclude: string[];
};
slowTestThreshold: number;
disableConsoleIntercept: false;
}>;
declare const extraInlineDeps: (string | RegExp)[];
interface UserWorkspaceConfig extends UserConfig$1 {
test?: ProjectConfig;
}
type UserConfigFnObject = (env: ConfigEnv) => UserConfig$1;
type UserConfigFnPromise = (env: ConfigEnv) => Promise<UserConfig$1>;
type UserConfigFn = (env: ConfigEnv) => UserConfig$1 | Promise<UserConfig$1>;
type UserConfigExport = UserConfig$1 | Promise<UserConfig$1> | UserConfigFnObject | UserConfigFnPromise | UserConfigFn;
type UserProjectConfigFn = (env: ConfigEnv) => UserWorkspaceConfig | Promise<UserWorkspaceConfig>;
type UserProjectConfigExport = UserWorkspaceConfig | Promise<UserWorkspaceConfig> | UserProjectConfigFn;
declare function defineConfig(config: UserConfig$1): UserConfig$1;
declare function defineConfig(config: Promise<UserConfig$1>): Promise<UserConfig$1>;
declare function defineConfig(config: UserConfigFnObject): UserConfigFnObject;
declare function defineConfig(config: UserConfigExport): UserConfigExport;
declare function defineProject<T extends UserProjectConfigExport>(config: T): T;
type Workspace = (string | (UserProjectConfigExport & {
extends?: string;
}));
declare function defineWorkspace(config: Workspace[]): Workspace[];
type BuiltinEnvironment = 'node' | 'jsdom' | 'happy-dom' | 'edge-runtime';
type VitestEnvironment = BuiltinEnvironment | (string & Record<never, never>);
type CSSModuleScopeStrategy = 'stable' | 'scoped' | 'non-scoped';
type ApiConfig = Pick<ServerOptions, 'port' | 'strictPort' | 'host' | 'middlewareMode'>;
interface EnvironmentOptions {
/**
* jsdom options.
*/
jsdom?: JSDOMOptions;
happyDOM?: HappyDOMOptions;
[x: string]: unknown;
}
type VitestRunMode = 'test' | 'benchmark';
interface SequenceOptions {
/**
* Class that handles sorting and sharding algorithm.
* If you only need to change sorting, you can extend
* your custom sequencer from `BaseSequencer` from `vitest/node`.
* @default BaseSequencer
*/
sequencer?: TestSequencerConstructor;
/**
* Should files and tests run in random order.
* @default false
*/
shuffle?: boolean | {
/**
* Should files run in random order. Long running tests will not start
* earlier if you enable this option.
* @default false
*/
files?: boolean;
/**
* Should tests run in random order.
* @default false
*/
tests?: boolean;
};
/**
* Should tests run in parallel.
* @default false
*/
concurrent?: boolean;
/**
* Defines how setup files should be ordered
* - 'parallel' will run all setup files in parallel
* - 'list' will run all setup files in the order they are defined in the config file
* @default 'parallel'
*/
setupFiles?: SequenceSetupFiles;
/**
* Seed for the random number generator.
* @default Date.now()
*/
seed?: number;
/**
* Defines how hooks should be ordered
* - `stack` will order "after" hooks in reverse order, "before" hooks will run sequentially
* - `list` will order hooks in the order they are defined
* - `parallel` will run hooks in a single group in parallel
* @default 'parallel'
*/
hooks?: SequenceHooks;
}
type DepsOptimizationOptions = Omit<DepOptimizationConfig, 'disabled' | 'noDiscovery'> & {
enabled?: boolean;
};
interface TransformModePatterns {
/**
* Use SSR transform pipeline for all modules inside specified tests.
* Vite plugins will receive `ssr: true` flag when processing those files.
*
* @default tests with node or edge environment
*/
ssr?: string[];
/**
* First do a normal transform pipeline (targeting browser),
* then then do a SSR rewrite to run the code in Node.
* Vite plugins will receive `ssr: false` flag when processing those files.
*
* @default tests with jsdom or happy-dom environment
*/
web?: string[];
}
interface DepsOptions {
/**
* Enable dependency optimization. This can improve the performance of your tests.
*/
optimizer?: {
web?: DepsOptimizationOptions;
ssr?: DepsOptimizationOptions;
};
web?: {
/**
* Should Vitest process assets (.png, .svg, .jpg, etc) files and resolve them like Vite does in the browser.
*
* These module will have a default export equal to the path to the asset, if no query is specified.
*
* **At the moment, this option only works with `{ pool: 'vmThreads' }`.**
*
* @default true
*/
transformAssets?: boolean;
/**
* Should Vitest process CSS (.css, .scss, .sass, etc) files and resolve them like Vite does in the browser.
*
* If CSS files are disabled with `css` options, this option will just silence UNKNOWN_EXTENSION errors.
*
* **At the moment, this option only works with `{ pool: 'vmThreads' }`.**
*
* @default true
*/
transformCss?: boolean;
/**
* Regexp pattern to match external files that should be transformed.
*
* By default, files inside `node_modules` are externalized and not transformed.
*
* **At the moment, this option only works with `{ pool: 'vmThreads' }`.**
*
* @default []
*/
transformGlobPattern?: RegExp | RegExp[];
};
/**
* Externalize means that Vite will bypass the package to native Node.
*
* Externalized dependencies will not be applied Vite's transformers and resolvers.
* And does not support HMR on reload.
*
* Typically, packages under `node_modules` are externalized.
*
* @deprecated If you rely on vite-node directly, use `server.deps.external` instead. Otherwise, consider using `deps.optimizer.{web,ssr}.exclude`.
*/
external?: (string | RegExp)[];
/**
* Vite will process inlined modules.
*
* This could be helpful to handle packages that ship `.js` in ESM format (that Node can't handle).
*
* If `true`, every dependency will be inlined
*
* @deprecated If you rely on vite-node directly, use `server.deps.inline` instead. Otherwise, consider using `deps.optimizer.{web,ssr}.include`.
*/
inline?: (string | RegExp)[] | true;
/**
* Interpret CJS module's default as named exports
*
* @default true
*/
interopDefault?: boolean;
/**
* When a dependency is a valid ESM package, try to guess the cjs version based on the path.
* This will significantly improve the performance in huge repo, but might potentially
* cause some misalignment if a package have different logic in ESM and CJS mode.
*
* @default false
*
* @deprecated Use `server.deps.fallbackCJS` instead.
*/
fallbackCJS?: boolean;
/**
* A list of directories relative to the config file that should be treated as module directories.
*
* @default ['node_modules']
*/
moduleDirectories?: string[];
}
type InlineReporter = Reporter;
type ReporterName = BuiltinReporters | 'html' | (string & {});
type ReporterWithOptions<Name extends ReporterName = ReporterName> = Name extends keyof BuiltinReporterOptions ? BuiltinReporterOptions[Name] extends never ? [Name, {}] : [Name, Partial<BuiltinReporterOptions[Name]>] : [Name, Record<string, unknown>];
interface InlineConfig {
/**
* Name of the project. Will be used to display in the reporter.
*/
name?: string;
/**
* Benchmark options.
*
* @default {}
*/
benchmark?: BenchmarkUserOptions;
/**
* Include globs for test files
*
* @default ['**\/*.{test,spec}.?(c|m)[jt]s?(x)']
*/
include?: string[];
/**
* Exclude globs for test files
* @default ['**\/node_modules/**', '**\/dist/**', '**\/cypress/**', '**\/.{idea,git,cache,output,temp}/**', '**\/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build,eslint,prettier}.config.*']
*/
exclude?: string[];
/**
* Include globs for in-source test files
*
* @default []
*/
includeSource?: string[];
/**
* Handling for dependencies inlining or externalizing
*
*/
deps?: DepsOptions;
/**
* Vite-node server options
*/
server?: Omit<ViteNodeServerOptions, 'transformMode'>;
/**
* Base directory to scan for the test files
*
* @default `config.root`
*/
dir?: string;
/**
* Register apis globally
*
* @default false
*/
globals?: boolean;
/**
* Running environment
*
* Supports 'node', 'jsdom', 'happy-dom', 'edge-runtime'
*
* If used unsupported string, will try to load the package `vitest-environment-${env}`
*
* @default 'node'
*/
environment?: VitestEnvironment;
/**
* Environment options.
*/
environmentOptions?: EnvironmentOptions;
/**
* Automatically assign environment based on globs. The first match will be used.
* This has effect only when running tests inside Node.js.
*
* Format: [glob, environment-name]
*
* @default []
* @example [
* // all tests in tests/dom will run in jsdom
* ['tests/dom/**', 'jsdom'],
* // all tests in tests/ with .edge.test.ts will run in edge-runtime
* ['**\/*.edge.test.ts', 'edge-runtime'],
* // ...
* ]
*/
environmentMatchGlobs?: [string, VitestEnvironment][];
/**
* Run tests in an isolated environment. This option has no effect on vmThreads pool.
*
* Disabling this option might improve performance if your code doesn't rely on side effects.
*
* @default true
*/
isolate?: boolean;
/**
* Pool used to run tests in.
*
* Supports 'threads', 'forks', 'vmThreads'
*
* @default 'threads'
*/
pool?: Exclude<Pool, 'browser'>;
/**
* Pool options
*/
poolOptions?: PoolOptions;
/**
* Maximum number of workers to run tests in. `poolOptions.{threads,vmThreads}.maxThreads`/`poolOptions.forks.maxForks` has higher priority.
*/
maxWorkers?: number;
/**
* Minimum number of workers to run tests in. `poolOptions.{threads,vmThreads}.minThreads`/`poolOptions.forks.minForks` has higher priority.
*/
minWorkers?: number;
/**
* Should all test files run in parallel. Doesn't affect tests running in the same file.
* Setting this to `false` will override `maxWorkers` and `minWorkers` options to `1`.
*
* @default true
*/
fileParallelism?: boolean;
/**
* Automatically assign pool based on globs. The first match will be used.
*
* Format: [glob, pool-name]
*
* @default []
* @example [
* // all tests in "forks" directory will run using "poolOptions.forks" API
* ['tests/forks/**', 'forks'],
* // all other tests will run based on "poolOptions.threads" option, if you didn't specify other globs
* // ...
* ]
*/
poolMatchGlobs?: [string, Exclude<Pool, 'browser'>][];
/**
* Path to a workspace configuration file
*/
workspace?: string;
/**
* Update snapshot
*
* @default false
*/
update?: boolean;
/**
* Watch mode
*
* @default !process.env.CI
*/
watch?: boolean;
/**
* Project root
*
* @default process.cwd()
*/
root?: string;
/**
* Custom reporter for output. Can contain one or more built-in report names, reporter instances,
* and/or paths to custom reporters.
*
* @default []
*/
reporters?: Arrayable<ReporterName | InlineReporter> | ((ReporterName | InlineReporter) | [ReporterName] | ReporterWithOptions)[];
/**
* Write test results to a file when the --reporter=json` or `--reporter=junit` option is also specified.
* Also definable individually per reporter by using an object instead.
*/
outputFile?: string | (Partial<Record<BuiltinReporters, string>> & Record<string, string>);
/**
* Default timeout of a test in milliseconds
*
* @default 5000
*/
testTimeout?: number;
/**
* Default timeout of a hook in milliseconds
*
* @default 10000
*/
hookTimeout?: number;
/**
* Default timeout to wait for close when Vitest shuts down, in milliseconds
*
* @default 10000
*/
teardownTimeout?: number;
/**
* Silent mode
*
* @default false
*/
silent?: boolean;
/**
* Hide logs for skipped tests
*
* @default false
*/
hideSkippedTests?: boolean;
/**
* Path to setup files
*/
setupFiles?: string | string[];
/**
* Path to global setup files
*/
globalSetup?: string | string[];
/**
* Glob pattern of file paths to be ignore from triggering watch rerun
* @deprecated Use server.watch.ignored instead
*/
watchExclude?: string[];
/**
* Glob patter of file paths that will trigger the whole suite rerun
*
* Useful if you are testing calling CLI commands
*
* @default ['**\/package.json/**', '**\/{vitest,vite}.config.*\/**']
*/
forceRerunTriggers?: string[];
/**
* Coverage options
*/
coverage?: CoverageOptions;
/**
* run test names with the specified pattern
*/
testNamePattern?: string | RegExp;
/**
* Will call `.mockClear()` on all spies before each test
* @default false
*/
clearMocks?: boolean;
/**
* Will call `.mockReset()` on all spies before each test
* @default false
*/
mockReset?: boolean;
/**
* Will call `.mockRestore()` on all spies before each test
* @default false
*/
restoreMocks?: boolean;
/**
* Will restore all global stubs to their original values before each test
* @default false
*/
unstubGlobals?: boolean;
/**
* Will restore all env stubs to their original values before each test
* @default false
*/
unstubEnvs?: boolean;
/**
* Serve API options.
*
* When set to true, the default port is 51204.
*
* @default false
*/
api?: boolean | number | ApiConfig;
/**
* Enable Vitest UI
*
* @default false
*/
ui?: boolean;
/**
* options for test in a browser environment
* @experimental
*
* @default false
*/
browser?: BrowserConfigOptions;
/**
* Open UI automatically.
*
* @default !process.env.CI
*/
open?: boolean;
/**
* Base url for the UI
*
* @default '/__vitest__/'
*/
uiBase?: string;
/**
* Determine the transform method for all modules imported inside a test that matches the glob pattern.
*/
testTransformMode?: TransformModePatterns;
/**
* Format options for snapshot testing.
*/
snapshotFormat?: Omit<PrettyFormatOptions, 'plugins'>;
/**
* Path to a module which has a default export of diff config.
*/
diff?: string;
/**
* Paths to snapshot serializer modules.
*/
snapshotSerializers?: string[];
/**
* Resolve custom snapshot path
*/
resolveSnapshotPath?: (path: string, extension: string) => string;
/**
* Path to a custom snapshot environment module that has a defualt export of `SnapshotEnvironment` object.
*/
snapshotEnvironment?: string;
/**
* Pass with no tests
*/
passWithNoTests?: boolean;
/**
* Allow tests and suites that are marked as only
*
* @default !process.env.CI
*/
allowOnly?: boolean;
/**
* Show heap usage after each test. Useful for debugging memory leaks.
*/
logHeapUsage?: boolean;
/**
* Custom environment variables assigned to `process.env` before running tests.
*/
env?: Record<string, string>;
/**
* Options for @sinon/fake-timers
*/
fakeTimers?: FakeTimerInstallOpts;
/**
* Custom handler for console.log in tests.
*
* Return `false` to ignore the log.
*/
onConsoleLog?: (log: string, type: 'stdout' | 'stderr') => boolean | void;
/**
* Enable stack trace filtering. If absent, all stack trace frames
* will be shown.
*
* Return `false` to omit the frame.
*/
onStackTrace?: (error: Error, frame: ParsedStack) => boolean | void;
/**
* Indicates if CSS files should be processed.
*
* When excluded, the CSS files will be replaced with empty strings to bypass the subsequent processing.
*
* @default { include: [], modules: { classNameStrategy: false } }
*/
css?: boolean | {
include?: RegExp | RegExp[];
exclude?: RegExp | RegExp[];
modules?: {
classNameStrategy?: CSSModuleScopeStrategy;
};
};
/**
* A number of tests that are allowed to run at the same time marked with `test.concurrent`.
* @default 5
*/
maxConcurrency?: number;
/**
* Options for configuring cache policy.
* @default { dir: 'node_modules/.vite/vitest' }
*/
cache?: false | {
/**
* @deprecated Use Vite's "cacheDir" instead if you want to change the cache director. Note caches will be written to "cacheDir\/vitest".
*/
dir: string;
};
/**
* Options for configuring the order of running tests.
*/
sequence?: SequenceOptions;
/**
* Specifies an `Object`, or an `Array` of `Object`,
* which defines aliases used to replace values in `import` or `require` statements.
* Will be merged with the default aliases inside `resolve.alias`.
*/
alias?: AliasOptions;
/**
* Ignore any unhandled errors that occur
*
* @default false
*/
dangerouslyIgnoreUnhandledErrors?: boolean;
/**
* Options for configuring typechecking test environment.
*/
typecheck?: Partial<TypecheckConfig>;
/**
* The number of milliseconds after which a test is considered slow and reported as such in the results.
*
* @default 300
*/
slowTestThreshold?: number;
/**
* Path to a custom test runner.
*/
runner?: string;
/**
* Debug tests by opening `node:inspector` in worker / child process.
* Provides similar experience as `--inspect` Node CLI argument.
*
* Requires `poolOptions.threads.singleThread: true` OR `poolOptions.forks.singleFork: true`.
*/
inspect?: boolean | string;
/**
* Debug tests by opening `node:inspector` in worker / child process and wait for debugger to connect.
* Provides similar experience as `--inspect-brk` Node CLI argument.
*
* Requires `poolOptions.threads.singleThread: true` OR `poolOptions.forks.singleFork: true`.
*/
inspectBrk?: boolean | string;
/**
* Inspector options. If `--inspect` or `--inspect-brk` is enabled, these options will be passed to the inspector.
*/
inspector?: {
/**
* Enable inspector
*/
enabled?: boolean;
/**
* Port to run inspector on
*/
port?: number;
/**
* Host to run inspector on
*/
host?: string;
/**
* Wait for debugger to connect before running tests
*/
waitForDebugger?: boolean;
};
/**
* Modify default Chai config. Vitest uses Chai for `expect` and `assert` matches.
* https://github.com/chaijs/chai/blob/4.x.x/lib/chai/config.js
*/
chaiConfig?: ChaiConfig;
/**
* Stop test execution when given number of tests have failed.
*/
bail?: number;
/**
* Retry the test specific number of times if it fails.
*
* @default 0
*/
retry?: number;
/**
* Show full diff when snapshot fails instead of a patch.
*/
expandSnapshotDiff?: boolean;
/**
* By default, Vitest automatically intercepts console logging during tests for extra formatting of test file, test title, etc...
* This is also required for console log preview on Vitest UI.
* However, disabling such interception might help when you want to debug a code with normal synchronus terminal console logging.
*
* This option has no effect on browser pool since Vitest preserves original logging on browser devtools.
*
* @default false
*/
disableConsoleIntercept?: boolean;
/**
* Include "location" property inside the test definition
*
* @default false
*/
includeTaskLocation?: boolean;
}
interface TypecheckConfig {
/**
* Run typechecking tests alongisde regular tests.
*/
enabled?: boolean;
/**
* When typechecking is enabled, only run typechecking tests.
*/
only?: boolean;
/**
* What tools to use for type checking.
*
* @default 'tsc'
*/
checker: 'tsc' | 'vue-tsc' | (string & Record<never, never>);
/**
* Pattern for files that should be treated as test files
*
* @default ['**\/*.{test,spec}-d.?(c|m)[jt]s?(x)']
*/
include: string[];
/**
* Pattern for files that should not be treated as test files
*
* @default ['**\/node_modules/**', '**\/dist/**', '**\/cypress/**', '**\/.{idea,git,cache,output,temp}/**', '**\/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build,eslint,prettier}.config.*']
*/
exclude: string[];
/**
* Check JS files that have `@ts-check` comment.
* If you have it enabled in tsconfig, this will not overwrite it.
*/
allowJs?: boolean;
/**
* Do not fail, if Vitest found errors outside the test files.
*/
ignoreSourceErrors?: boolean;
/**
* Path to tsconfig, relative to the project root.
*/
tsconfig?: string;
}
interface UserConfig extends InlineConfig {
/**
* Path to the config file.
*
* Default resolving to `vitest.config.*`, `vite.config.*`
*
* Setting to `false` will disable config resolving.
*/
config?: string | false | undefined;
/**
* Do not run tests when Vitest starts.
*
* Vitest will only run tests if it's called programmatically or the test file changes.
*
* CLI file filters will be ignored.
*/
standalone?: boolean;
/**
* Use happy-dom
*/
dom?: boolean;
/**
* Run tests that cover a list of source files
*/
related?: string[] | string;
/**
* Overrides Vite mode
* @default 'test'
*/
mode?: string;
/**
* Runs tests that are affected by the changes in the repository, or between specified branch or commit hash
* Requires initialized git repository
* @default false
*/
changed?: boolean | string;
/**
* Test suite shard to execute in a format of <index>/<count>.
* Will divide tests into a `count` numbers, and run only the `indexed` part.
* Cannot be used with enabled watch.
* @example --shard=2/3
*/
shard?: string;
/**
* Name of the project or projects to run.
*/
project?: string | string[];
/**
* Additional exclude patterns
*/
cliExclude?: string[];
/**
* Override vite config's clearScreen from cli
*/
clearScreen?: boolean;
/**
* benchmark.compare option exposed at the top level for cli
*/
compare?: string;
/**
* benchmark.outputJson option exposed at the top level for cli
*/
outputJson?: string;
}
interface ResolvedConfig extends Omit<Required<UserConfig>, 'config' | 'filters' | 'browser' | 'coverage' | 'testNamePattern' | 'related' | 'api' | 'reporters' | 'resolveSnapshotPath' | 'benchmark' | 'shard' | 'cache' | 'sequence' | 'typecheck' | 'runner' | 'poolOptions' | 'pool' | 'cliExclude'> {
mode: VitestRunMode;
base?: string;
config?: string;
filters?: string[];
testNamePattern?: RegExp;
related?: string[];
coverage: ResolvedCoverageOptions;
snapshotOptions: SnapshotStateOptions;
browser: ResolvedBrowserOptions;
pool: Pool;
poolOptions?: PoolOptions;
reporters: (InlineReporter | ReporterWithOptions)[];
defines: Record<string, any>;
api: ApiConfig & {
token: string;
};
cliExclude?: string[];
benchmark?: Required<Omit<BenchmarkUserOptions, 'outputFile' | 'compare' | 'outputJson'>> & Pick<BenchmarkUserOptions, 'outputFile' | 'compare' | 'outputJson'>;
shard?: {
index: number;
count: number;
};
cache: {
/**
* @deprecated
*/
dir: string;
} | false;
sequence: {
sequencer: TestSequencerConstructor;
hooks: SequenceHooks;
setupFiles: SequenceSetupFiles;
shuffle?: boolean;
concurrent?: boolean;
seed: number;
};
typecheck: Omit<TypecheckConfig, 'enabled'> & {
enabled: boolean;
};
runner?: string;
}
type ProjectConfig = Omit<UserConfig, 'sequencer' | 'shard' | 'watch' | 'run' | 'cache' | 'update' | 'reporters' | 'outputFile' | 'poolOptions' | 'teardownTimeout' | 'silent' | 'watchExclude' | 'forceRerunTriggers' | 'testNamePattern' | 'ui' | 'open' | 'uiBase' | 'snapshotFormat' | 'resolveSnapshotPath' | 'passWithNoTests' | 'onConsoleLog' | 'onStackTrace' | 'dangerouslyIgnoreUnhandledErrors' | 'slowTestThreshold' | 'inspect' | 'inspectBrk' | 'deps' | 'coverage'> & {
sequencer?: Omit<SequenceOptions, 'sequencer' | 'seed'>;
deps?: Omit<DepsOptions, 'moduleDirectories'>;
poolOptions?: {
threads?: Pick<NonNullable<PoolOptions['threads']>, 'singleThread' | 'isolate'>;
vmThreads?: Pick<NonNullable<PoolOptions['vmThreads']>, 'singleThread'>;
forks?: Pick<NonNullable<PoolOptions['forks']>, 'singleFork' | 'isolate'>;
};
};
type RuntimeConfig = Pick<UserConfig, 'allowOnly' | 'testTimeout' | 'hookTimeout' | 'clearMocks' | 'mockReset' | 'restoreMocks' | 'fakeTimers' | 'maxConcurrency'> & {
sequence?: {
concurrent?: boolean;
hooks?: SequenceHooks;
};
};
type VitestInlineConfig = InlineConfig;
declare module 'vite' {
interface UserConfig {
/**
* Options for Vitest
*/
test?: VitestInlineConfig;
}
}
declare global {
namespace Chai {
interface Assertion {
containSubset: (expected: any) => Assertion;
}
interface Assert {
containSubset: (val: any, exp: any, msg?: string) => void;
}
}
}
interface SnapshotMatcher<T> {
<U extends {
[P in keyof T]: any;
}>(snapshot: Partial<U>, message?: string): void;
(message?: string): void;
}
interface InlineSnapshotMatcher<T> {
<U extends {
[P in keyof T]: any;
}>(properties: Partial<U>, snapshot?: string, message?: string): void;
(message?: string): void;
}
declare module '@vitest/expect' {
interface MatcherState {
environment: VitestEnvironment;
snapshotState: SnapshotState;
}
interface ExpectStatic {
addSnapshotSerializer: (plugin: Plugin_2) => void;
}
interface Assertion<T> {
matchSnapshot: SnapshotMatcher<T>;
toMatchSnapshot: SnapshotMatcher<T>;
toMatchInlineSnapshot: InlineSnapshotMatcher<T>;
toThrowErrorMatchingSnapshot: (message?: string) => void;
toThrowErrorMatchingInlineSnapshot: (snapshot?: string, message?: string) => void;
toMatchFileSnapshot: (filepath: string, message?: string) => Promise<void>;
}
}
declare module '@vitest/runner' {
interface TestContext {
expect: ExpectStatic;
}
interface TaskMeta {
typecheck?: boolean;
benchmark?: boolean;
}
interface File {
prepareDuration?: number;
environmentLoad?: number;
}
interface TaskBase {
logs?: UserConsoleLog[];
}
interface TaskResult {
benchmark?: BenchmarkResult;
}
}
type RawErrsMap = Map<string, TscErrorInfo[]>;
interface TscErrorInfo {
filePath: string;
errCode: number;
errMsg: string;
line: number;
column: number;
}
interface CollectLineNumbers {
target: number;
next: number;
prev?: number;
}
type CollectLines = {
[key in keyof CollectLineNumbers]: string;
};
interface RootAndTarget {
root: string;
targetAbsPath: string;
}
type Context = RootAndTarget & {
rawErrsMap: RawErrsMap;
openedDirs: Set<string>;
lastActivePath?: string;
};
export { type ProjectConfig as $, type AfterSuiteRunMeta as A, type BaseCoverageOptions as B, type CoverageOptions as C, type RootAndTarget as D, type Environment as E, type FakeTimerInstallOpts as F, type Context as G, type Pool as H, type PoolOptions as I, type JSDOMOptions as J, type HappyDOMOptions as K, type BuiltinEnvironment as L, type MockFactoryWithHelper as M, type VitestEnvironment as N, type CSSModuleScopeStrategy as O, type ProvidedContext as P, type ApiConfig as Q, type ResolvedConfig as R, type EnvironmentOptions as S, type TestSequencer as T, type UserConfig as U, type VitestRunMode as V, type WorkerGlobalState as W, type DepsOptimizationOptions as X, type TransformModePatterns as Y, type InlineConfig as Z, type TypecheckConfig as _, type ResolvedCoverageOptions as a, type BrowserConfigOptions as a0, type UserWorkspaceConfig as a1, type RunnerRPC as a2, type ContextTestEnvironment as a3, type ResolvedTestEnvironment as a4, type ResolveIdFunction as a5, type WorkerRPC as a6, type Awaitable as a7, type Nullable as a8, type Arrayable as a9, defineConfig as aA, defineProject as aB, defineWorkspace as aC, configDefaults as aD, defaultInclude as aE, defaultExclude as aF, coverageConfigDefaults as aG, extraInlineDeps as aH, DefaultReporter as aI, BasicReporter as aJ, DotReporter as aK, JsonReporter as aL, VerboseReporter as aM, TapReporter as aN, JUnitReporter as aO, TapFlatReporter as aP, HangingProcessReporter as aQ, GithubActionsReporter as aR, BaseReporter as aS, ReportersMap as aT, type BuiltinReporters as aU, type BuiltinReporterOptions as aV, type JsonAssertionResult as aW, type JsonTestResult as aX, type JsonTestResults as aY, BenchmarkReportsMap as aZ, type BenchmarkBuiltinReporters as a_, type ArgumentsType$1 as aa, type MutableArray as ab, type Constructable as ac, type ModuleCache as ad, type EnvironmentReturn as ae, type VmEnvironmentReturn as af, type OnServerRestartHandler as ag, type ReportContext as ah, type CoverageReporter as ai, type CoverageIstanbulOptions as aj, type CoverageV8Options as ak, type CustomProviderOptions as al, type BenchmarkUserOptions as am, type Benchmark as an, type BenchmarkResult as ao, type BenchFunction as ap, type BenchmarkAPI as aq, type PendingSuiteMock as ar, type MockFactory as as, type MockMap as at, type UserConfigFnObject as au, type UserConfigFnPromise as av, type UserConfigFn as aw, type UserConfigExport as ax, type UserProjectConfigFn as ay, type UserProjectConfigExport as az, type CoverageProvider as b, type CoverageProviderModule as c, type BirpcOptions as d, type RuntimeRPC as e, type ContextRPC as f, type WorkerContext as g, type VitestOptions as h, Vitest as i, WorkspaceProject as j, type WorkspaceSpec as k, type ProcessPool as l, VitestPackageInstaller as m, type TestSequencerConstructor as n, type BrowserProviderInitializationOptions as o, type BrowserProvider as p, type BrowserProviderOptions as q, type BrowserScript as r, type RuntimeConfig as s, type UserConsoleLog as t, type ModuleGraphData as u, type Reporter as v, type RawErrsMap as w, type TscErrorInfo as x, type CollectLineNumbers as y, type CollectLines as z };
+16
View File
@@ -0,0 +1,16 @@
export { aS as BaseReporter, aJ as BasicReporter, a_ as BenchmarkBuiltinReporters, aZ as BenchmarkReportsMap, aV as BuiltinReporterOptions, aU as BuiltinReporters, aI as DefaultReporter, aK as DotReporter, aR as GithubActionsReporter, aQ as HangingProcessReporter, aO as JUnitReporter, aW as JsonAssertionResult, aL as JsonReporter, aX as JsonTestResult, aY as JsonTestResults, v as Reporter, aT as ReportersMap, aP as TapFlatReporter, aN as TapReporter, aM as VerboseReporter } from './reporters-w_64AS5f.js';
import 'vite';
import '@vitest/runner';
import 'vite-node';
import '@vitest/snapshot';
import '@vitest/expect';
import '@vitest/runner/utils';
import '@vitest/utils';
import 'tinybench';
import 'node:stream';
import 'vite-node/client';
import '@vitest/snapshot/manager';
import 'vite-node/server';
import 'node:worker_threads';
import 'node:fs';
import 'chai';
+36
View File
@@ -0,0 +1,36 @@
export { a as BasicReporter, e as BenchmarkReportsMap, D as DefaultReporter, b as DotReporter, G as GithubActionsReporter, H as HangingProcessReporter, c as JUnitReporter, J as JsonReporter, R as ReportersMap, d as TapFlatReporter, T as TapReporter, V as VerboseReporter } from './vendor/index.-xs08BYx.js';
import 'node:fs';
import 'picocolors';
import 'pathe';
import './vendor/tasks.IknbGB2n.js';
import '@vitest/runner/utils';
import '@vitest/utils';
import './vendor/env.AtSIuHFg.js';
import 'std-env';
import './vendor/utils.dEtNIEgr.js';
import './vendor/base.5NT-gWu5.js';
import 'node:perf_hooks';
import './vendor/index.SMVOaj7F.js';
import './vendor/global.CkGT_TMy.js';
import './chunks/runtime-console.EO5ha7qv.js';
import 'node:stream';
import 'node:console';
import 'node:path';
import './vendor/date.Ns1pGd_X.js';
import '@vitest/utils/source-map';
import 'node:os';
import 'node:fs/promises';
import 'execa';
import 'node:url';
import 'path';
import 'fs';
import 'module';
import 'vite';
import 'acorn-walk';
import 'node:process';
import './vendor/_commonjsHelpers.jjO7Zipk.js';
import 'assert';
import 'events';
import 'node:crypto';
import 'vite-node/utils';
import 'node:module';
+48
View File
@@ -0,0 +1,48 @@
import { VitestRunner, VitestRunnerImportSource, Suite, Task, CancelReason, Test, Custom, TaskContext, ExtendedContext } from '@vitest/runner';
import { R as ResolvedConfig } from './reporters-w_64AS5f.js';
import * as tinybench from 'tinybench';
import 'vite';
import 'vite-node';
import '@vitest/snapshot';
import '@vitest/expect';
import '@vitest/runner/utils';
import '@vitest/utils';
import 'node:stream';
import 'vite-node/client';
import '@vitest/snapshot/manager';
import 'vite-node/server';
import 'node:worker_threads';
import 'node:fs';
import 'chai';
declare class VitestTestRunner implements VitestRunner {
config: ResolvedConfig;
private snapshotClient;
private workerState;
private __vitest_executor;
private cancelRun;
constructor(config: ResolvedConfig);
importFile(filepath: string, source: VitestRunnerImportSource): unknown;
onBeforeRunFiles(): void;
onAfterRunFiles(): void;
onAfterRunSuite(suite: Suite): Promise<void>;
onAfterRunTask(test: Task): void;
onCancel(_reason: CancelReason): void;
onBeforeRunTask(test: Task): Promise<void>;
onBeforeRunSuite(suite: Suite): Promise<void>;
onBeforeTryTask(test: Task): void;
onAfterTryTask(test: Task): void;
extendTaskContext<T extends Test | Custom>(context: TaskContext<T>): ExtendedContext<T>;
}
declare class NodeBenchmarkRunner implements VitestRunner {
config: ResolvedConfig;
private __vitest_executor;
constructor(config: ResolvedConfig);
importTinybench(): Promise<typeof tinybench>;
importFile(filepath: string, source: VitestRunnerImportSource): unknown;
runSuite(suite: Suite): Promise<void>;
runTask(): Promise<void>;
}
export { NodeBenchmarkRunner, VitestTestRunner };
+257
View File
@@ -0,0 +1,257 @@
import { setState, GLOBAL_EXPECT, getState } from '@vitest/expect';
import { g as getSnapshotClient, c as createExpect, v as vi } from './vendor/vi.YFlodzP_.js';
import 'pathe';
import { g as getFullName } from './vendor/tasks.IknbGB2n.js';
import { createDefer, getSafeTimers } from '@vitest/utils';
import { g as getWorkerState } from './vendor/global.CkGT_TMy.js';
import './vendor/env.AtSIuHFg.js';
import { r as rpc } from './vendor/rpc.joBhAkyK.js';
import { getTests, getNames } from '@vitest/runner/utils';
import { updateTask } from '@vitest/runner';
import { a as getBenchOptions, g as getBenchFn } from './vendor/benchmark.yGkUTKnC.js';
import 'chai';
import './vendor/_commonjsHelpers.jjO7Zipk.js';
import '@vitest/snapshot';
import '@vitest/utils/error';
import '@vitest/utils/source-map';
import './vendor/base.5NT-gWu5.js';
import './vendor/date.Ns1pGd_X.js';
import '@vitest/spy';
import 'std-env';
import './vendor/index.8bPxjt7g.js';
import './vendor/index.SMVOaj7F.js';
class VitestTestRunner {
constructor(config) {
this.config = config;
}
snapshotClient = getSnapshotClient();
workerState = getWorkerState();
__vitest_executor;
cancelRun = false;
importFile(filepath, source) {
if (source === "setup")
this.workerState.moduleCache.delete(filepath);
return this.__vitest_executor.executeId(filepath);
}
onBeforeRunFiles() {
this.snapshotClient.clear();
}
onAfterRunFiles() {
this.workerState.current = void 0;
}
async onAfterRunSuite(suite) {
if (this.config.logHeapUsage && typeof process !== "undefined")
suite.result.heap = process.memoryUsage().heapUsed;
if (suite.mode !== "skip" && typeof suite.filepath !== "undefined") {
for (const test of getTests(suite)) {
if (test.mode === "skip") {
const name = getNames(test).slice(1).join(" > ");
this.snapshotClient.skipTestSnapshots(name);
}
}
const result = await this.snapshotClient.finishCurrentRun();
if (result)
await rpc().snapshotSaved(result);
}
this.workerState.current = suite.suite;
}
onAfterRunTask(test) {
this.snapshotClient.clearTest();
if (this.config.logHeapUsage && typeof process !== "undefined")
test.result.heap = process.memoryUsage().heapUsed;
this.workerState.current = test.suite;
}
onCancel(_reason) {
this.cancelRun = true;
}
async onBeforeRunTask(test) {
if (this.cancelRun)
test.mode = "skip";
if (test.mode !== "run")
return;
clearModuleMocks(this.config);
this.workerState.current = test;
}
async onBeforeRunSuite(suite) {
if (this.cancelRun)
suite.mode = "skip";
if (suite.mode !== "skip" && typeof suite.filepath !== "undefined") {
await this.snapshotClient.startCurrentRun(suite.filepath, "__default_name_", this.workerState.config.snapshotOptions);
}
this.workerState.current = suite;
}
onBeforeTryTask(test) {
var _a, _b;
setState({
assertionCalls: 0,
isExpectingAssertions: false,
isExpectingAssertionsError: null,
expectedAssertionsNumber: null,
expectedAssertionsNumberErrorGen: null,
testPath: (_b = (_a = test.suite) == null ? void 0 : _a.file) == null ? void 0 : _b.filepath,
currentTestName: getFullName(test),
snapshotState: this.snapshotClient.snapshotState
}, globalThis[GLOBAL_EXPECT]);
}
onAfterTryTask(test) {
const {
assertionCalls,
expectedAssertionsNumber,
expectedAssertionsNumberErrorGen,
isExpectingAssertions,
isExpectingAssertionsError
// @ts-expect-error _local is untyped
} = "context" in test && test.context._local ? test.context.expect.getState() : getState(globalThis[GLOBAL_EXPECT]);
if (expectedAssertionsNumber !== null && assertionCalls !== expectedAssertionsNumber)
throw expectedAssertionsNumberErrorGen();
if (isExpectingAssertions === true && assertionCalls === 0)
throw isExpectingAssertionsError;
}
extendTaskContext(context) {
let _expect;
Object.defineProperty(context, "expect", {
get() {
if (!_expect)
_expect = createExpect(context.task);
return _expect;
}
});
Object.defineProperty(context, "_local", {
get() {
return _expect != null;
}
});
return context;
}
}
function clearModuleMocks(config) {
const { clearMocks, mockReset, restoreMocks, unstubEnvs, unstubGlobals } = config;
if (restoreMocks)
vi.restoreAllMocks();
else if (mockReset)
vi.resetAllMocks();
else if (clearMocks)
vi.clearAllMocks();
if (unstubEnvs)
vi.unstubAllEnvs();
if (unstubGlobals)
vi.unstubAllGlobals();
}
function createBenchmarkResult(name) {
return {
name,
rank: 0,
rme: 0,
samples: []
};
}
const benchmarkTasks = /* @__PURE__ */ new WeakMap();
async function runBenchmarkSuite(suite, runner) {
var _a;
const { Task, Bench } = await runner.importTinybench();
const start = performance.now();
const benchmarkGroup = [];
const benchmarkSuiteGroup = [];
for (const task of suite.tasks) {
if (task.mode !== "run")
continue;
if ((_a = task.meta) == null ? void 0 : _a.benchmark)
benchmarkGroup.push(task);
else if (task.type === "suite")
benchmarkSuiteGroup.push(task);
}
for (const subSuite of benchmarkSuiteGroup)
await runBenchmarkSuite(subSuite, runner);
if (benchmarkGroup.length) {
const defer = createDefer();
suite.result = {
state: "run",
startTime: start,
benchmark: createBenchmarkResult(suite.name)
};
updateTask$1(suite);
const addBenchTaskListener = (task, benchmark) => {
task.addEventListener("complete", (e) => {
const task2 = e.task;
const taskRes = task2.result;
const result = benchmark.result.benchmark;
Object.assign(result, taskRes);
updateTask$1(benchmark);
}, {
once: true
});
task.addEventListener("error", (e) => {
const task2 = e.task;
defer.reject(benchmark ? task2.result.error : e);
}, {
once: true
});
};
benchmarkGroup.forEach((benchmark) => {
const options = getBenchOptions(benchmark);
const benchmarkInstance = new Bench(options);
const benchmarkFn = getBenchFn(benchmark);
benchmark.result = {
state: "run",
startTime: start,
benchmark: createBenchmarkResult(benchmark.name)
};
const task = new Task(benchmarkInstance, benchmark.name, benchmarkFn);
benchmarkTasks.set(benchmark, task);
addBenchTaskListener(task, benchmark);
updateTask$1(benchmark);
});
const { setTimeout } = getSafeTimers();
const tasks = [];
for (const benchmark of benchmarkGroup) {
const task = benchmarkTasks.get(benchmark);
await task.warmup();
tasks.push([
await new Promise((resolve) => setTimeout(async () => {
resolve(await task.run());
})),
benchmark
]);
}
suite.result.duration = performance.now() - start;
suite.result.state = "pass";
tasks.sort(([taskA], [taskB]) => taskA.result.mean - taskB.result.mean).forEach(([, benchmark], idx) => {
benchmark.result.state = "pass";
if (benchmark) {
const result = benchmark.result.benchmark;
result.rank = Number(idx) + 1;
updateTask$1(benchmark);
}
});
updateTask$1(suite);
defer.resolve(null);
await defer;
}
function updateTask$1(task) {
updateTask(task, runner);
}
}
class NodeBenchmarkRunner {
constructor(config) {
this.config = config;
}
__vitest_executor;
async importTinybench() {
return await import('tinybench');
}
importFile(filepath, source) {
if (source === "setup")
getWorkerState().moduleCache.delete(filepath);
return this.__vitest_executor.executeId(filepath);
}
async runSuite(suite) {
await runBenchmarkSuite(suite, this);
}
async runTask() {
throw new Error("`test()` and `it()` is only available in test mode.");
}
}
export { NodeBenchmarkRunner, VitestTestRunner };
+9
View File
@@ -0,0 +1,9 @@
import { NodeSnapshotEnvironment } from '@vitest/snapshot/environment';
export { SnapshotEnvironment } from '@vitest/snapshot/environment';
declare class VitestNodeSnapshotEnvironment extends NodeSnapshotEnvironment {
getHeader(): string;
resolvePath(filepath: string): Promise<string>;
}
export { VitestNodeSnapshotEnvironment as VitestSnapshotEnvironment };
+8
View File
@@ -0,0 +1,8 @@
export { VitestNodeSnapshotEnvironment as VitestSnapshotEnvironment } from './chunks/environments-node.vcoXCoKs.js';
import '@vitest/snapshot/environment';
import 'pathe';
import '@vitest/runner/utils';
import '@vitest/utils';
import './vendor/global.CkGT_TMy.js';
import './vendor/env.AtSIuHFg.js';
import 'std-env';
+1
View File
@@ -0,0 +1 @@
export * from '@vitest/spy';
+10
View File
@@ -0,0 +1,10 @@
import { Custom } from '@vitest/runner';
import '@vitest/runner/utils';
import { ap as BenchFunction, aq as BenchmarkAPI } from './reporters-w_64AS5f.js';
import { Options } from 'tinybench';
declare function getBenchOptions(key: Custom): Options;
declare function getBenchFn(key: Custom): BenchFunction;
declare const bench: BenchmarkAPI;
export { getBenchOptions as a, bench as b, getBenchFn as g };
+17
View File
@@ -0,0 +1,17 @@
export { createTaskCollector, getCurrentSuite, getCurrentTest, getFn, getHooks, setFn, setHooks } from '@vitest/runner';
export { createChainable } from '@vitest/runner/utils';
export { g as getBenchFn, a as getBenchOptions } from './suite-dWqIFb_-.js';
import './reporters-w_64AS5f.js';
import 'vite';
import 'vite-node';
import '@vitest/snapshot';
import '@vitest/expect';
import '@vitest/utils';
import 'tinybench';
import 'node:stream';
import 'vite-node/client';
import '@vitest/snapshot/manager';
import 'vite-node/server';
import 'node:worker_threads';
import 'node:fs';
import 'chai';
+9
View File
@@ -0,0 +1,9 @@
export { createTaskCollector, getCurrentSuite, getCurrentTest, getFn, getHooks, setFn, setHooks } from '@vitest/runner';
export { createChainable } from '@vitest/runner/utils';
export { g as getBenchFn, a as getBenchOptions } from './vendor/benchmark.yGkUTKnC.js';
import '@vitest/utils';
import './vendor/index.SMVOaj7F.js';
import 'pathe';
import './vendor/global.CkGT_TMy.js';
import './vendor/env.AtSIuHFg.js';
import 'std-env';
+6
View File
@@ -0,0 +1,6 @@
import * as _vitest_utils_source_map from '@vitest/utils/source-map';
export * from '@vitest/utils';
declare function loadSourceMapUtils(): Promise<typeof _vitest_utils_source_map>;
export { loadSourceMapUtils };
+7
View File
@@ -0,0 +1,7 @@
export * from '@vitest/utils';
function loadSourceMapUtils() {
return import('@vitest/utils/source-map');
}
export { loadSourceMapUtils };
@@ -0,0 +1,7 @@
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
function getDefaultExportFromCjs (x) {
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
}
export { commonjsGlobal as c, getDefaultExportFromCjs as g };
@@ -0,0 +1,119 @@
import '@vitest/utils';
function collectOwnProperties(obj, collector) {
const collect = typeof collector === "function" ? collector : (key) => collector.add(key);
Object.getOwnPropertyNames(obj).forEach(collect);
Object.getOwnPropertySymbols(obj).forEach(collect);
}
function groupBy(collection, iteratee) {
return collection.reduce((acc, item) => {
const key = iteratee(item);
acc[key] || (acc[key] = []);
acc[key].push(item);
return acc;
}, {});
}
function isPrimitive(value) {
return value === null || typeof value !== "function" && typeof value !== "object";
}
function getAllMockableProperties(obj, isModule, constructors) {
const {
Map,
Object: Object2,
Function,
RegExp: RegExp2,
Array: Array2
} = constructors;
const allProps = new Map();
let curr = obj;
do {
if (curr === Object2.prototype || curr === Function.prototype || curr === RegExp2.prototype)
break;
collectOwnProperties(curr, (key) => {
const descriptor = Object2.getOwnPropertyDescriptor(curr, key);
if (descriptor)
allProps.set(key, { key, descriptor });
});
} while (curr = Object2.getPrototypeOf(curr));
if (isModule && !allProps.has("default") && "default" in obj) {
const descriptor = Object2.getOwnPropertyDescriptor(obj, "default");
if (descriptor)
allProps.set("default", { key: "default", descriptor });
}
return Array2.from(allProps.values());
}
function slash(str) {
return str.replace(/\\/g, "/");
}
function noop() {
}
function toArray(array) {
if (array === null || array === void 0)
array = [];
if (Array.isArray(array))
return array;
return [array];
}
function toString(v) {
return Object.prototype.toString.call(v);
}
function isPlainObject(val) {
return toString(val) === "[object Object]" && (!val.constructor || val.constructor.name === "Object");
}
function deepMerge(target, ...sources) {
if (!sources.length)
return target;
const source = sources.shift();
if (source === void 0)
return target;
if (isMergeableObject(target) && isMergeableObject(source)) {
Object.keys(source).forEach((key) => {
if (isMergeableObject(source[key])) {
if (!target[key])
target[key] = {};
deepMerge(target[key], source[key]);
} else {
target[key] = source[key];
}
});
}
return deepMerge(target, ...sources);
}
function isMergeableObject(item) {
return isPlainObject(item) && !Array.isArray(item);
}
function stdout() {
return console._stdout || process.stdout;
}
class AggregateErrorPonyfill extends Error {
errors;
constructor(errors, message = "") {
super(message);
this.errors = [...errors];
}
}
function isChildProcess() {
return typeof process !== "undefined" && !!process.send;
}
function setProcessTitle(title) {
try {
process.title = `node (${title})`;
} catch {
}
}
function escapeRegExp(s) {
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
function wildcardPatternToRegExp(pattern) {
return new RegExp(`^${pattern.split("*").map(escapeRegExp).join(".*")}$`, "i");
}
const urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
function nanoid(size = 21) {
let id = "";
let i = size;
while (i--)
id += urlAlphabet[Math.random() * 64 | 0];
return id;
}
export { AggregateErrorPonyfill as A, slash as a, isPrimitive as b, groupBy as c, deepMerge as d, nanoid as e, stdout as f, getAllMockableProperties as g, isChildProcess as i, noop as n, setProcessTitle as s, toArray as t, wildcardPatternToRegExp as w };
@@ -0,0 +1,38 @@
import { ModuleCacheMap } from 'vite-node/client';
import { p as provideWorkerState } from './global.CkGT_TMy.js';
import { g as getDefaultRequestStubs, s as startVitestExecutor } from './execute.fL3szUAI.js';
let _viteNode;
const moduleCache = new ModuleCacheMap();
const mockMap = /* @__PURE__ */ new Map();
async function startViteNode(options) {
if (_viteNode)
return _viteNode;
_viteNode = await startVitestExecutor(options);
return _viteNode;
}
async function runBaseTests(state) {
const { ctx } = state;
state.moduleCache = moduleCache;
state.mockMap = mockMap;
provideWorkerState(globalThis, state);
if (ctx.invalidates) {
ctx.invalidates.forEach((fsPath) => {
moduleCache.delete(fsPath);
moduleCache.delete(`mock:${fsPath}`);
});
}
ctx.files.forEach((i) => state.moduleCache.delete(i));
const [executor, { run }] = await Promise.all([
startViteNode({ state, requestStubs: getDefaultRequestStubs() }),
import('../chunks/runtime-runBaseTests.oAvMKtQC.js')
]);
await run(
ctx.files,
ctx.config,
{ environment: state.environment, options: ctx.environment.options },
executor
);
}
export { runBaseTests as r };
@@ -0,0 +1,41 @@
import { getCurrentSuite } from '@vitest/runner';
import { createChainable } from '@vitest/runner/utils';
import { noop } from '@vitest/utils';
import { i as isRunningInBenchmark } from './index.SMVOaj7F.js';
const benchFns = /* @__PURE__ */ new WeakMap();
const benchOptsMap = /* @__PURE__ */ new WeakMap();
function getBenchOptions(key) {
return benchOptsMap.get(key);
}
function getBenchFn(key) {
return benchFns.get(key);
}
const bench = createBenchmark(
function(name, fn = noop, options = {}) {
if (!isRunningInBenchmark())
throw new Error("`bench()` is only available in benchmark mode.");
const task = getCurrentSuite().task(formatName(name), {
...this,
meta: {
benchmark: true
}
});
benchFns.set(task, fn);
benchOptsMap.set(task, options);
}
);
function createBenchmark(fn) {
const benchmark = createChainable(
["skip", "only", "todo"],
fn
);
benchmark.skipIf = (condition) => condition ? benchmark.skip : benchmark;
benchmark.runIf = (condition) => condition ? benchmark : benchmark.skip;
return benchmark;
}
function formatName(name) {
return typeof name === "string" ? name : name instanceof Function ? name.name || "<anonymous>" : String(name);
}
export { getBenchOptions as a, bench as b, getBenchFn as g };
+1429
View File
@@ -0,0 +1,1429 @@
import { normalize } from 'pathe';
import { EventEmitter } from 'events';
import c from 'picocolors';
import { t as toArray } from './base.5NT-gWu5.js';
import { d as defaultPort, a as defaultBrowserPort } from './constants.5J7I254_.js';
function toArr(any) {
return any == null ? [] : Array.isArray(any) ? any : [any];
}
function toVal(out, key, val, opts) {
var x, old=out[key], nxt=(
!!~opts.string.indexOf(key) ? (val == null || val === true ? '' : String(val))
: typeof val === 'boolean' ? val
: !!~opts.boolean.indexOf(key) ? (val === 'false' ? false : val === 'true' || (out._.push((x = +val,x * 0 === 0) ? x : val),!!val))
: (x = +val,x * 0 === 0) ? x : val
);
out[key] = old == null ? nxt : (Array.isArray(old) ? old.concat(nxt) : [old, nxt]);
}
function mri2 (args, opts) {
args = args || [];
opts = opts || {};
var k, arr, arg, name, val, out={ _:[] };
var i=0, j=0, idx=0, len=args.length;
const alibi = opts.alias !== void 0;
const strict = opts.unknown !== void 0;
const defaults = opts.default !== void 0;
opts.alias = opts.alias || {};
opts.string = toArr(opts.string);
opts.boolean = toArr(opts.boolean);
if (alibi) {
for (k in opts.alias) {
arr = opts.alias[k] = toArr(opts.alias[k]);
for (i=0; i < arr.length; i++) {
(opts.alias[arr[i]] = arr.concat(k)).splice(i, 1);
}
}
}
for (i=opts.boolean.length; i-- > 0;) {
arr = opts.alias[opts.boolean[i]] || [];
for (j=arr.length; j-- > 0;) opts.boolean.push(arr[j]);
}
for (i=opts.string.length; i-- > 0;) {
arr = opts.alias[opts.string[i]] || [];
for (j=arr.length; j-- > 0;) opts.string.push(arr[j]);
}
if (defaults) {
for (k in opts.default) {
name = typeof opts.default[k];
arr = opts.alias[k] = opts.alias[k] || [];
if (opts[name] !== void 0) {
opts[name].push(k);
for (i=0; i < arr.length; i++) {
opts[name].push(arr[i]);
}
}
}
}
const keys = strict ? Object.keys(opts.alias) : [];
for (i=0; i < len; i++) {
arg = args[i];
if (arg === '--') {
out._ = out._.concat(args.slice(++i));
break;
}
for (j=0; j < arg.length; j++) {
if (arg.charCodeAt(j) !== 45) break; // "-"
}
if (j === 0) {
out._.push(arg);
} else if (arg.substring(j, j + 3) === 'no-') {
name = arg.substring(j + 3);
if (strict && !~keys.indexOf(name)) {
return opts.unknown(arg);
}
out[name] = false;
} else {
for (idx=j+1; idx < arg.length; idx++) {
if (arg.charCodeAt(idx) === 61) break; // "="
}
name = arg.substring(j, idx);
val = arg.substring(++idx) || (i+1 === len || (''+args[i+1]).charCodeAt(0) === 45 || args[++i]);
arr = (j === 2 ? [name] : name);
for (idx=0; idx < arr.length; idx++) {
name = arr[idx];
if (strict && !~keys.indexOf(name)) return opts.unknown('-'.repeat(j) + name);
toVal(out, name, (idx + 1 < arr.length) || val, opts);
}
}
}
if (defaults) {
for (k in opts.default) {
if (out[k] === void 0) {
out[k] = opts.default[k];
}
}
}
if (alibi) {
for (k in out) {
arr = opts.alias[k] || [];
while (arr.length > 0) {
out[arr.shift()] = out[k];
}
}
}
return out;
}
const removeBrackets = (v) => v.replace(/[<[].+/, "").trim();
const findAllBrackets = (v) => {
const ANGLED_BRACKET_RE_GLOBAL = /<([^>]+)>/g;
const SQUARE_BRACKET_RE_GLOBAL = /\[([^\]]+)\]/g;
const res = [];
const parse = (match) => {
let variadic = false;
let value = match[1];
if (value.startsWith("...")) {
value = value.slice(3);
variadic = true;
}
return {
required: match[0].startsWith("<"),
value,
variadic
};
};
let angledMatch;
while (angledMatch = ANGLED_BRACKET_RE_GLOBAL.exec(v)) {
res.push(parse(angledMatch));
}
let squareMatch;
while (squareMatch = SQUARE_BRACKET_RE_GLOBAL.exec(v)) {
res.push(parse(squareMatch));
}
return res;
};
const getMriOptions = (options) => {
const result = {alias: {}, boolean: []};
for (const [index, option] of options.entries()) {
if (option.names.length > 1) {
result.alias[option.names[0]] = option.names.slice(1);
}
if (option.isBoolean) {
if (option.negated) {
const hasStringTypeOption = options.some((o, i) => {
return i !== index && o.names.some((name) => option.names.includes(name)) && typeof o.required === "boolean";
});
if (!hasStringTypeOption) {
result.boolean.push(option.names[0]);
}
} else {
result.boolean.push(option.names[0]);
}
}
}
return result;
};
const findLongest = (arr) => {
return arr.sort((a, b) => {
return a.length > b.length ? -1 : 1;
})[0];
};
const padRight = (str, length) => {
return str.length >= length ? str : `${str}${" ".repeat(length - str.length)}`;
};
const camelcase = (input) => {
return input.replace(/([a-z])-([a-z])/g, (_, p1, p2) => {
return p1 + p2.toUpperCase();
});
};
const setDotProp = (obj, keys, val, transforms) => {
let i = 0;
let length = keys.length;
let t = obj;
let x;
let convertKey = (i) => {
let key = keys[i];
i--;
while(i >= 0) {
key = keys[i] + '.' + key;
i--;
}
return key
};
for (; i < length; ++i) {
x = t[keys[i]];
const transform = transforms[convertKey(i)] || ((v) => v);
t = t[keys[i]] = transform(i === length - 1 ? val : x != null ? x : !!~keys[i + 1].indexOf(".") || !(+keys[i + 1] > -1) ? {} : []);
}
};
const getFileName = (input) => {
const m = /([^\\\/]+)$/.exec(input);
return m ? m[1] : "";
};
const camelcaseOptionName = (name) => {
return name.split(".").map((v, i) => {
return i === 0 ? camelcase(v) : v;
}).join(".");
};
class CACError extends Error {
constructor(message) {
super(message);
this.name = this.constructor.name;
if (typeof Error.captureStackTrace === "function") {
Error.captureStackTrace(this, this.constructor);
} else {
this.stack = new Error(message).stack;
}
}
}
class Option {
constructor(rawName, description, config) {
this.rawName = rawName;
this.description = description;
this.config = Object.assign({}, config);
rawName = rawName.replace(/\.\*/g, "");
this.negated = false;
this.names = removeBrackets(rawName).split(",").map((v) => {
let name = v.trim().replace(/^-{1,2}/, "");
if (name.startsWith("no-")) {
this.negated = true;
name = name.replace(/^no-/, "");
}
return camelcaseOptionName(name);
}).sort((a, b) => a.length > b.length ? 1 : -1);
this.name = this.names[this.names.length - 1];
if (this.negated && this.config.default == null) {
this.config.default = true;
}
if (rawName.includes("<")) {
this.required = true;
} else if (rawName.includes("[")) {
this.required = false;
} else {
this.isBoolean = true;
}
}
}
const processArgs = process.argv;
const platformInfo = `${process.platform}-${process.arch} node-${process.version}`;
class Command {
constructor(rawName, description, config = {}, cli) {
this.rawName = rawName;
this.description = description;
this.config = config;
this.cli = cli;
this.options = [];
this.aliasNames = [];
this.name = removeBrackets(rawName);
this.args = findAllBrackets(rawName);
this.examples = [];
}
usage(text) {
this.usageText = text;
return this;
}
allowUnknownOptions() {
this.config.allowUnknownOptions = true;
return this;
}
ignoreOptionDefaultValue() {
this.config.ignoreOptionDefaultValue = true;
return this;
}
version(version, customFlags = "-v, --version") {
this.versionNumber = version;
this.option(customFlags, "Display version number");
return this;
}
example(example) {
this.examples.push(example);
return this;
}
option(rawName, description, config) {
const option = new Option(rawName, description, config);
this.options.push(option);
return this;
}
alias(name) {
this.aliasNames.push(name);
return this;
}
action(callback) {
this.commandAction = callback;
return this;
}
isMatched(name) {
return this.name === name || this.aliasNames.includes(name);
}
get isDefaultCommand() {
return this.name === "" || this.aliasNames.includes("!");
}
get isGlobalCommand() {
return this instanceof GlobalCommand;
}
hasOption(name) {
name = name.split(".")[0];
return this.options.find((option) => {
return option.names.includes(name);
});
}
outputHelp() {
const {name, commands} = this.cli;
const {
versionNumber,
options: globalOptions,
helpCallback
} = this.cli.globalCommand;
let sections = [
{
body: `${name}${versionNumber ? `/${versionNumber}` : ""}`
}
];
sections.push({
title: "Usage",
body: ` $ ${name} ${this.usageText || this.rawName}`
});
const showCommands = (this.isGlobalCommand || this.isDefaultCommand) && commands.length > 0;
if (showCommands) {
const longestCommandName = findLongest(commands.map((command) => command.rawName));
sections.push({
title: "Commands",
body: commands.map((command) => {
return ` ${padRight(command.rawName, longestCommandName.length)} ${command.description}`;
}).join("\n")
});
sections.push({
title: `For more info, run any command with the \`--help\` flag`,
body: commands.map((command) => ` $ ${name}${command.name === "" ? "" : ` ${command.name}`} --help`).join("\n")
});
}
let options = this.isGlobalCommand ? globalOptions : [...this.options, ...globalOptions || []];
if (!this.isGlobalCommand && !this.isDefaultCommand) {
options = options.filter((option) => option.name !== "version");
}
if (options.length > 0) {
const longestOptionName = findLongest(options.map((option) => option.rawName));
sections.push({
title: "Options",
body: options.map((option) => {
return ` ${padRight(option.rawName, longestOptionName.length)} ${option.description} ${option.config.default === void 0 ? "" : `(default: ${option.config.default})`}`;
}).join("\n")
});
}
if (this.examples.length > 0) {
sections.push({
title: "Examples",
body: this.examples.map((example) => {
if (typeof example === "function") {
return example(name);
}
return example;
}).join("\n")
});
}
if (helpCallback) {
sections = helpCallback(sections) || sections;
}
console.log(sections.map((section) => {
return section.title ? `${section.title}:
${section.body}` : section.body;
}).join("\n\n"));
}
outputVersion() {
const {name} = this.cli;
const {versionNumber} = this.cli.globalCommand;
if (versionNumber) {
console.log(`${name}/${versionNumber} ${platformInfo}`);
}
}
checkRequiredArgs() {
const minimalArgsCount = this.args.filter((arg) => arg.required).length;
if (this.cli.args.length < minimalArgsCount) {
throw new CACError(`missing required args for command \`${this.rawName}\``);
}
}
checkUnknownOptions() {
const {options, globalCommand} = this.cli;
if (!this.config.allowUnknownOptions) {
for (const name of Object.keys(options)) {
if (name !== "--" && !this.hasOption(name) && !globalCommand.hasOption(name)) {
throw new CACError(`Unknown option \`${name.length > 1 ? `--${name}` : `-${name}`}\``);
}
}
}
}
checkOptionValue() {
const {options: parsedOptions, globalCommand} = this.cli;
const options = [...globalCommand.options, ...this.options];
for (const option of options) {
// skip dot names because only top level options are required
if (option.name.includes('.')) {
continue;
}
const value = parsedOptions[option.name];
if (option.required) {
const hasNegated = options.some((o) => o.negated && o.names.includes(option.name));
if (value === true || value === false && !hasNegated) {
throw new CACError(`option \`${option.rawName}\` value is missing`);
}
}
}
}
}
class GlobalCommand extends Command {
constructor(cli) {
super("@@global@@", "", {}, cli);
}
}
var __assign = Object.assign;
class CAC extends EventEmitter {
constructor(name = "") {
super();
this.name = name;
this.commands = [];
this.rawArgs = [];
this.args = [];
this.options = {};
this.globalCommand = new GlobalCommand(this);
this.globalCommand.usage("<command> [options]");
}
usage(text) {
this.globalCommand.usage(text);
return this;
}
command(rawName, description, config) {
const command = new Command(rawName, description || "", config, this);
command.globalCommand = this.globalCommand;
this.commands.push(command);
return command;
}
option(rawName, description, config) {
this.globalCommand.option(rawName, description, config);
return this;
}
help(callback) {
this.globalCommand.option("-h, --help", "Display this message");
this.globalCommand.helpCallback = callback;
this.showHelpOnExit = true;
return this;
}
version(version, customFlags = "-v, --version") {
this.globalCommand.version(version, customFlags);
this.showVersionOnExit = true;
return this;
}
example(example) {
this.globalCommand.example(example);
return this;
}
outputHelp() {
if (this.matchedCommand) {
this.matchedCommand.outputHelp();
} else {
this.globalCommand.outputHelp();
}
}
outputVersion() {
this.globalCommand.outputVersion();
}
setParsedInfo({args, options}, matchedCommand, matchedCommandName) {
this.args = args;
this.options = options;
if (matchedCommand) {
this.matchedCommand = matchedCommand;
}
if (matchedCommandName) {
this.matchedCommandName = matchedCommandName;
}
return this;
}
unsetMatchedCommand() {
this.matchedCommand = void 0;
this.matchedCommandName = void 0;
}
parse(argv = processArgs, {
run = true
} = {}) {
this.rawArgs = argv;
if (!this.name) {
this.name = argv[1] ? getFileName(argv[1]) : "cli";
}
let shouldParse = true;
for (const command of this.commands) {
const parsed = this.mri(argv.slice(2), command);
const commandName = parsed.args[0];
if (command.isMatched(commandName)) {
shouldParse = false;
const parsedInfo = __assign(__assign({}, parsed), {
args: parsed.args.slice(1)
});
this.setParsedInfo(parsedInfo, command, commandName);
this.emit(`command:${commandName}`, command);
}
}
if (shouldParse) {
for (const command of this.commands) {
if (command.name === "") {
shouldParse = false;
const parsed = this.mri(argv.slice(2), command);
this.setParsedInfo(parsed, command);
this.emit(`command:!`, command);
}
}
}
if (shouldParse) {
const parsed = this.mri(argv.slice(2));
this.setParsedInfo(parsed);
}
if (this.options.help && this.showHelpOnExit) {
this.outputHelp();
run = false;
this.unsetMatchedCommand();
}
if (this.options.version && this.showVersionOnExit && this.matchedCommandName == null) {
this.outputVersion();
run = false;
this.unsetMatchedCommand();
}
const parsedArgv = {args: this.args, options: this.options};
if (run) {
this.runMatchedCommand();
}
if (!this.matchedCommand && this.args[0]) {
this.emit("command:*");
}
return parsedArgv;
}
mri(argv, command) {
const cliOptions = [
...this.globalCommand.options,
...command ? command.options : []
];
const mriOptions = getMriOptions(cliOptions);
let argsAfterDoubleDashes = [];
const doubleDashesIndex = argv.indexOf("--");
if (doubleDashesIndex > -1) {
argsAfterDoubleDashes = argv.slice(doubleDashesIndex + 1);
argv = argv.slice(0, doubleDashesIndex);
}
let parsed = mri2(argv, mriOptions);
parsed = Object.keys(parsed).reduce((res, name) => {
return __assign(__assign({}, res), {
[camelcaseOptionName(name)]: parsed[name]
});
}, {_: []});
const args = parsed._;
const options = {
"--": argsAfterDoubleDashes
};
const ignoreDefault = command && command.config.ignoreOptionDefaultValue ? command.config.ignoreOptionDefaultValue : this.globalCommand.config.ignoreOptionDefaultValue;
let transforms = Object.create(null);
for (const cliOption of cliOptions) {
if (!ignoreDefault && cliOption.config.default !== void 0) {
for (const name of cliOption.names) {
options[name] = cliOption.config.default;
}
}
if (cliOption.config.type != null) {
if (transforms[cliOption.name] === void 0) {
transforms[cliOption.name] = cliOption.config.type;
}
}
}
for (const key of Object.keys(parsed)) {
if (key !== "_") {
const keys = key.split(".");
setDotProp(options, keys, parsed[key], transforms);
// setByType(options, transforms);
}
}
return {
args,
options
};
}
runMatchedCommand() {
const {args, options, matchedCommand: command} = this;
if (!command || !command.commandAction)
return;
command.checkUnknownOptions();
command.checkOptionValue();
command.checkRequiredArgs();
const actionArgs = [];
command.args.forEach((arg, index) => {
if (arg.variadic) {
actionArgs.push(args.slice(index));
} else {
actionArgs.push(args[index]);
}
});
actionArgs.push(options);
return command.commandAction.apply(this, actionArgs);
}
}
const cac = (name = "") => new CAC(name);
var version = "1.6.1";
const apiConfig = (port) => ({
port: {
description: `Specify server port. Note if the port is already being used, Vite will automatically try the next available port so this may not be the actual port the server ends up listening on. If true will be set to \`${port}\``,
argument: "[port]"
},
host: {
description: "Specify which IP addresses the server should listen on. Set this to `0.0.0.0` or `true` to listen on all addresses, including LAN and public addresses",
argument: "[host]"
},
strictPort: {
description: "Set to true to exit if port is already in use, instead of automatically trying the next available port"
},
middlewareMode: null
});
const poolThreadsCommands = {
isolate: {
description: "Isolate tests in threads pool (default: `true`)"
},
singleThread: {
description: "Run tests inside a single thread (default: `false`)"
},
maxThreads: {
description: "Maximum number of threads to run tests in",
argument: "<workers>"
},
minThreads: {
description: "Minimum number of threads to run tests in",
argument: "<workers>"
},
useAtomics: {
description: "Use Atomics to synchronize threads. This can improve performance in some cases, but might cause segfault in older Node versions (default: `false`)"
},
execArgv: null
};
const poolForksCommands = {
isolate: {
description: "Isolate tests in forks pool (default: `true`)"
},
singleFork: {
description: "Run tests inside a single child_process (default: `false`)"
},
maxForks: {
description: "Maximum number of processes to run tests in",
argument: "<workers>"
},
minForks: {
description: "Minimum number of processes to run tests in",
argument: "<workers>"
},
execArgv: null
};
function watermarkTransform(value) {
if (typeof value === "string")
return value.split(",").map(Number);
return value;
}
function transformNestedBoolean(value) {
if (typeof value === "boolean")
return { enabled: value };
return value;
}
const cliOptionsConfig = {
root: {
description: "Root path",
shorthand: "r",
argument: "<path>",
normalize: true
},
config: {
shorthand: "c",
description: "Path to config file",
argument: "<path>",
normalize: true
},
update: {
shorthand: "u",
description: "Update snapshot"
},
watch: {
shorthand: "w",
description: "Enable watch mode"
},
testNamePattern: {
description: "Run tests with full names matching the specified regexp pattern",
argument: "<pattern>",
shorthand: "t"
},
dir: {
description: "Base directory to scan for the test files",
argument: "<path>",
normalize: true
},
ui: {
description: "Enable UI"
},
open: {
description: "Open UI automatically (default: `!process.env.CI`)"
},
api: {
argument: "[port]",
description: `Specify server port. Note if the port is already being used, Vite will automatically try the next available port so this may not be the actual port the server ends up listening on. If true will be set to ${defaultPort}`,
subcommands: apiConfig(defaultPort)
},
silent: {
description: "Silent console output from tests"
},
hideSkippedTests: {
description: "Hide logs for skipped tests"
},
reporters: {
alias: "reporter",
description: "Specify reporters",
argument: "<name>",
subcommands: null,
// don't support custom objects
array: true
},
outputFile: {
argument: "<filename/-s>",
description: "Write test results to a file when supporter reporter is also specified, use cac's dot notation for individual outputs of multiple reporters (example: --outputFile.tap=./tap.txt)",
subcommands: null
},
coverage: {
description: "Enable coverage report",
argument: "",
// empty string means boolean
transform: transformNestedBoolean,
subcommands: {
all: {
description: "Whether to include all files, including the untested ones into report",
default: true
},
provider: {
description: 'Select the tool for coverage collection, available values are: "v8", "istanbul" and "custom"',
argument: "<name>"
},
enabled: {
description: "Enables coverage collection. Can be overridden using the `--coverage` CLI option (default: `false`)"
},
include: {
description: "Files included in coverage as glob patterns. May be specified more than once when using multiple patterns (default: `**`)",
argument: "<pattern>",
array: true
},
exclude: {
description: "Files to be excluded in coverage. May be specified more than once when using multiple extensions (default: Visit [`coverage.exclude`](https://vitest.dev/config/#coverage-exclude))",
argument: "<pattern>",
array: true
},
extension: {
description: 'Extension to be included in coverage. May be specified more than once when using multiple extensions (default: `[".js", ".cjs", ".mjs", ".ts", ".mts", ".cts", ".tsx", ".jsx", ".vue", ".svelte"]`)',
argument: "<extension>",
array: true
},
clean: {
description: "Clean coverage results before running tests (default: true)"
},
cleanOnRerun: {
description: "Clean coverage report on watch rerun (default: true)"
},
reportsDirectory: {
description: "Directory to write coverage report to (default: ./coverage)",
argument: "<path>",
normalize: true
},
reporter: {
description: 'Coverage reporters to use. Visit [`coverage.reporter`](https://vitest.dev/config/#coverage-reporter) for more information (default: `["text", "html", "clover", "json"]`)',
argument: "<name>",
subcommands: null,
// don't support custom objects
array: true
},
reportOnFailure: {
description: "Generate coverage report even when tests fail (default: `false`)"
},
allowExternal: {
description: "Collect coverage of files outside the project root (default: `false`)"
},
skipFull: {
description: "Do not show files with 100% statement, branch, and function coverage (default: `false`)"
},
thresholds: {
description: null,
argument: "",
// no displayed
subcommands: {
perFile: {
description: "Check thresholds per file. See `--coverage.thresholds.lines`, `--coverage.thresholds.functions`, `--coverage.thresholds.branches` and `--coverage.thresholds.statements` for the actual thresholds (default: `false`)"
},
autoUpdate: {
description: 'Update threshold values: "lines", "functions", "branches" and "statements" to configuration file when current coverage is above the configured thresholds (default: `false`)'
},
lines: {
description: "Threshold for lines. Visit [istanbuljs](https://github.com/istanbuljs/nyc#coverage-thresholds) for more information. This option is not available for custom providers",
argument: "<number>"
},
functions: {
description: "Threshold for functions. Visit [istanbuljs](https://github.com/istanbuljs/nyc#coverage-thresholds) for more information. This option is not available for custom providers",
argument: "<number>"
},
branches: {
description: "Threshold for branches. Visit [istanbuljs](https://github.com/istanbuljs/nyc#coverage-thresholds) for more information. This option is not available for custom providers",
argument: "<number>"
},
statements: {
description: "Threshold for statements. Visit [istanbuljs](https://github.com/istanbuljs/nyc#coverage-thresholds) for more information. This option is not available for custom providers",
argument: "<number>"
},
100: {
description: "Shortcut to set all coverage thresholds to 100 (default: `false`)"
}
}
},
ignoreClassMethods: {
description: "Array of class method names to ignore for coverage. Visit [istanbuljs](https://github.com/istanbuljs/nyc#ignoring-methods) for more information. This option is only available for the istanbul providers (default: `[]`)",
argument: "<name>",
array: true
},
processingConcurrency: {
description: "Concurrency limit used when processing the coverage results. (default min between 20 and the number of CPUs)",
argument: "<number>"
},
customProviderModule: {
description: "Specifies the module name or path for the custom coverage provider module. Visit [Custom Coverage Provider](https://vitest.dev/guide/coverage#custom-coverage-provider) for more information. This option is only available for custom providers",
argument: "<path>",
normalize: true
},
watermarks: {
description: null,
argument: "",
// no displayed
subcommands: {
statements: {
description: "High and low watermarks for statements in the format of `<high>,<low>`",
argument: "<watermarks>",
transform: watermarkTransform
},
lines: {
description: "High and low watermarks for lines in the format of `<high>,<low>`",
argument: "<watermarks>",
transform: watermarkTransform
},
branches: {
description: "High and low watermarks for branches in the format of `<high>,<low>`",
argument: "<watermarks>",
transform: watermarkTransform
},
functions: {
description: "High and low watermarks for functions in the format of `<high>,<low>`",
argument: "<watermarks>",
transform: watermarkTransform
}
}
}
}
},
mode: {
description: "Override Vite mode (default: `test` or `benchmark`)",
argument: "<name>"
},
workspace: {
description: "Path to a workspace configuration file",
argument: "<path>",
normalize: true
},
isolate: {
description: "Run every test file in isolation. To disable isolation, use `--no-isolate` (default: `true`)"
},
globals: {
description: "Inject apis globally"
},
dom: {
description: "Mock browser API with happy-dom"
},
browser: {
description: "Run tests in the browser. Equivalent to `--browser.enabled` (default: `false`)",
argument: "<name>",
transform(browser) {
if (typeof browser === "boolean")
return { enabled: browser };
if (browser === "true" || browser === "false")
return { enabled: browser === "true" };
if (browser === "yes" || browser === "no")
return { enabled: browser === "yes" };
if (typeof browser === "string")
return { enabled: true, name: browser };
return browser;
},
subcommands: {
enabled: {
description: "Run tests in the browser. Equivalent to `--browser.enabled` (default: `false`)"
},
name: {
description: "Run all tests in a specific browser. Some browsers are only available for specific providers (see `--browser.provider`). Visit [`browser.name`](https://vitest.dev/config/#browser-name) for more information",
argument: "<name>"
},
headless: {
description: "Run the browser in headless mode (i.e. without opening the GUI (Graphical User Interface)). If you are running Vitest in CI, it will be enabled by default (default: `process.env.CI`)"
},
api: {
description: "Specify options for the browser API server. Does not affect the --api option",
argument: "[port]",
subcommands: apiConfig(defaultBrowserPort)
},
provider: {
description: 'Provider used to run browser tests. Some browsers are only available for specific providers. Can be "webdriverio", "playwright", or the path to a custom provider. Visit [`browser.provider`](https://vitest.dev/config/#browser-provider) for more information (default: `"webdriverio"`)',
argument: "<name>",
subcommands: null
// don't support custom objects
},
providerOptions: {
description: "Options that are passed down to a browser provider. Visit [`browser.providerOptions`](https://vitest.dev/config/#browser-provideroptions) for more information",
argument: "<options>",
subcommands: null
// don't support custom objects
},
slowHijackESM: {
description: "Let Vitest use its own module resolution on the browser to enable APIs such as vi.mock and vi.spyOn. Visit [`browser.slowHijackESM`](https://vitest.dev/config/#browser-slowhijackesm) for more information (default: `false`)"
},
isolate: {
description: "Run every browser test file in isolation. To disable isolation, use `--browser.isolate=false` (default: `true`)"
},
fileParallelism: {
description: "Should all test files run in parallel. Use `--browser.file-parallelism=false` to disable (default: same as `--file-parallelism`)"
},
indexScripts: null,
testerScripts: null
}
},
pool: {
description: "Specify pool, if not running in the browser (default: `threads`)",
argument: "<pool>",
subcommands: null
// don't support custom objects
},
poolOptions: {
description: "Specify pool options",
argument: "<options>",
// we use casting here because TypeScript (for some reason) makes this into CLIOption<unknown>
// even when using casting, these types fail if the new option is added which is good
subcommands: {
threads: {
description: "Specify threads pool options",
argument: "<options>",
subcommands: poolThreadsCommands
},
vmThreads: {
description: "Specify VM threads pool options",
argument: "<options>",
subcommands: {
...poolThreadsCommands,
memoryLimit: {
description: "Memory limit for VM threads pool. If you see memory leaks, try to tinker this value.",
argument: "<limit>"
}
}
},
forks: {
description: "Specify forks pool options",
argument: "<options>",
subcommands: poolForksCommands
},
vmForks: {
description: "Specify VM forks pool options",
argument: "<options>",
subcommands: {
...poolForksCommands,
memoryLimit: {
description: "Memory limit for VM forks pool. If you see memory leaks, try to tinker this value.",
argument: "<limit>"
}
}
}
}
},
fileParallelism: {
description: "Should all test files run in parallel. Use `--no-file-parallelism` to disable (default: `true`)"
},
maxWorkers: {
description: "Maximum number of workers to run tests in",
argument: "<workers>"
},
minWorkers: {
description: "Minimum number of workers to run tests in",
argument: "<workers>"
},
environment: {
description: "Specify runner environment, if not running in the browser (default: `node`)",
argument: "<name>",
subcommands: null
// don't support custom objects
},
passWithNoTests: {
description: "Pass when no tests are found"
},
logHeapUsage: {
description: "Show the size of heap for each test when running in node"
},
allowOnly: {
description: "Allow tests and suites that are marked as only (default: `!process.env.CI`)"
},
dangerouslyIgnoreUnhandledErrors: {
description: "Ignore any unhandled errors that occur"
},
shard: {
description: "Test suite shard to execute in a format of `<index>/<count>`",
argument: "<shards>"
},
changed: {
description: "Run tests that are affected by the changed files (default: `false`)",
argument: "[since]"
},
sequence: {
description: "Options for how tests should be sorted",
argument: "<options>",
subcommands: {
shuffle: {
description: "Run files and tests in a random order. Enabling this option will impact Vitest's cache and have a performance impact. May be useful to find tests that accidentally depend on another run previously (default: `false`)",
argument: "",
subcommands: {
files: {
description: "Run files in a random order. Long running tests will not start earlier if you enable this option. (default: `false`)"
},
tests: {
description: "Run tests in a random oder (default: `false`)"
}
}
},
concurrent: {
description: "Make tests run in parallel (default: `false`)"
},
seed: {
description: 'Set the randomization seed. This option will have no effect if --sequence.shuffle is falsy. Visit ["Random Seed" page](https://en.wikipedia.org/wiki/Random_seed) for more information',
argument: "<seed>"
},
hooks: {
description: 'Changes the order in which hooks are executed. Accepted values are: "stack", "list" and "parallel". Visit [`sequence.hooks`](https://vitest.dev/config/#sequence-hooks) for more information (default: `"parallel"`)',
argument: "<order>"
},
setupFiles: {
description: 'Changes the order in which setup files are executed. Accepted values are: "list" and "parallel". If set to "list", will run setup files in the order they are defined. If set to "parallel", will run setup files in parallel (default: `"parallel"`)',
argument: "<order>"
}
}
},
inspect: {
description: "Enable Node.js inspector (default: `127.0.0.1:9229`)",
argument: "[[host:]port]",
transform(portOrEnabled) {
if (portOrEnabled === 0 || portOrEnabled === "true" || portOrEnabled === "yes")
return true;
if (portOrEnabled === "false" || portOrEnabled === "no")
return false;
return portOrEnabled;
}
},
inspectBrk: {
description: "Enable Node.js inspector and break before the test starts",
argument: "[[host:]port]",
transform(portOrEnabled) {
if (portOrEnabled === 0 || portOrEnabled === "true" || portOrEnabled === "yes")
return true;
if (portOrEnabled === "false" || portOrEnabled === "no")
return false;
return portOrEnabled;
}
},
inspector: null,
testTimeout: {
description: "Default timeout of a test in milliseconds (default: `5000`)",
argument: "<timeout>"
},
hookTimeout: {
description: "Default hook timeout in milliseconds (default: `10000`)",
argument: "<timeout>"
},
bail: {
description: "Stop test execution when given number of tests have failed (default: `0`)",
argument: "<number>"
},
retry: {
description: "Retry the test specific number of times if it fails (default: `0`)",
argument: "<times>"
},
diff: {
description: "Path to a diff config that will be used to generate diff interface",
argument: "<path>",
normalize: true
},
exclude: {
description: "Additional file globs to be excluded from test",
argument: "<glob>"
},
expandSnapshotDiff: {
description: "Show full diff when snapshot fails"
},
disableConsoleIntercept: {
description: "Disable automatic interception of console logging (default: `false`)"
},
typecheck: {
description: "Enable typechecking alongside tests (default: `false`)",
argument: "",
// allow boolean
transform: transformNestedBoolean,
subcommands: {
enabled: {
description: "Enable typechecking alongside tests (default: `false`)"
},
only: {
description: "Run only typecheck tests. This automatically enables typecheck (default: `false`)"
},
checker: {
description: 'Specify the typechecker to use. Available values are: "tcs" and "vue-tsc" and a path to an executable (default: `"tsc"`)',
argument: "<name>",
subcommands: null
},
allowJs: {
description: "Allow JavaScript files to be typechecked. By default takes the value from tsconfig.json"
},
ignoreSourceErrors: {
description: "Ignore type errors from source files"
},
tsconfig: {
description: "Path to a custom tsconfig file",
argument: "<path>",
normalize: true
},
include: null,
exclude: null
}
},
project: {
description: "The name of the project to run if you are using Vitest workspace feature. This can be repeated for multiple projects: `--project=1 --project=2`. You can also filter projects using wildcards like `--project=packages*`",
argument: "<name>",
array: true
},
slowTestThreshold: {
description: "Threshold in milliseconds for a test to be considered slow (default: `300`)",
argument: "<threshold>"
},
teardownTimeout: {
description: "Default timeout of a teardown function in milliseconds (default: `10000`)",
argument: "<timeout>"
},
cache: {
description: "Enable cache",
argument: "",
// allow only boolean
subcommands: {
dir: null
},
default: true,
// cache can only be "false" or an object
transform(cache) {
if (typeof cache !== "boolean" && cache)
throw new Error("--cache.dir is deprecated");
if (cache)
return {};
return cache;
}
},
maxConcurrency: {
description: "Maximum number of concurrent tests in a suite (default: `5`)",
argument: "<number>"
},
// CLI only options
run: {
description: "Disable watch mode"
},
segfaultRetry: {
description: "Retry the test suite if it crashes due to a segfault (default: `true`)",
argument: "<times>",
default: 0
},
color: {
description: "Removes colors from the console output",
alias: "no-color"
},
clearScreen: {
description: "Clear terminal screen when re-running tests during watch mode (default: `true`)"
},
standalone: {
description: "Start Vitest without running tests. File filters will be ignored, tests will be running only on change (default: `false`)"
},
// disable CLI options
cliExclude: null,
server: null,
setupFiles: null,
globalSetup: null,
snapshotFormat: null,
snapshotSerializers: null,
includeSource: null,
watchExclude: null,
alias: null,
env: null,
environmentMatchGlobs: null,
environmentOptions: null,
unstubEnvs: null,
related: null,
restoreMocks: null,
runner: null,
mockReset: null,
forceRerunTriggers: null,
unstubGlobals: null,
uiBase: null,
benchmark: null,
include: null,
testTransformMode: null,
fakeTimers: null,
chaiConfig: null,
clearMocks: null,
css: null,
poolMatchGlobs: null,
deps: null,
name: null,
includeTaskLocation: null,
snapshotEnvironment: null,
compare: null,
outputJson: null
};
const benchCliOptionsConfig = {
compare: {
description: "benchmark output file to compare against",
argument: "<filename>"
},
outputJson: {
description: "benchmark output file",
argument: "<filename>"
}
};
function addCommand(cli, name, option) {
const commandName = option.alias || name;
let command = option.shorthand ? `-${option.shorthand}, --${commandName}` : `--${commandName}`;
if ("argument" in option)
command += ` ${option.argument}`;
function transform(value) {
if (!option.array && Array.isArray(value)) {
const received = value.map((s) => typeof s === "string" ? `"${s}"` : s).join(", ");
throw new Error(
`Expected a single value for option "${command}", received [${received}]`
);
}
if (option.transform)
return option.transform(value);
if (option.array)
return toArray(value);
if (option.normalize)
return normalize(String(value));
return value;
}
const hasSubcommands = "subcommands" in option && option.subcommands;
if (option.description) {
let description = option.description.replace(/\[.*\]\((.*)\)/, "$1").replace(/`/g, "");
if (hasSubcommands)
description += `. Use '--help --${commandName}' for more info.`;
cli.option(command, description, {
type: transform
});
}
if (hasSubcommands) {
for (const commandName2 in option.subcommands) {
const subcommand = option.subcommands[commandName2];
if (subcommand)
addCommand(cli, `${name}.${commandName2}`, subcommand);
}
}
}
function addCliOptions(cli, options) {
for (const [optionName, option] of Object.entries(options)) {
if (option)
addCommand(cli, optionName, option);
}
}
function createCLI(options = {}) {
const cli = cac("vitest");
cli.version(version);
addCliOptions(cli, cliOptionsConfig);
cli.help((info) => {
const helpSection = info.find((current) => {
var _a;
return (_a = current.title) == null ? void 0 : _a.startsWith("For more info, run any command");
});
if (helpSection)
helpSection.body += "\n $ vitest --help --expand-help";
const options2 = info.find((current) => current.title === "Options");
if (typeof options2 !== "object")
return info;
const helpIndex = process.argv.findIndex((arg) => arg === "--help");
const subcommands = process.argv.slice(helpIndex + 1);
const defaultOutput = options2.body.split("\n").filter((line) => /^\s+--\S+\./.test(line) === false).join("\n");
if (subcommands.length === 0) {
options2.body = defaultOutput;
return info;
}
if (subcommands.length === 1 && (subcommands[0] === "--expand-help" || subcommands[0] === "--expandHelp"))
return info;
const subcommandMarker = "$SUB_COMMAND_MARKER$";
const banner = info.find((current) => /^vitest\/[0-9]+\.[0-9]+\.[0-9]+$/.test(current.body));
function addBannerWarning(warning) {
if (typeof (banner == null ? void 0 : banner.body) === "string") {
if (banner == null ? void 0 : banner.body.includes(warning))
return;
banner.body = `${banner.body}
WARN: ${warning}`;
}
}
for (let i = 0; i < subcommands.length; i++) {
const subcommand = subcommands[i];
if (subcommand === "--expand-help" || subcommand === "--expandHelp") {
addBannerWarning("--expand-help subcommand ignored because, when used with --help, it must be the only subcommand");
continue;
}
if (subcommand.startsWith("--")) {
options2.body = options2.body.split("\n").map((line) => line.trim().startsWith(subcommand) ? `${subcommandMarker}${line}` : line).join("\n");
}
}
options2.body = options2.body.split("\n").map((line) => line.startsWith(subcommandMarker) ? line.split(subcommandMarker)[1] : "").filter((line) => line.length !== 0).join("\n");
if (!options2.body) {
addBannerWarning("no options were found for your subcommands so we printed the whole output");
options2.body = defaultOutput;
}
return info;
});
cli.command("run [...filters]", void 0, options).action(run);
cli.command("related [...filters]", void 0, options).action(runRelated);
cli.command("watch [...filters]", void 0, options).action(watch);
cli.command("dev [...filters]", void 0, options).action(watch);
addCliOptions(
cli.command("bench [...filters]", void 0, options).action(benchmark),
benchCliOptionsConfig
);
cli.command("typecheck [...filters]").action(() => {
throw new Error(`Running typecheck via "typecheck" command is removed. Please use "--typecheck" to run your regular tests alongside typechecking, or "--typecheck.only" to run only typecheck tests.`);
});
cli.command("[...filters]", void 0, options).action((filters, options2) => start("test", filters, options2));
return cli;
}
function parseCLI(argv, config = {}) {
const arrayArgs = typeof argv === "string" ? argv.split(" ") : argv;
if (arrayArgs[0] !== "vitest")
throw new Error(`Expected "vitest" as the first argument, received "${arrayArgs[0]}"`);
arrayArgs[0] = "/index.js";
arrayArgs.unshift("node");
let { args, options } = createCLI(config).parse(arrayArgs, {
run: false
});
if (arrayArgs[2] === "watch" || arrayArgs[2] === "dev")
options.watch = true;
if (arrayArgs[2] === "run")
options.run = true;
if (arrayArgs[2] === "related") {
options.related = args;
options.passWithNoTests ?? (options.passWithNoTests = true);
args = [];
}
return {
filter: args,
options
};
}
async function runRelated(relatedFiles, argv) {
argv.related = relatedFiles;
argv.passWithNoTests ?? (argv.passWithNoTests = true);
await start("test", [], argv);
}
async function watch(cliFilters, options) {
options.watch = true;
await start("test", cliFilters, options);
}
async function run(cliFilters, options) {
options.run = true;
await start("test", cliFilters, options);
}
async function benchmark(cliFilters, options) {
console.warn(c.yellow("Benchmarking is an experimental feature.\nBreaking changes might not follow SemVer, please pin Vitest's version when using it."));
await start("benchmark", cliFilters, options);
}
function normalizeCliOptions(argv) {
if (argv.exclude) {
argv.cliExclude = toArray(argv.exclude);
delete argv.exclude;
}
return argv;
}
async function start(mode, cliFilters, options) {
try {
process.title = "node (vitest)";
} catch {
}
try {
const { startVitest } = await import('./cli-api.OdDWuB7Y.js').then(function (n) { return n.d; });
const ctx = await startVitest(mode, cliFilters.map(normalize), normalizeCliOptions(options));
if (!(ctx == null ? void 0 : ctx.shouldKeepServer()))
await (ctx == null ? void 0 : ctx.exit());
return ctx;
} catch (e) {
const { divider } = await import('./utils.dEtNIEgr.js').then(function (n) { return n.u; });
console.error(`
${c.red(divider(c.bold(c.inverse(" Unhandled Error "))))}`);
console.error(e);
console.error("\n\n");
process.exit(1);
}
}
export { createCLI as c, parseCLI as p, version as v };
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,65 @@
const defaultPort = 51204;
const defaultBrowserPort = 63315;
const defaultInspectPort = 9229;
const EXIT_CODE_RESTART = 43;
const API_PATH = "/__vitest_api__";
const extraInlineDeps = [
/^(?!.*(?:node_modules)).*\.mjs$/,
/^(?!.*(?:node_modules)).*\.cjs\.js$/,
// Vite client
/vite\w*\/dist\/client\/env.mjs/,
// Nuxt
"@nuxt/test-utils"
];
const CONFIG_NAMES = [
"vitest.config",
"vite.config"
];
const WORKSPACES_NAMES = [
"vitest.workspace",
"vitest.projects"
];
const CONFIG_EXTENSIONS = [
".ts",
".mts",
".cts",
".js",
".mjs",
".cjs"
];
const configFiles = CONFIG_NAMES.flatMap(
(name) => CONFIG_EXTENSIONS.map((ext) => name + ext)
);
const WORKSPACES_EXTENSIONS = [
...CONFIG_EXTENSIONS,
".json"
];
const workspacesFiles = WORKSPACES_NAMES.flatMap(
(name) => WORKSPACES_EXTENSIONS.map((ext) => name + ext)
);
const globalApis = [
// suite
"suite",
"test",
"describe",
"it",
// chai
"chai",
"expect",
"assert",
// typecheck
"expectTypeOf",
"assertType",
// utils
"vitest",
"vi",
// hooks
"beforeAll",
"afterAll",
"beforeEach",
"afterEach",
"onTestFinished",
"onTestFailed"
];
export { API_PATH as A, CONFIG_NAMES as C, EXIT_CODE_RESTART as E, defaultBrowserPort as a, defaultInspectPort as b, configFiles as c, defaultPort as d, extraInlineDeps as e, globalApis as g, workspacesFiles as w };
@@ -0,0 +1,53 @@
const CoverageProviderMap = {
v8: "@vitest/coverage-v8",
istanbul: "@vitest/coverage-istanbul"
};
async function resolveCoverageProviderModule(options, loader) {
if (!(options == null ? void 0 : options.enabled) || !options.provider)
return null;
const provider = options.provider;
if (provider === "v8" || provider === "istanbul") {
const { default: coverageModule } = await loader.executeId(CoverageProviderMap[provider]);
if (!coverageModule)
throw new Error(`Failed to load ${CoverageProviderMap[provider]}. Default export is missing.`);
return coverageModule;
}
let customProviderModule;
try {
customProviderModule = await loader.executeId(options.customProviderModule);
} catch (error) {
throw new Error(`Failed to load custom CoverageProviderModule from ${options.customProviderModule}`, { cause: error });
}
if (customProviderModule.default == null)
throw new Error(`Custom CoverageProviderModule loaded from ${options.customProviderModule} was not the default export`);
return customProviderModule.default;
}
async function getCoverageProvider(options, loader) {
const coverageModule = await resolveCoverageProviderModule(options, loader);
if (coverageModule)
return coverageModule.getProvider();
return null;
}
async function startCoverageInsideWorker(options, loader) {
var _a;
const coverageModule = await resolveCoverageProviderModule(options, loader);
if (coverageModule)
return (_a = coverageModule.startCoverage) == null ? void 0 : _a.call(coverageModule);
return null;
}
async function takeCoverageInsideWorker(options, loader) {
var _a;
const coverageModule = await resolveCoverageProviderModule(options, loader);
if (coverageModule)
return (_a = coverageModule.takeCoverage) == null ? void 0 : _a.call(coverageModule);
return null;
}
async function stopCoverageInsideWorker(options, loader) {
var _a;
const coverageModule = await resolveCoverageProviderModule(options, loader);
if (coverageModule)
return (_a = coverageModule.stopCoverage) == null ? void 0 : _a.call(coverageModule);
return null;
}
export { CoverageProviderMap as C, startCoverageInsideWorker as a, getCoverageProvider as g, stopCoverageInsideWorker as s, takeCoverageInsideWorker as t };
@@ -0,0 +1,51 @@
const RealDate = Date;
let now = null;
class MockDate extends RealDate {
constructor(y, m, d, h, M, s, ms) {
super();
let date;
switch (arguments.length) {
case 0:
if (now !== null)
date = new RealDate(now.valueOf());
else
date = new RealDate();
break;
case 1:
date = new RealDate(y);
break;
default:
d = typeof d === "undefined" ? 1 : d;
h = h || 0;
M = M || 0;
s = s || 0;
ms = ms || 0;
date = new RealDate(y, m, d, h, M, s, ms);
break;
}
Object.setPrototypeOf(date, MockDate.prototype);
return date;
}
}
MockDate.UTC = RealDate.UTC;
MockDate.now = function() {
return new MockDate().valueOf();
};
MockDate.parse = function(dateString) {
return RealDate.parse(dateString);
};
MockDate.toString = function() {
return RealDate.toString();
};
function mockDate(date) {
const dateObj = new RealDate(date.valueOf());
if (Number.isNaN(dateObj.getTime()))
throw new TypeError(`mockdate: The time set is an invalid date: ${date}`);
globalThis.Date = MockDate;
now = dateObj.valueOf();
}
function resetDate() {
globalThis.Date = RealDate;
}
export { RealDate as R, mockDate as m, resetDate as r };
@@ -0,0 +1,7 @@
import 'std-env';
var _a;
const isNode = typeof process < "u" && typeof process.stdout < "u" && !((_a = process.versions) == null ? void 0 : _a.deno) && !globalThis.window;
const isWindows = isNode && process.platform === "win32";
export { isWindows as a, isNode as i };
@@ -0,0 +1,594 @@
import vm from 'node:vm';
import { pathToFileURL } from 'node:url';
import { existsSync, readdirSync, readFileSync } from 'node:fs';
import { ViteNodeRunner, DEFAULT_REQUEST_STUBS } from 'vite-node/client';
import { isNodeBuiltin, isInternalRequest, toFilePath, isPrimitive } from 'vite-node/utils';
import { resolve, isAbsolute, dirname, join, basename, extname, normalize, relative } from 'pathe';
import { processError } from '@vitest/utils/error';
import { distDir } from '../path.js';
import { highlight, getType } from '@vitest/utils';
import { g as getAllMockableProperties } from './base.5NT-gWu5.js';
const spyModulePath = resolve(distDir, "spy.js");
class RefTracker {
idMap = /* @__PURE__ */ new Map();
mockedValueMap = /* @__PURE__ */ new Map();
getId(value) {
return this.idMap.get(value);
}
getMockedValue(id) {
return this.mockedValueMap.get(id);
}
track(originalValue, mockedValue) {
const newId = this.idMap.size;
this.idMap.set(originalValue, newId);
this.mockedValueMap.set(newId, mockedValue);
return newId;
}
}
function isSpecialProp(prop, parentType) {
return parentType.includes("Function") && typeof prop === "string" && ["arguments", "callee", "caller", "length", "name"].includes(prop);
}
class VitestMocker {
constructor(executor) {
this.executor = executor;
const context = this.executor.options.context;
if (context)
this.primitives = vm.runInContext("({ Object, Error, Function, RegExp, Symbol, Array, Map })", context);
else
this.primitives = { Object, Error, Function, RegExp, Symbol: globalThis.Symbol, Array, Map };
const Symbol2 = this.primitives.Symbol;
this.filterPublicKeys = ["__esModule", Symbol2.asyncIterator, Symbol2.hasInstance, Symbol2.isConcatSpreadable, Symbol2.iterator, Symbol2.match, Symbol2.matchAll, Symbol2.replace, Symbol2.search, Symbol2.split, Symbol2.species, Symbol2.toPrimitive, Symbol2.toStringTag, Symbol2.unscopables];
}
static pendingIds = [];
spyModule;
resolveCache = /* @__PURE__ */ new Map();
primitives;
filterPublicKeys;
mockContext = {
callstack: null
};
get root() {
return this.executor.options.root;
}
get mockMap() {
return this.executor.options.mockMap;
}
get moduleCache() {
return this.executor.moduleCache;
}
get moduleDirectories() {
return this.executor.options.moduleDirectories || [];
}
async initializeSpyModule() {
this.spyModule = await this.executor.executeId(spyModulePath);
}
deleteCachedItem(id) {
const mockId = this.getMockPath(id);
if (this.moduleCache.has(mockId))
this.moduleCache.delete(mockId);
}
isAModuleDirectory(path) {
return this.moduleDirectories.some((dir) => path.includes(dir));
}
getSuiteFilepath() {
return this.executor.state.filepath || "global";
}
createError(message, codeFrame) {
const Error2 = this.primitives.Error;
const error = new Error2(message);
Object.assign(error, { codeFrame });
return error;
}
getMocks() {
const suite = this.getSuiteFilepath();
const suiteMocks = this.mockMap.get(suite);
const globalMocks = this.mockMap.get("global");
return {
...globalMocks,
...suiteMocks
};
}
async resolvePath(rawId, importer) {
let id;
let fsPath;
try {
[id, fsPath] = await this.executor.originalResolveUrl(rawId, importer);
} catch (error) {
if (error.code === "ERR_MODULE_NOT_FOUND") {
const { id: unresolvedId } = error[Symbol.for("vitest.error.not_found.data")];
id = unresolvedId;
fsPath = unresolvedId;
} else {
throw error;
}
}
const external = !isAbsolute(fsPath) || this.isAModuleDirectory(fsPath) ? rawId : null;
return {
id,
fsPath,
external
};
}
async resolveMocks() {
if (!VitestMocker.pendingIds.length)
return;
await Promise.all(VitestMocker.pendingIds.map(async (mock) => {
const { fsPath, external } = await this.resolvePath(mock.id, mock.importer);
if (mock.type === "unmock")
this.unmockPath(fsPath);
if (mock.type === "mock")
this.mockPath(mock.id, fsPath, external, mock.factory);
}));
VitestMocker.pendingIds = [];
}
async callFunctionMock(dep, mock) {
var _a, _b;
const cached = (_a = this.moduleCache.get(dep)) == null ? void 0 : _a.exports;
if (cached)
return cached;
let exports;
try {
exports = await mock();
} catch (err) {
const vitestError = this.createError(
'[vitest] There was an error when mocking a module. If you are using "vi.mock" factory, make sure there are no top level variables inside, since this call is hoisted to top of the file. Read more: https://vitest.dev/api/vi.html#vi-mock'
);
vitestError.cause = err;
throw vitestError;
}
const filepath = dep.slice(5);
const mockpath = ((_b = this.resolveCache.get(this.getSuiteFilepath())) == null ? void 0 : _b[filepath]) || filepath;
if (exports === null || typeof exports !== "object")
throw this.createError(`[vitest] vi.mock("${mockpath}", factory?: () => unknown) is not returning an object. Did you mean to return an object with a "default" key?`);
const moduleExports = new Proxy(exports, {
get: (target, prop) => {
const val = target[prop];
if (prop === "then") {
if (target instanceof Promise)
return target.then.bind(target);
} else if (!(prop in target)) {
if (this.filterPublicKeys.includes(prop))
return void 0;
throw this.createError(
`[vitest] No "${String(prop)}" export is defined on the "${mockpath}" mock. Did you forget to return it from "vi.mock"?
If you need to partially mock a module, you can use "importOriginal" helper inside:
`,
highlight(`vi.mock("${mockpath}", async (importOriginal) => {
const actual = await importOriginal()
return {
...actual,
// your mocked methods
}
})`)
);
}
return val;
}
});
this.moduleCache.set(dep, { exports: moduleExports });
return moduleExports;
}
getMockContext() {
return this.mockContext;
}
getMockPath(dep) {
return `mock:${dep}`;
}
getDependencyMock(id) {
return this.getMocks()[id];
}
normalizePath(path) {
return this.moduleCache.normalizePath(path);
}
resolveMockPath(mockPath, external) {
const path = external || mockPath;
if (external || isNodeBuiltin(mockPath) || !existsSync(mockPath)) {
const mockDirname = dirname(path);
const mockFolder = join(this.root, "__mocks__", mockDirname);
if (!existsSync(mockFolder))
return null;
const files = readdirSync(mockFolder);
const baseOriginal = basename(path);
for (const file of files) {
const baseFile = basename(file, extname(file));
if (baseFile === baseOriginal)
return resolve(mockFolder, file);
}
return null;
}
const dir = dirname(path);
const baseId = basename(path);
const fullPath = resolve(dir, "__mocks__", baseId);
return existsSync(fullPath) ? fullPath : null;
}
mockObject(object, mockExports = {}) {
const finalizers = new Array();
const refs = new RefTracker();
const define = (container, key, value) => {
try {
container[key] = value;
return true;
} catch {
return false;
}
};
const mockPropertiesOf = (container, newContainer) => {
const containerType = getType(container);
const isModule = containerType === "Module" || !!container.__esModule;
for (const { key: property, descriptor } of getAllMockableProperties(container, isModule, this.primitives)) {
if (!isModule && descriptor.get) {
try {
Object.defineProperty(newContainer, property, descriptor);
} catch (error) {
}
continue;
}
if (isSpecialProp(property, containerType))
continue;
const value = container[property];
const refId = refs.getId(value);
if (refId !== void 0) {
finalizers.push(() => define(newContainer, property, refs.getMockedValue(refId)));
continue;
}
const type = getType(value);
if (Array.isArray(value)) {
define(newContainer, property, []);
continue;
}
const isFunction = type.includes("Function") && typeof value === "function";
if ((!isFunction || value.__isMockFunction) && type !== "Object" && type !== "Module") {
define(newContainer, property, value);
continue;
}
if (!define(newContainer, property, isFunction ? value : {}))
continue;
if (isFunction) {
let mockFunction2 = function() {
if (this instanceof newContainer[property]) {
for (const { key, descriptor: descriptor2 } of getAllMockableProperties(this, false, primitives)) {
if (descriptor2.get)
continue;
const value2 = this[key];
const type2 = getType(value2);
const isFunction2 = type2.includes("Function") && typeof value2 === "function";
if (isFunction2) {
const original = this[key];
const mock2 = spyModule.spyOn(this, key).mockImplementation(original);
mock2.mockRestore = () => {
mock2.mockReset();
mock2.mockImplementation(original);
return mock2;
};
}
}
}
};
if (!this.spyModule)
throw this.createError("[vitest] `spyModule` is not defined. This is Vitest error. Please open a new issue with reproduction.");
const spyModule = this.spyModule;
const primitives = this.primitives;
const mock = spyModule.spyOn(newContainer, property).mockImplementation(mockFunction2);
mock.mockRestore = () => {
mock.mockReset();
mock.mockImplementation(mockFunction2);
return mock;
};
Object.defineProperty(newContainer[property], "length", { value: 0 });
}
refs.track(value, newContainer[property]);
mockPropertiesOf(value, newContainer[property]);
}
};
const mockedObject = mockExports;
mockPropertiesOf(object, mockedObject);
for (const finalizer of finalizers)
finalizer();
return mockedObject;
}
unmockPath(path) {
const suitefile = this.getSuiteFilepath();
const id = this.normalizePath(path);
const mock = this.mockMap.get(suitefile);
if (mock && id in mock)
delete mock[id];
this.deleteCachedItem(id);
}
mockPath(originalId, path, external, factory) {
const id = this.normalizePath(path);
const suitefile = this.getSuiteFilepath();
const mocks = this.mockMap.get(suitefile) || {};
const resolves = this.resolveCache.get(suitefile) || {};
mocks[id] = factory || this.resolveMockPath(path, external);
resolves[id] = originalId;
this.mockMap.set(suitefile, mocks);
this.resolveCache.set(suitefile, resolves);
this.deleteCachedItem(id);
}
async importActual(rawId, importer, callstack) {
const { id, fsPath } = await this.resolvePath(rawId, importer);
const result = await this.executor.cachedRequest(id, fsPath, callstack || [importer]);
return result;
}
async importMock(rawId, importee) {
const { id, fsPath, external } = await this.resolvePath(rawId, importee);
const normalizedId = this.normalizePath(fsPath);
let mock = this.getDependencyMock(normalizedId);
if (mock === void 0)
mock = this.resolveMockPath(fsPath, external);
if (mock === null) {
const mod = await this.executor.cachedRequest(id, fsPath, [importee]);
return this.mockObject(mod);
}
if (typeof mock === "function")
return this.callFunctionMock(fsPath, mock);
return this.executor.dependencyRequest(mock, mock, [importee]);
}
async requestWithMock(url, callstack) {
const id = this.normalizePath(url);
const mock = this.getDependencyMock(id);
const mockPath = this.getMockPath(id);
if (mock === null) {
const cache = this.moduleCache.get(mockPath);
if (cache.exports)
return cache.exports;
const exports = {};
this.moduleCache.set(mockPath, { exports });
const mod = await this.executor.directRequest(url, url, callstack);
this.mockObject(mod, exports);
return exports;
}
if (typeof mock === "function" && !callstack.includes(mockPath) && !callstack.includes(url)) {
try {
callstack.push(mockPath);
this.mockContext.callstack = callstack;
return await this.callFunctionMock(mockPath, mock);
} finally {
this.mockContext.callstack = null;
const indexMock = callstack.indexOf(mockPath);
callstack.splice(indexMock, 1);
}
}
if (typeof mock === "string" && !callstack.includes(mock))
return mock;
}
queueMock(id, importer, factory, throwIfCached = false) {
VitestMocker.pendingIds.push({ type: "mock", id, importer, factory, throwIfCached });
}
queueUnmock(id, importer, throwIfCached = false) {
VitestMocker.pendingIds.push({ type: "unmock", id, importer, throwIfCached });
}
}
async function createVitestExecutor(options) {
const runner = new VitestExecutor(options);
await runner.executeId("/@vite/env");
await runner.mocker.initializeSpyModule();
return runner;
}
const externalizeMap = /* @__PURE__ */ new Map();
const bareVitestRegexp = /^@?vitest(\/|$)/;
const dispose = [];
function listenForErrors(state) {
dispose.forEach((fn) => fn());
dispose.length = 0;
function catchError(err, type) {
var _a;
const worker = state();
const error = processError(err);
if (!isPrimitive(error)) {
error.VITEST_TEST_NAME = (_a = worker.current) == null ? void 0 : _a.name;
if (worker.filepath)
error.VITEST_TEST_PATH = relative(state().config.root, worker.filepath);
error.VITEST_AFTER_ENV_TEARDOWN = worker.environmentTeardownRun;
}
state().rpc.onUnhandledError(error, type);
}
const uncaughtException = (e) => catchError(e, "Uncaught Exception");
const unhandledRejection = (e) => catchError(e, "Unhandled Rejection");
process.on("uncaughtException", uncaughtException);
process.on("unhandledRejection", unhandledRejection);
dispose.push(() => {
process.off("uncaughtException", uncaughtException);
process.off("unhandledRejection", unhandledRejection);
});
}
async function startVitestExecutor(options) {
const state = () => globalThis.__vitest_worker__ || options.state;
const rpc = () => state().rpc;
process.exit = (code = process.exitCode || 0) => {
throw new Error(`process.exit unexpectedly called with "${code}"`);
};
listenForErrors(state);
const getTransformMode = () => {
return state().environment.transformMode ?? "ssr";
};
return await createVitestExecutor({
async fetchModule(id) {
if (externalizeMap.has(id))
return { externalize: externalizeMap.get(id) };
if (id.includes(distDir)) {
const { path } = toFilePath(id, state().config.root);
const externalize = pathToFileURL(path).toString();
externalizeMap.set(id, externalize);
return { externalize };
}
if (bareVitestRegexp.test(id)) {
externalizeMap.set(id, id);
return { externalize: id };
}
const result = await rpc().fetch(id, getTransformMode());
if (result.id && !result.externalize) {
const code = readFileSync(result.id, "utf-8");
return { code };
}
return result;
},
resolveId(id, importer) {
return rpc().resolveId(id, importer, getTransformMode());
},
get moduleCache() {
return state().moduleCache;
},
get mockMap() {
return state().mockMap;
},
get interopDefault() {
return state().config.deps.interopDefault;
},
get moduleDirectories() {
return state().config.deps.moduleDirectories;
},
get root() {
return state().config.root;
},
get base() {
return state().config.base;
},
...options
});
}
function updateStyle(id, css) {
if (typeof document === "undefined")
return;
const element = document.querySelector(`[data-vite-dev-id="${id}"]`);
if (element) {
element.textContent = css;
return;
}
const head = document.querySelector("head");
const style = document.createElement("style");
style.setAttribute("type", "text/css");
style.setAttribute("data-vite-dev-id", id);
style.textContent = css;
head == null ? void 0 : head.appendChild(style);
}
function removeStyle(id) {
if (typeof document === "undefined")
return;
const sheet = document.querySelector(`[data-vite-dev-id="${id}"]`);
if (sheet)
document.head.removeChild(sheet);
}
function getDefaultRequestStubs(context) {
if (!context) {
const clientStub2 = { ...DEFAULT_REQUEST_STUBS["@vite/client"], updateStyle, removeStyle };
return {
"/@vite/client": clientStub2,
"@vite/client": clientStub2
};
}
const clientStub = vm.runInContext(
`(defaultClient) => ({ ...defaultClient, updateStyle: ${updateStyle.toString()}, removeStyle: ${removeStyle.toString()} })`,
context
)(DEFAULT_REQUEST_STUBS["@vite/client"]);
return {
"/@vite/client": clientStub,
"@vite/client": clientStub
};
}
class VitestExecutor extends ViteNodeRunner {
constructor(options) {
super({
...options,
// interop is done inside the external executor instead
interopDefault: options.context ? false : options.interopDefault
});
this.options = options;
this.mocker = new VitestMocker(this);
if (!options.context) {
Object.defineProperty(globalThis, "__vitest_mocker__", {
value: this.mocker,
writable: true,
configurable: true
});
this.primitives = { Object, Reflect, Symbol };
} else if (options.externalModulesExecutor) {
this.primitives = vm.runInContext("({ Object, Reflect, Symbol })", options.context);
this.externalModules = options.externalModulesExecutor;
} else {
throw new Error("When context is provided, externalModulesExecutor must be provided as well.");
}
}
mocker;
externalModules;
primitives;
getContextPrimitives() {
return this.primitives;
}
get state() {
return globalThis.__vitest_worker__ || this.options.state;
}
shouldResolveId(id, _importee) {
var _a;
if (isInternalRequest(id) || id.startsWith("data:"))
return false;
const transformMode = ((_a = this.state.environment) == null ? void 0 : _a.transformMode) ?? "ssr";
return transformMode === "ssr" ? !isNodeBuiltin(id) : !id.startsWith("node:");
}
async originalResolveUrl(id, importer) {
return super.resolveUrl(id, importer);
}
async resolveUrl(id, importer) {
if (VitestMocker.pendingIds.length)
await this.mocker.resolveMocks();
if (importer && importer.startsWith("mock:"))
importer = importer.slice(5);
try {
return await super.resolveUrl(id, importer);
} catch (error) {
if (error.code === "ERR_MODULE_NOT_FOUND") {
const { id: id2 } = error[Symbol.for("vitest.error.not_found.data")];
const path = this.mocker.normalizePath(id2);
const mock = this.mocker.getDependencyMock(path);
if (mock !== void 0)
return [id2, id2];
}
throw error;
}
}
async runModule(context, transformed) {
const vmContext = this.options.context;
if (!vmContext || !this.externalModules)
return super.runModule(context, transformed);
const codeDefinition = `'use strict';async (${Object.keys(context).join(",")})=>{{`;
const code = `${codeDefinition}${transformed}
}}`;
const options = {
filename: context.__filename,
lineOffset: 0,
columnOffset: -codeDefinition.length
};
const fn = vm.runInContext(code, vmContext, {
...options,
// if we encountered an import, it's not inlined
importModuleDynamically: this.externalModules.importModuleDynamically
});
await fn(...Object.values(context));
}
async importExternalModule(path) {
if (this.externalModules)
return this.externalModules.import(path);
return super.importExternalModule(path);
}
async dependencyRequest(id, fsPath, callstack) {
const mocked = await this.mocker.requestWithMock(fsPath, callstack);
if (typeof mocked === "string")
return super.dependencyRequest(mocked, mocked, callstack);
if (mocked && typeof mocked === "object")
return mocked;
return super.dependencyRequest(id, fsPath, callstack);
}
prepareContext(context) {
if (this.state.filepath && normalize(this.state.filepath) === normalize(context.__filename)) {
const globalNamespace = this.options.context || globalThis;
Object.defineProperty(context.__vite_ssr_import_meta__, "vitest", { get: () => globalNamespace.__vitest_index__ });
}
if (this.options.context && this.externalModules)
context.require = this.externalModules.createRequire(context.__filename);
return context;
}
}
export { VitestExecutor as V, getDefaultRequestStubs as g, startVitestExecutor as s };
@@ -0,0 +1,23 @@
function getWorkerState() {
const workerState = globalThis.__vitest_worker__;
if (!workerState) {
const errorMsg = 'Vitest failed to access its internal state.\n\nOne of the following is possible:\n- "vitest" is imported directly without running "vitest" command\n- "vitest" is imported inside "globalSetup" (to fix this, use "setupFiles" instead, because "globalSetup" runs in a different context)\n- Otherwise, it might be a Vitest bug. Please report it to https://github.com/vitest-dev/vitest/issues\n';
throw new Error(errorMsg);
}
return workerState;
}
function provideWorkerState(context, state) {
Object.defineProperty(context, "__vitest_worker__", {
value: state,
configurable: true,
writable: true,
enumerable: false
});
return state;
}
function getCurrentEnvironment() {
const state = getWorkerState();
return state == null ? void 0 : state.environment.name;
}
export { getCurrentEnvironment as a, getWorkerState as g, provideWorkerState as p };
File diff suppressed because one or more lines are too long
@@ -0,0 +1,99 @@
const DEFAULT_TIMEOUT = 6e4;
function defaultSerialize(i) {
return i;
}
const defaultDeserialize = defaultSerialize;
const { clearTimeout, setTimeout } = globalThis;
const random = Math.random.bind(Math);
function createBirpc(functions, options) {
const {
post,
on,
eventNames = [],
serialize = defaultSerialize,
deserialize = defaultDeserialize,
resolver,
timeout = DEFAULT_TIMEOUT
} = options;
const rpcPromiseMap = /* @__PURE__ */ new Map();
let _promise;
const rpc = new Proxy({}, {
get(_, method) {
if (method === "$functions")
return functions;
const sendEvent = (...args) => {
post(serialize({ m: method, a: args, t: "q" }));
};
if (eventNames.includes(method)) {
sendEvent.asEvent = sendEvent;
return sendEvent;
}
const sendCall = async (...args) => {
await _promise;
return new Promise((resolve, reject) => {
const id = nanoid();
let timeoutId;
if (timeout >= 0) {
timeoutId = setTimeout(() => {
try {
options.onTimeoutError?.(method, args);
throw new Error(`[birpc] timeout on calling "${method}"`);
} catch (e) {
reject(e);
}
rpcPromiseMap.delete(id);
}, timeout).unref?.();
}
rpcPromiseMap.set(id, { resolve, reject, timeoutId });
post(serialize({ m: method, a: args, i: id, t: "q" }));
});
};
sendCall.asEvent = sendEvent;
return sendCall;
}
});
_promise = on(async (data, ...extra) => {
const msg = deserialize(data);
if (msg.t === "q") {
const { m: method, a: args } = msg;
let result, error;
const fn = resolver ? resolver(method, functions[method]) : functions[method];
if (!fn) {
error = new Error(`[birpc] function "${method}" not found`);
} else {
try {
result = await fn.apply(rpc, args);
} catch (e) {
error = e;
}
}
if (msg.i) {
if (error && options.onError)
options.onError(error, method, args);
post(serialize({ t: "s", i: msg.i, r: result, e: error }), ...extra);
}
} else {
const { i: ack, r: result, e: error } = msg;
const promise = rpcPromiseMap.get(ack);
if (promise) {
clearTimeout(promise.timeoutId);
if (error)
promise.reject(error);
else
promise.resolve(result);
}
rpcPromiseMap.delete(ack);
}
});
return rpc;
}
const urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
function nanoid(size = 21) {
let id = "";
let i = size;
while (i--)
id += urlAlphabet[random() * 64 | 0];
return id;
}
export { createBirpc as c };
@@ -0,0 +1,99 @@
import * as chai from 'chai';
import { resolve } from 'pathe';
import { distDir } from '../path.js';
import { g as getWorkerState } from './global.CkGT_TMy.js';
import { r as rpc } from './rpc.joBhAkyK.js';
import { t as takeCoverageInsideWorker } from './coverage.E7sG1b3r.js';
import { l as loadDiffConfig, a as loadSnapshotSerializers } from './setup-common.8nJLd4ay.js';
function setupChaiConfig(config) {
Object.assign(chai.config, config);
}
async function resolveSnapshotEnvironment(config, executor) {
if (!config.snapshotEnvironment) {
const { VitestNodeSnapshotEnvironment } = await import('../chunks/environments-node.vcoXCoKs.js');
return new VitestNodeSnapshotEnvironment();
}
const mod = await executor.executeId(config.snapshotEnvironment);
if (typeof mod.default !== "object" || !mod.default)
throw new Error("Snapshot environment module must have a default export object with a shape of `SnapshotEnvironment`");
return mod.default;
}
const runnersFile = resolve(distDir, "runners.js");
async function getTestRunnerConstructor(config, executor) {
if (!config.runner) {
const { VitestTestRunner, NodeBenchmarkRunner } = await executor.executeFile(runnersFile);
return config.mode === "test" ? VitestTestRunner : NodeBenchmarkRunner;
}
const mod = await executor.executeId(config.runner);
if (!mod.default && typeof mod.default !== "function")
throw new Error(`Runner must export a default function, but got ${typeof mod.default} imported from ${config.runner}`);
return mod.default;
}
async function resolveTestRunner(config, executor) {
const TestRunner = await getTestRunnerConstructor(config, executor);
const testRunner = new TestRunner(config);
Object.defineProperty(testRunner, "__vitest_executor", {
value: executor,
enumerable: false,
configurable: false
});
if (!testRunner.config)
testRunner.config = config;
if (!testRunner.importFile)
throw new Error('Runner must implement "importFile" method.');
const [diffOptions] = await Promise.all([
loadDiffConfig(config, executor),
loadSnapshotSerializers(config, executor)
]);
testRunner.config.diffOptions = diffOptions;
const originalOnTaskUpdate = testRunner.onTaskUpdate;
testRunner.onTaskUpdate = async (task) => {
const p = rpc().onTaskUpdate(task);
await (originalOnTaskUpdate == null ? void 0 : originalOnTaskUpdate.call(testRunner, task));
return p;
};
const originalOnCollected = testRunner.onCollected;
testRunner.onCollected = async (files) => {
const state = getWorkerState();
files.forEach((file) => {
file.prepareDuration = state.durations.prepare;
file.environmentLoad = state.durations.environment;
state.durations.prepare = 0;
state.durations.environment = 0;
});
rpc().onCollected(files);
await (originalOnCollected == null ? void 0 : originalOnCollected.call(testRunner, files));
};
const originalOnAfterRun = testRunner.onAfterRunFiles;
testRunner.onAfterRunFiles = async (files) => {
const state = getWorkerState();
const coverage = await takeCoverageInsideWorker(config.coverage, executor);
if (coverage) {
rpc().onAfterSuiteRun({
coverage,
transformMode: state.environment.transformMode,
projectName: state.ctx.projectName
});
}
await (originalOnAfterRun == null ? void 0 : originalOnAfterRun.call(testRunner, files));
};
const originalOnAfterRunTask = testRunner.onAfterRunTask;
testRunner.onAfterRunTask = async (test) => {
var _a, _b;
if (config.bail && ((_a = test.result) == null ? void 0 : _a.state) === "fail") {
const previousFailures = await rpc().getCountOfFailedTests();
const currentFailures = 1 + previousFailures;
if (currentFailures >= config.bail) {
rpc().onCancel("test-failure");
(_b = testRunner.onCancel) == null ? void 0 : _b.call(testRunner, "test-failure");
}
}
await (originalOnAfterRunTask == null ? void 0 : originalOnAfterRunTask.call(testRunner, test));
};
return testRunner;
}
export { resolveSnapshotEnvironment as a, resolveTestRunner as r, setupChaiConfig as s };
@@ -0,0 +1,678 @@
import { Console } from 'node:console';
const denyList = /* @__PURE__ */ new Set([
"GLOBAL",
"root",
"global",
"Buffer",
"ArrayBuffer",
"Uint8Array"
]);
const nodeGlobals = new Map(
Object.getOwnPropertyNames(globalThis).filter((global) => !denyList.has(global)).map((nodeGlobalsKey) => {
const descriptor = Object.getOwnPropertyDescriptor(
globalThis,
nodeGlobalsKey
);
if (!descriptor) {
throw new Error(
`No property descriptor for ${nodeGlobalsKey}, this is a bug in Vitest.`
);
}
return [nodeGlobalsKey, descriptor];
})
);
var node = {
name: "node",
transformMode: "ssr",
// this is largely copied from jest's node environment
async setupVM() {
const vm = await import('node:vm');
let context = vm.createContext();
let global = vm.runInContext(
"this",
context
);
const contextGlobals = new Set(Object.getOwnPropertyNames(global));
for (const [nodeGlobalsKey, descriptor] of nodeGlobals) {
if (!contextGlobals.has(nodeGlobalsKey)) {
if (descriptor.configurable) {
Object.defineProperty(global, nodeGlobalsKey, {
configurable: true,
enumerable: descriptor.enumerable,
get() {
const val = globalThis[nodeGlobalsKey];
Object.defineProperty(global, nodeGlobalsKey, {
configurable: true,
enumerable: descriptor.enumerable,
value: val,
writable: descriptor.writable === true || nodeGlobalsKey === "performance"
});
return val;
},
set(val) {
Object.defineProperty(global, nodeGlobalsKey, {
configurable: true,
enumerable: descriptor.enumerable,
value: val,
writable: true
});
}
});
} else if ("value" in descriptor) {
Object.defineProperty(global, nodeGlobalsKey, {
configurable: false,
enumerable: descriptor.enumerable,
value: descriptor.value,
writable: descriptor.writable
});
} else {
Object.defineProperty(global, nodeGlobalsKey, {
configurable: false,
enumerable: descriptor.enumerable,
get: descriptor.get,
set: descriptor.set
});
}
}
}
global.global = global;
global.Buffer = Buffer;
global.ArrayBuffer = ArrayBuffer;
global.Uint8Array = Uint8Array;
return {
getVmContext() {
return context;
},
teardown() {
context = void 0;
global = void 0;
}
};
},
async setup(global) {
global.console.Console = Console;
return {
teardown(global2) {
delete global2.console.Console;
}
};
}
};
const LIVING_KEYS = [
"DOMException",
"URL",
"URLSearchParams",
"EventTarget",
"NamedNodeMap",
"Node",
"Attr",
"Element",
"DocumentFragment",
"DOMImplementation",
"Document",
"XMLDocument",
"CharacterData",
"Text",
"CDATASection",
"ProcessingInstruction",
"Comment",
"DocumentType",
"NodeList",
"RadioNodeList",
"HTMLCollection",
"HTMLOptionsCollection",
"DOMStringMap",
"DOMTokenList",
"StyleSheetList",
"HTMLElement",
"HTMLHeadElement",
"HTMLTitleElement",
"HTMLBaseElement",
"HTMLLinkElement",
"HTMLMetaElement",
"HTMLStyleElement",
"HTMLBodyElement",
"HTMLHeadingElement",
"HTMLParagraphElement",
"HTMLHRElement",
"HTMLPreElement",
"HTMLUListElement",
"HTMLOListElement",
"HTMLLIElement",
"HTMLMenuElement",
"HTMLDListElement",
"HTMLDivElement",
"HTMLAnchorElement",
"HTMLAreaElement",
"HTMLBRElement",
"HTMLButtonElement",
"HTMLCanvasElement",
"HTMLDataElement",
"HTMLDataListElement",
"HTMLDetailsElement",
"HTMLDialogElement",
"HTMLDirectoryElement",
"HTMLFieldSetElement",
"HTMLFontElement",
"HTMLFormElement",
"HTMLHtmlElement",
"HTMLImageElement",
"HTMLInputElement",
"HTMLLabelElement",
"HTMLLegendElement",
"HTMLMapElement",
"HTMLMarqueeElement",
"HTMLMediaElement",
"HTMLMeterElement",
"HTMLModElement",
"HTMLOptGroupElement",
"HTMLOptionElement",
"HTMLOutputElement",
"HTMLPictureElement",
"HTMLProgressElement",
"HTMLQuoteElement",
"HTMLScriptElement",
"HTMLSelectElement",
"HTMLSlotElement",
"HTMLSourceElement",
"HTMLSpanElement",
"HTMLTableCaptionElement",
"HTMLTableCellElement",
"HTMLTableColElement",
"HTMLTableElement",
"HTMLTimeElement",
"HTMLTableRowElement",
"HTMLTableSectionElement",
"HTMLTemplateElement",
"HTMLTextAreaElement",
"HTMLUnknownElement",
"HTMLFrameElement",
"HTMLFrameSetElement",
"HTMLIFrameElement",
"HTMLEmbedElement",
"HTMLObjectElement",
"HTMLParamElement",
"HTMLVideoElement",
"HTMLAudioElement",
"HTMLTrackElement",
"HTMLFormControlsCollection",
"SVGElement",
"SVGGraphicsElement",
"SVGSVGElement",
"SVGTitleElement",
"SVGAnimatedString",
"SVGNumber",
"SVGStringList",
"Event",
"CloseEvent",
"CustomEvent",
"MessageEvent",
"ErrorEvent",
"HashChangeEvent",
"PopStateEvent",
"StorageEvent",
"ProgressEvent",
"PageTransitionEvent",
"SubmitEvent",
"UIEvent",
"FocusEvent",
"InputEvent",
"MouseEvent",
"KeyboardEvent",
"TouchEvent",
"CompositionEvent",
"WheelEvent",
"BarProp",
"External",
"Location",
"History",
"Screen",
"Crypto",
"Performance",
"Navigator",
"PluginArray",
"MimeTypeArray",
"Plugin",
"MimeType",
"FileReader",
"Blob",
"File",
"FileList",
"ValidityState",
"DOMParser",
"XMLSerializer",
"FormData",
"XMLHttpRequestEventTarget",
"XMLHttpRequestUpload",
"XMLHttpRequest",
"WebSocket",
"NodeFilter",
"NodeIterator",
"TreeWalker",
"AbstractRange",
"Range",
"StaticRange",
"Selection",
"Storage",
"CustomElementRegistry",
"ShadowRoot",
"MutationObserver",
"MutationRecord",
"Headers",
"AbortController",
"AbortSignal",
"Uint8Array",
"Uint16Array",
"Uint32Array",
"Uint8ClampedArray",
"Int8Array",
"Int16Array",
"Int32Array",
"Float32Array",
"Float64Array",
"ArrayBuffer",
"DOMRectReadOnly",
"DOMRect",
// not specified in docs, but is available
"Image",
"Audio",
"Option",
"CSS"
];
const OTHER_KEYS = [
"addEventListener",
"alert",
// 'atob',
"blur",
// 'btoa',
"cancelAnimationFrame",
/* 'clearInterval', */
/* 'clearTimeout', */
"close",
"confirm",
/* 'console', */
"createPopup",
"dispatchEvent",
"document",
"focus",
"frames",
"getComputedStyle",
"history",
"innerHeight",
"innerWidth",
"length",
"location",
"matchMedia",
"moveBy",
"moveTo",
"name",
"navigator",
"open",
"outerHeight",
"outerWidth",
"pageXOffset",
"pageYOffset",
"parent",
"postMessage",
"print",
"prompt",
"removeEventListener",
"requestAnimationFrame",
"resizeBy",
"resizeTo",
"screen",
"screenLeft",
"screenTop",
"screenX",
"screenY",
"scroll",
"scrollBy",
"scrollLeft",
"scrollTo",
"scrollTop",
"scrollX",
"scrollY",
"self",
/* 'setInterval', */
/* 'setTimeout', */
"stop",
/* 'toString', */
"top",
"Window",
"window"
];
const KEYS = LIVING_KEYS.concat(OTHER_KEYS);
const skipKeys = [
"window",
"self",
"top",
"parent"
];
function getWindowKeys(global, win, additionalKeys = []) {
const keysArray = [...additionalKeys, ...KEYS];
const keys = new Set(keysArray.concat(Object.getOwnPropertyNames(win)).filter((k) => {
if (skipKeys.includes(k))
return false;
if (k in global)
return keysArray.includes(k);
return true;
}));
return keys;
}
function isClassLikeName(name) {
return name[0] === name[0].toUpperCase();
}
function populateGlobal(global, win, options = {}) {
const { bindFunctions = false } = options;
const keys = getWindowKeys(global, win, options.additionalKeys);
const originals = /* @__PURE__ */ new Map();
const overrideObject = /* @__PURE__ */ new Map();
for (const key of keys) {
const boundFunction = bindFunctions && typeof win[key] === "function" && !isClassLikeName(key) && win[key].bind(win);
if (KEYS.includes(key) && key in global)
originals.set(key, global[key]);
Object.defineProperty(global, key, {
get() {
if (overrideObject.has(key))
return overrideObject.get(key);
if (boundFunction)
return boundFunction;
return win[key];
},
set(v) {
overrideObject.set(key, v);
},
configurable: true
});
}
global.window = global;
global.self = global;
global.top = global;
global.parent = global;
if (global.global)
global.global = global;
if (global.document && global.document.defaultView) {
Object.defineProperty(global.document, "defaultView", {
get: () => global,
enumerable: true,
configurable: true
});
}
skipKeys.forEach((k) => keys.add(k));
return {
keys,
skipKeys,
originals
};
}
function catchWindowErrors(window) {
let userErrorListenerCount = 0;
function throwUnhandlerError(e) {
if (userErrorListenerCount === 0 && e.error != null)
process.emit("uncaughtException", e.error);
}
const addEventListener = window.addEventListener.bind(window);
const removeEventListener = window.removeEventListener.bind(window);
window.addEventListener("error", throwUnhandlerError);
window.addEventListener = function(...args) {
if (args[0] === "error")
userErrorListenerCount++;
return addEventListener.apply(this, args);
};
window.removeEventListener = function(...args) {
if (args[0] === "error" && userErrorListenerCount)
userErrorListenerCount--;
return removeEventListener.apply(this, args);
};
return function clearErrorHandlers() {
window.removeEventListener("error", throwUnhandlerError);
};
}
var jsdom = {
name: "jsdom",
transformMode: "web",
async setupVM({ jsdom = {} }) {
const {
CookieJar,
JSDOM,
ResourceLoader,
VirtualConsole
} = await import('jsdom');
const {
html = "<!DOCTYPE html>",
userAgent,
url = "http://localhost:3000",
contentType = "text/html",
pretendToBeVisual = true,
includeNodeLocations = false,
runScripts = "dangerously",
resources,
console = false,
cookieJar = false,
...restOptions
} = jsdom;
let dom = new JSDOM(
html,
{
pretendToBeVisual,
resources: resources ?? (userAgent ? new ResourceLoader({ userAgent }) : void 0),
runScripts,
url,
virtualConsole: console && globalThis.console ? new VirtualConsole().sendTo(globalThis.console) : void 0,
cookieJar: cookieJar ? new CookieJar() : void 0,
includeNodeLocations,
contentType,
userAgent,
...restOptions
}
);
const clearWindowErrors = catchWindowErrors(dom.window);
dom.window.Buffer = Buffer;
dom.window.jsdom = dom;
const globalNames = [
"structuredClone",
"fetch",
"Request",
"Response",
"BroadcastChannel",
"MessageChannel",
"MessagePort",
"TextEncoder",
"TextDecoder"
];
for (const name of globalNames) {
const value = globalThis[name];
if (typeof value !== "undefined" && typeof dom.window[name] === "undefined")
dom.window[name] = value;
}
return {
getVmContext() {
return dom.getInternalVMContext();
},
teardown() {
clearWindowErrors();
dom.window.close();
dom = void 0;
}
};
},
async setup(global, { jsdom = {} }) {
const {
CookieJar,
JSDOM,
ResourceLoader,
VirtualConsole
} = await import('jsdom');
const {
html = "<!DOCTYPE html>",
userAgent,
url = "http://localhost:3000",
contentType = "text/html",
pretendToBeVisual = true,
includeNodeLocations = false,
runScripts = "dangerously",
resources,
console = false,
cookieJar = false,
...restOptions
} = jsdom;
const dom = new JSDOM(
html,
{
pretendToBeVisual,
resources: resources ?? (userAgent ? new ResourceLoader({ userAgent }) : void 0),
runScripts,
url,
virtualConsole: console && global.console ? new VirtualConsole().sendTo(global.console) : void 0,
cookieJar: cookieJar ? new CookieJar() : void 0,
includeNodeLocations,
contentType,
userAgent,
...restOptions
}
);
const { keys, originals } = populateGlobal(global, dom.window, { bindFunctions: true });
const clearWindowErrors = catchWindowErrors(global);
global.jsdom = dom;
return {
teardown(global2) {
clearWindowErrors();
dom.window.close();
delete global2.jsdom;
keys.forEach((key) => delete global2[key]);
originals.forEach((v, k) => global2[k] = v);
}
};
}
};
async function teardownWindow(win) {
if (win.close && win.happyDOM.abort) {
await win.happyDOM.abort();
win.close();
} else {
win.happyDOM.cancelAsync();
}
}
var happy = {
name: "happy-dom",
transformMode: "web",
async setupVM({ happyDOM = {} }) {
const { Window } = await import('happy-dom');
let win = new Window({
...happyDOM,
console: console && globalThis.console ? globalThis.console : void 0,
url: happyDOM.url || "http://localhost:3000",
settings: {
...happyDOM.settings,
disableErrorCapturing: true
}
});
win.Buffer = Buffer;
if (typeof structuredClone !== "undefined" && !win.structuredClone)
win.structuredClone = structuredClone;
return {
getVmContext() {
return win;
},
async teardown() {
await teardownWindow(win);
win = void 0;
}
};
},
async setup(global, { happyDOM = {} }) {
const { Window, GlobalWindow } = await import('happy-dom');
const win = new (GlobalWindow || Window)({
...happyDOM,
console: console && global.console ? global.console : void 0,
url: happyDOM.url || "http://localhost:3000",
settings: {
...happyDOM.settings,
disableErrorCapturing: true
}
});
const { keys, originals } = populateGlobal(global, win, {
bindFunctions: true,
// jsdom doesn't support Request and Response, but happy-dom does
additionalKeys: ["Request", "Response"]
});
return {
async teardown(global2) {
await teardownWindow(win);
keys.forEach((key) => delete global2[key]);
originals.forEach((v, k) => global2[k] = v);
}
};
}
};
var edge = {
name: "edge-runtime",
transformMode: "ssr",
async setupVM() {
const { EdgeVM } = await import('@edge-runtime/vm');
const vm = new EdgeVM({
extend: (context) => {
context.global = context;
context.Buffer = Buffer;
return context;
}
});
return {
getVmContext() {
return vm.context;
},
teardown() {
}
};
},
async setup(global) {
const { EdgeVM } = await import('@edge-runtime/vm');
const vm = new EdgeVM({
extend: (context) => {
context.global = context;
context.Buffer = Buffer;
KEYS.forEach((key) => {
if (key in global)
context[key] = global[key];
});
return context;
}
});
const { keys, originals } = populateGlobal(global, vm.context, { bindFunctions: true });
return {
teardown(global2) {
keys.forEach((key) => delete global2[key]);
originals.forEach((v, k) => global2[k] = v);
}
};
}
};
const environments = {
node,
jsdom,
"happy-dom": happy,
"edge-runtime": edge
};
const envPackageNames = {
"jsdom": "jsdom",
"happy-dom": "happy-dom",
"edge-runtime": "@edge-runtime/vm"
};
function getEnvPackageName(env) {
if (env === "node")
return null;
if (env in envPackageNames)
return envPackageNames[env];
if (env[0] === "." || env[0] === "/")
return null;
return `vitest-environment-${env}`;
}
export { environments as e, getEnvPackageName as g, populateGlobal as p };
@@ -0,0 +1,22 @@
import { relative } from 'pathe';
import '@vitest/runner/utils';
import '@vitest/utils';
import { g as getWorkerState } from './global.CkGT_TMy.js';
import './env.AtSIuHFg.js';
function getRunMode() {
return getWorkerState().config.mode;
}
function isRunningInBenchmark() {
return getRunMode() === "benchmark";
}
const relativePath = relative;
function removeUndefinedValues(obj) {
for (const key in Object.keys(obj)) {
if (obj[key] === void 0)
delete obj[key];
}
return obj;
}
export { removeUndefinedValues as a, isRunningInBenchmark as i, relativePath as r };
@@ -0,0 +1,129 @@
import { afterAll, afterEach, beforeAll, beforeEach, describe, it, onTestFailed, onTestFinished, suite, test } from '@vitest/runner';
import { b as bench } from './benchmark.yGkUTKnC.js';
import { i as isFirstRun, a as runOnce } from './run-once.Olz_Zkd8.js';
import { c as createExpect, a as globalExpect, v as vi, b as vitest } from './vi.YFlodzP_.js';
import { g as getWorkerState } from './global.CkGT_TMy.js';
import * as chai from 'chai';
import { assert, should } from 'chai';
function getRunningMode() {
return process.env.VITEST_MODE === "WATCH" ? "watch" : "run";
}
function isWatchMode() {
return getRunningMode() === "watch";
}
function inject(key) {
const workerState = getWorkerState();
return workerState.providedContext[key];
}
var dist = {};
(function (exports) {
Object.defineProperty(exports, "__esModule", { value: true });
exports.expectTypeOf = void 0;
const fn = () => true;
/**
* Similar to Jest's `expect`, but with type-awareness.
* Gives you access to a number of type-matchers that let you make assertions about the
* form of a reference or generic type parameter.
*
* @example
* import {foo, bar} from '../foo'
* import {expectTypeOf} from 'expect-type'
*
* test('foo types', () => {
* // make sure `foo` has type {a: number}
* expectTypeOf(foo).toMatchTypeOf({a: 1})
* expectTypeOf(foo).toHaveProperty('a').toBeNumber()
*
* // make sure `bar` is a function taking a string:
* expectTypeOf(bar).parameter(0).toBeString()
* expectTypeOf(bar).returns.not.toBeAny()
* })
*
* @description
* See the [full docs](https://npmjs.com/package/expect-type#documentation) for lots more examples.
*/
const expectTypeOf = (_actual) => {
const nonFunctionProperties = [
'parameters',
'returns',
'resolves',
'not',
'items',
'constructorParameters',
'thisParameter',
'instance',
'guards',
'asserts',
'branded',
];
const obj = {
/* eslint-disable mmkal/@typescript-eslint/no-unsafe-assignment */
toBeAny: fn,
toBeUnknown: fn,
toBeNever: fn,
toBeFunction: fn,
toBeObject: fn,
toBeArray: fn,
toBeString: fn,
toBeNumber: fn,
toBeBoolean: fn,
toBeVoid: fn,
toBeSymbol: fn,
toBeNull: fn,
toBeUndefined: fn,
toBeNullable: fn,
toMatchTypeOf: fn,
toEqualTypeOf: fn,
toBeCallableWith: fn,
toBeConstructibleWith: fn,
/* eslint-enable mmkal/@typescript-eslint/no-unsafe-assignment */
extract: exports.expectTypeOf,
exclude: exports.expectTypeOf,
toHaveProperty: exports.expectTypeOf,
parameter: exports.expectTypeOf,
};
const getterProperties = nonFunctionProperties;
getterProperties.forEach((prop) => Object.defineProperty(obj, prop, { get: () => (0, exports.expectTypeOf)({}) }));
return obj;
};
exports.expectTypeOf = expectTypeOf;
} (dist));
function noop() {
}
const assertType = noop;
var VitestIndex = /*#__PURE__*/Object.freeze({
__proto__: null,
afterAll: afterAll,
afterEach: afterEach,
assert: assert,
assertType: assertType,
beforeAll: beforeAll,
beforeEach: beforeEach,
bench: bench,
chai: chai,
createExpect: createExpect,
describe: describe,
expect: globalExpect,
expectTypeOf: dist.expectTypeOf,
getRunningMode: getRunningMode,
inject: inject,
isFirstRun: isFirstRun,
isWatchMode: isWatchMode,
it: it,
onTestFailed: onTestFailed,
onTestFinished: onTestFinished,
runOnce: runOnce,
should: should,
suite: suite,
test: test,
vi: vi,
vitest: vitest
});
export { VitestIndex as V, isWatchMode as a, assertType as b, dist as d, getRunningMode as g, inject as i };
+3962
View File
@@ -0,0 +1,3962 @@
import { g as getDefaultExportFromCjs } from './_commonjsHelpers.jjO7Zipk.js';
import require$$0 from 'util';
import p from 'path';
var utils$8 = {};
(function (exports) {
exports.isInteger = num => {
if (typeof num === 'number') {
return Number.isInteger(num);
}
if (typeof num === 'string' && num.trim() !== '') {
return Number.isInteger(Number(num));
}
return false;
};
/**
* Find a node of the given type
*/
exports.find = (node, type) => node.nodes.find(node => node.type === type);
/**
* Find a node of the given type
*/
exports.exceedsLimit = (min, max, step = 1, limit) => {
if (limit === false) return false;
if (!exports.isInteger(min) || !exports.isInteger(max)) return false;
return ((Number(max) - Number(min)) / Number(step)) >= limit;
};
/**
* Escape the given node with '\\' before node.value
*/
exports.escapeNode = (block, n = 0, type) => {
let node = block.nodes[n];
if (!node) return;
if ((type && node.type === type) || node.type === 'open' || node.type === 'close') {
if (node.escaped !== true) {
node.value = '\\' + node.value;
node.escaped = true;
}
}
};
/**
* Returns true if the given brace node should be enclosed in literal braces
*/
exports.encloseBrace = node => {
if (node.type !== 'brace') return false;
if ((node.commas >> 0 + node.ranges >> 0) === 0) {
node.invalid = true;
return true;
}
return false;
};
/**
* Returns true if a brace node is invalid.
*/
exports.isInvalidBrace = block => {
if (block.type !== 'brace') return false;
if (block.invalid === true || block.dollar) return true;
if ((block.commas >> 0 + block.ranges >> 0) === 0) {
block.invalid = true;
return true;
}
if (block.open !== true || block.close !== true) {
block.invalid = true;
return true;
}
return false;
};
/**
* Returns true if a node is an open or close node
*/
exports.isOpenOrClose = node => {
if (node.type === 'open' || node.type === 'close') {
return true;
}
return node.open === true || node.close === true;
};
/**
* Reduce an array of text nodes.
*/
exports.reduce = nodes => nodes.reduce((acc, node) => {
if (node.type === 'text') acc.push(node.value);
if (node.type === 'range') node.type = 'text';
return acc;
}, []);
/**
* Flatten an array
*/
exports.flatten = (...args) => {
const result = [];
const flat = arr => {
for (let i = 0; i < arr.length; i++) {
let ele = arr[i];
Array.isArray(ele) ? flat(ele) : ele !== void 0 && result.push(ele);
}
return result;
};
flat(args);
return result;
};
} (utils$8));
const utils$7 = utils$8;
var stringify$4 = (ast, options = {}) => {
let stringify = (node, parent = {}) => {
let invalidBlock = options.escapeInvalid && utils$7.isInvalidBrace(parent);
let invalidNode = node.invalid === true && options.escapeInvalid === true;
let output = '';
if (node.value) {
if ((invalidBlock || invalidNode) && utils$7.isOpenOrClose(node)) {
return '\\' + node.value;
}
return node.value;
}
if (node.value) {
return node.value;
}
if (node.nodes) {
for (let child of node.nodes) {
output += stringify(child);
}
}
return output;
};
return stringify(ast);
};
/*!
* is-number <https://github.com/jonschlinkert/is-number>
*
* Copyright (c) 2014-present, Jon Schlinkert.
* Released under the MIT License.
*/
var isNumber$2 = function(num) {
if (typeof num === 'number') {
return num - num === 0;
}
if (typeof num === 'string' && num.trim() !== '') {
return Number.isFinite ? Number.isFinite(+num) : isFinite(+num);
}
return false;
};
/*!
* to-regex-range <https://github.com/micromatch/to-regex-range>
*
* Copyright (c) 2015-present, Jon Schlinkert.
* Released under the MIT License.
*/
const isNumber$1 = isNumber$2;
const toRegexRange$1 = (min, max, options) => {
if (isNumber$1(min) === false) {
throw new TypeError('toRegexRange: expected the first argument to be a number');
}
if (max === void 0 || min === max) {
return String(min);
}
if (isNumber$1(max) === false) {
throw new TypeError('toRegexRange: expected the second argument to be a number.');
}
let opts = { relaxZeros: true, ...options };
if (typeof opts.strictZeros === 'boolean') {
opts.relaxZeros = opts.strictZeros === false;
}
let relax = String(opts.relaxZeros);
let shorthand = String(opts.shorthand);
let capture = String(opts.capture);
let wrap = String(opts.wrap);
let cacheKey = min + ':' + max + '=' + relax + shorthand + capture + wrap;
if (toRegexRange$1.cache.hasOwnProperty(cacheKey)) {
return toRegexRange$1.cache[cacheKey].result;
}
let a = Math.min(min, max);
let b = Math.max(min, max);
if (Math.abs(a - b) === 1) {
let result = min + '|' + max;
if (opts.capture) {
return `(${result})`;
}
if (opts.wrap === false) {
return result;
}
return `(?:${result})`;
}
let isPadded = hasPadding(min) || hasPadding(max);
let state = { min, max, a, b };
let positives = [];
let negatives = [];
if (isPadded) {
state.isPadded = isPadded;
state.maxLen = String(state.max).length;
}
if (a < 0) {
let newMin = b < 0 ? Math.abs(b) : 1;
negatives = splitToPatterns(newMin, Math.abs(a), state, opts);
a = state.a = 0;
}
if (b >= 0) {
positives = splitToPatterns(a, b, state, opts);
}
state.negatives = negatives;
state.positives = positives;
state.result = collatePatterns(negatives, positives);
if (opts.capture === true) {
state.result = `(${state.result})`;
} else if (opts.wrap !== false && (positives.length + negatives.length) > 1) {
state.result = `(?:${state.result})`;
}
toRegexRange$1.cache[cacheKey] = state;
return state.result;
};
function collatePatterns(neg, pos, options) {
let onlyNegative = filterPatterns(neg, pos, '-', false) || [];
let onlyPositive = filterPatterns(pos, neg, '', false) || [];
let intersected = filterPatterns(neg, pos, '-?', true) || [];
let subpatterns = onlyNegative.concat(intersected).concat(onlyPositive);
return subpatterns.join('|');
}
function splitToRanges(min, max) {
let nines = 1;
let zeros = 1;
let stop = countNines(min, nines);
let stops = new Set([max]);
while (min <= stop && stop <= max) {
stops.add(stop);
nines += 1;
stop = countNines(min, nines);
}
stop = countZeros(max + 1, zeros) - 1;
while (min < stop && stop <= max) {
stops.add(stop);
zeros += 1;
stop = countZeros(max + 1, zeros) - 1;
}
stops = [...stops];
stops.sort(compare);
return stops;
}
/**
* Convert a range to a regex pattern
* @param {Number} `start`
* @param {Number} `stop`
* @return {String}
*/
function rangeToPattern(start, stop, options) {
if (start === stop) {
return { pattern: start, count: [], digits: 0 };
}
let zipped = zip(start, stop);
let digits = zipped.length;
let pattern = '';
let count = 0;
for (let i = 0; i < digits; i++) {
let [startDigit, stopDigit] = zipped[i];
if (startDigit === stopDigit) {
pattern += startDigit;
} else if (startDigit !== '0' || stopDigit !== '9') {
pattern += toCharacterClass(startDigit, stopDigit);
} else {
count++;
}
}
if (count) {
pattern += options.shorthand === true ? '\\d' : '[0-9]';
}
return { pattern, count: [count], digits };
}
function splitToPatterns(min, max, tok, options) {
let ranges = splitToRanges(min, max);
let tokens = [];
let start = min;
let prev;
for (let i = 0; i < ranges.length; i++) {
let max = ranges[i];
let obj = rangeToPattern(String(start), String(max), options);
let zeros = '';
if (!tok.isPadded && prev && prev.pattern === obj.pattern) {
if (prev.count.length > 1) {
prev.count.pop();
}
prev.count.push(obj.count[0]);
prev.string = prev.pattern + toQuantifier(prev.count);
start = max + 1;
continue;
}
if (tok.isPadded) {
zeros = padZeros(max, tok, options);
}
obj.string = zeros + obj.pattern + toQuantifier(obj.count);
tokens.push(obj);
start = max + 1;
prev = obj;
}
return tokens;
}
function filterPatterns(arr, comparison, prefix, intersection, options) {
let result = [];
for (let ele of arr) {
let { string } = ele;
// only push if _both_ are negative...
if (!intersection && !contains(comparison, 'string', string)) {
result.push(prefix + string);
}
// or _both_ are positive
if (intersection && contains(comparison, 'string', string)) {
result.push(prefix + string);
}
}
return result;
}
/**
* Zip strings
*/
function zip(a, b) {
let arr = [];
for (let i = 0; i < a.length; i++) arr.push([a[i], b[i]]);
return arr;
}
function compare(a, b) {
return a > b ? 1 : b > a ? -1 : 0;
}
function contains(arr, key, val) {
return arr.some(ele => ele[key] === val);
}
function countNines(min, len) {
return Number(String(min).slice(0, -len) + '9'.repeat(len));
}
function countZeros(integer, zeros) {
return integer - (integer % Math.pow(10, zeros));
}
function toQuantifier(digits) {
let [start = 0, stop = ''] = digits;
if (stop || start > 1) {
return `{${start + (stop ? ',' + stop : '')}}`;
}
return '';
}
function toCharacterClass(a, b, options) {
return `[${a}${(b - a === 1) ? '' : '-'}${b}]`;
}
function hasPadding(str) {
return /^-?(0+)\d/.test(str);
}
function padZeros(value, tok, options) {
if (!tok.isPadded) {
return value;
}
let diff = Math.abs(tok.maxLen - String(value).length);
let relax = options.relaxZeros !== false;
switch (diff) {
case 0:
return '';
case 1:
return relax ? '0?' : '0';
case 2:
return relax ? '0{0,2}' : '00';
default: {
return relax ? `0{0,${diff}}` : `0{${diff}}`;
}
}
}
/**
* Cache
*/
toRegexRange$1.cache = {};
toRegexRange$1.clearCache = () => (toRegexRange$1.cache = {});
/**
* Expose `toRegexRange`
*/
var toRegexRange_1 = toRegexRange$1;
/*!
* fill-range <https://github.com/jonschlinkert/fill-range>
*
* Copyright (c) 2014-present, Jon Schlinkert.
* Licensed under the MIT License.
*/
const util$1 = require$$0;
const toRegexRange = toRegexRange_1;
const isObject$1 = val => val !== null && typeof val === 'object' && !Array.isArray(val);
const transform = toNumber => {
return value => toNumber === true ? Number(value) : String(value);
};
const isValidValue = value => {
return typeof value === 'number' || (typeof value === 'string' && value !== '');
};
const isNumber = num => Number.isInteger(+num);
const zeros = input => {
let value = `${input}`;
let index = -1;
if (value[0] === '-') value = value.slice(1);
if (value === '0') return false;
while (value[++index] === '0');
return index > 0;
};
const stringify$3 = (start, end, options) => {
if (typeof start === 'string' || typeof end === 'string') {
return true;
}
return options.stringify === true;
};
const pad = (input, maxLength, toNumber) => {
if (maxLength > 0) {
let dash = input[0] === '-' ? '-' : '';
if (dash) input = input.slice(1);
input = (dash + input.padStart(dash ? maxLength - 1 : maxLength, '0'));
}
if (toNumber === false) {
return String(input);
}
return input;
};
const toMaxLen = (input, maxLength) => {
let negative = input[0] === '-' ? '-' : '';
if (negative) {
input = input.slice(1);
maxLength--;
}
while (input.length < maxLength) input = '0' + input;
return negative ? ('-' + input) : input;
};
const toSequence = (parts, options) => {
parts.negatives.sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
parts.positives.sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
let prefix = options.capture ? '' : '?:';
let positives = '';
let negatives = '';
let result;
if (parts.positives.length) {
positives = parts.positives.join('|');
}
if (parts.negatives.length) {
negatives = `-(${prefix}${parts.negatives.join('|')})`;
}
if (positives && negatives) {
result = `${positives}|${negatives}`;
} else {
result = positives || negatives;
}
if (options.wrap) {
return `(${prefix}${result})`;
}
return result;
};
const toRange = (a, b, isNumbers, options) => {
if (isNumbers) {
return toRegexRange(a, b, { wrap: false, ...options });
}
let start = String.fromCharCode(a);
if (a === b) return start;
let stop = String.fromCharCode(b);
return `[${start}-${stop}]`;
};
const toRegex = (start, end, options) => {
if (Array.isArray(start)) {
let wrap = options.wrap === true;
let prefix = options.capture ? '' : '?:';
return wrap ? `(${prefix}${start.join('|')})` : start.join('|');
}
return toRegexRange(start, end, options);
};
const rangeError = (...args) => {
return new RangeError('Invalid range arguments: ' + util$1.inspect(...args));
};
const invalidRange = (start, end, options) => {
if (options.strictRanges === true) throw rangeError([start, end]);
return [];
};
const invalidStep = (step, options) => {
if (options.strictRanges === true) {
throw new TypeError(`Expected step "${step}" to be a number`);
}
return [];
};
const fillNumbers = (start, end, step = 1, options = {}) => {
let a = Number(start);
let b = Number(end);
if (!Number.isInteger(a) || !Number.isInteger(b)) {
if (options.strictRanges === true) throw rangeError([start, end]);
return [];
}
// fix negative zero
if (a === 0) a = 0;
if (b === 0) b = 0;
let descending = a > b;
let startString = String(start);
let endString = String(end);
let stepString = String(step);
step = Math.max(Math.abs(step), 1);
let padded = zeros(startString) || zeros(endString) || zeros(stepString);
let maxLen = padded ? Math.max(startString.length, endString.length, stepString.length) : 0;
let toNumber = padded === false && stringify$3(start, end, options) === false;
let format = options.transform || transform(toNumber);
if (options.toRegex && step === 1) {
return toRange(toMaxLen(start, maxLen), toMaxLen(end, maxLen), true, options);
}
let parts = { negatives: [], positives: [] };
let push = num => parts[num < 0 ? 'negatives' : 'positives'].push(Math.abs(num));
let range = [];
let index = 0;
while (descending ? a >= b : a <= b) {
if (options.toRegex === true && step > 1) {
push(a);
} else {
range.push(pad(format(a, index), maxLen, toNumber));
}
a = descending ? a - step : a + step;
index++;
}
if (options.toRegex === true) {
return step > 1
? toSequence(parts, options)
: toRegex(range, null, { wrap: false, ...options });
}
return range;
};
const fillLetters = (start, end, step = 1, options = {}) => {
if ((!isNumber(start) && start.length > 1) || (!isNumber(end) && end.length > 1)) {
return invalidRange(start, end, options);
}
let format = options.transform || (val => String.fromCharCode(val));
let a = `${start}`.charCodeAt(0);
let b = `${end}`.charCodeAt(0);
let descending = a > b;
let min = Math.min(a, b);
let max = Math.max(a, b);
if (options.toRegex && step === 1) {
return toRange(min, max, false, options);
}
let range = [];
let index = 0;
while (descending ? a >= b : a <= b) {
range.push(format(a, index));
a = descending ? a - step : a + step;
index++;
}
if (options.toRegex === true) {
return toRegex(range, null, { wrap: false, options });
}
return range;
};
const fill$2 = (start, end, step, options = {}) => {
if (end == null && isValidValue(start)) {
return [start];
}
if (!isValidValue(start) || !isValidValue(end)) {
return invalidRange(start, end, options);
}
if (typeof step === 'function') {
return fill$2(start, end, 1, { transform: step });
}
if (isObject$1(step)) {
return fill$2(start, end, 0, step);
}
let opts = { ...options };
if (opts.capture === true) opts.wrap = true;
step = step || opts.step || 1;
if (!isNumber(step)) {
if (step != null && !isObject$1(step)) return invalidStep(step, opts);
return fill$2(start, end, 1, step);
}
if (isNumber(start) && isNumber(end)) {
return fillNumbers(start, end, step, opts);
}
return fillLetters(start, end, Math.max(Math.abs(step), 1), opts);
};
var fillRange = fill$2;
const fill$1 = fillRange;
const utils$6 = utils$8;
const compile$1 = (ast, options = {}) => {
let walk = (node, parent = {}) => {
let invalidBlock = utils$6.isInvalidBrace(parent);
let invalidNode = node.invalid === true && options.escapeInvalid === true;
let invalid = invalidBlock === true || invalidNode === true;
let prefix = options.escapeInvalid === true ? '\\' : '';
let output = '';
if (node.isOpen === true) {
return prefix + node.value;
}
if (node.isClose === true) {
return prefix + node.value;
}
if (node.type === 'open') {
return invalid ? (prefix + node.value) : '(';
}
if (node.type === 'close') {
return invalid ? (prefix + node.value) : ')';
}
if (node.type === 'comma') {
return node.prev.type === 'comma' ? '' : (invalid ? node.value : '|');
}
if (node.value) {
return node.value;
}
if (node.nodes && node.ranges > 0) {
let args = utils$6.reduce(node.nodes);
let range = fill$1(...args, { ...options, wrap: false, toRegex: true });
if (range.length !== 0) {
return args.length > 1 && range.length > 1 ? `(${range})` : range;
}
}
if (node.nodes) {
for (let child of node.nodes) {
output += walk(child, node);
}
}
return output;
};
return walk(ast);
};
var compile_1 = compile$1;
const fill = fillRange;
const stringify$2 = stringify$4;
const utils$5 = utils$8;
const append = (queue = '', stash = '', enclose = false) => {
let result = [];
queue = [].concat(queue);
stash = [].concat(stash);
if (!stash.length) return queue;
if (!queue.length) {
return enclose ? utils$5.flatten(stash).map(ele => `{${ele}}`) : stash;
}
for (let item of queue) {
if (Array.isArray(item)) {
for (let value of item) {
result.push(append(value, stash, enclose));
}
} else {
for (let ele of stash) {
if (enclose === true && typeof ele === 'string') ele = `{${ele}}`;
result.push(Array.isArray(ele) ? append(item, ele, enclose) : (item + ele));
}
}
}
return utils$5.flatten(result);
};
const expand$1 = (ast, options = {}) => {
let rangeLimit = options.rangeLimit === void 0 ? 1000 : options.rangeLimit;
let walk = (node, parent = {}) => {
node.queue = [];
let p = parent;
let q = parent.queue;
while (p.type !== 'brace' && p.type !== 'root' && p.parent) {
p = p.parent;
q = p.queue;
}
if (node.invalid || node.dollar) {
q.push(append(q.pop(), stringify$2(node, options)));
return;
}
if (node.type === 'brace' && node.invalid !== true && node.nodes.length === 2) {
q.push(append(q.pop(), ['{}']));
return;
}
if (node.nodes && node.ranges > 0) {
let args = utils$5.reduce(node.nodes);
if (utils$5.exceedsLimit(...args, options.step, rangeLimit)) {
throw new RangeError('expanded array length exceeds range limit. Use options.rangeLimit to increase or disable the limit.');
}
let range = fill(...args, options);
if (range.length === 0) {
range = stringify$2(node, options);
}
q.push(append(q.pop(), range));
node.nodes = [];
return;
}
let enclose = utils$5.encloseBrace(node);
let queue = node.queue;
let block = node;
while (block.type !== 'brace' && block.type !== 'root' && block.parent) {
block = block.parent;
queue = block.queue;
}
for (let i = 0; i < node.nodes.length; i++) {
let child = node.nodes[i];
if (child.type === 'comma' && node.type === 'brace') {
if (i === 1) queue.push('');
queue.push('');
continue;
}
if (child.type === 'close') {
q.push(append(q.pop(), queue, enclose));
continue;
}
if (child.value && child.type !== 'open') {
queue.push(append(queue.pop(), child.value));
continue;
}
if (child.nodes) {
walk(child, node);
}
}
return queue;
};
return utils$5.flatten(walk(ast));
};
var expand_1 = expand$1;
var constants$3 = {
MAX_LENGTH: 1024 * 64,
// Digits
CHAR_0: '0', /* 0 */
CHAR_9: '9', /* 9 */
// Alphabet chars.
CHAR_UPPERCASE_A: 'A', /* A */
CHAR_LOWERCASE_A: 'a', /* a */
CHAR_UPPERCASE_Z: 'Z', /* Z */
CHAR_LOWERCASE_Z: 'z', /* z */
CHAR_LEFT_PARENTHESES: '(', /* ( */
CHAR_RIGHT_PARENTHESES: ')', /* ) */
CHAR_ASTERISK: '*', /* * */
// Non-alphabetic chars.
CHAR_AMPERSAND: '&', /* & */
CHAR_AT: '@', /* @ */
CHAR_BACKSLASH: '\\', /* \ */
CHAR_BACKTICK: '`', /* ` */
CHAR_CARRIAGE_RETURN: '\r', /* \r */
CHAR_CIRCUMFLEX_ACCENT: '^', /* ^ */
CHAR_COLON: ':', /* : */
CHAR_COMMA: ',', /* , */
CHAR_DOLLAR: '$', /* . */
CHAR_DOT: '.', /* . */
CHAR_DOUBLE_QUOTE: '"', /* " */
CHAR_EQUAL: '=', /* = */
CHAR_EXCLAMATION_MARK: '!', /* ! */
CHAR_FORM_FEED: '\f', /* \f */
CHAR_FORWARD_SLASH: '/', /* / */
CHAR_HASH: '#', /* # */
CHAR_HYPHEN_MINUS: '-', /* - */
CHAR_LEFT_ANGLE_BRACKET: '<', /* < */
CHAR_LEFT_CURLY_BRACE: '{', /* { */
CHAR_LEFT_SQUARE_BRACKET: '[', /* [ */
CHAR_LINE_FEED: '\n', /* \n */
CHAR_NO_BREAK_SPACE: '\u00A0', /* \u00A0 */
CHAR_PERCENT: '%', /* % */
CHAR_PLUS: '+', /* + */
CHAR_QUESTION_MARK: '?', /* ? */
CHAR_RIGHT_ANGLE_BRACKET: '>', /* > */
CHAR_RIGHT_CURLY_BRACE: '}', /* } */
CHAR_RIGHT_SQUARE_BRACKET: ']', /* ] */
CHAR_SEMICOLON: ';', /* ; */
CHAR_SINGLE_QUOTE: '\'', /* ' */
CHAR_SPACE: ' ', /* */
CHAR_TAB: '\t', /* \t */
CHAR_UNDERSCORE: '_', /* _ */
CHAR_VERTICAL_LINE: '|', /* | */
CHAR_ZERO_WIDTH_NOBREAK_SPACE: '\uFEFF' /* \uFEFF */
};
const stringify$1 = stringify$4;
/**
* Constants
*/
const {
MAX_LENGTH: MAX_LENGTH$1,
CHAR_BACKSLASH, /* \ */
CHAR_BACKTICK, /* ` */
CHAR_COMMA: CHAR_COMMA$1, /* , */
CHAR_DOT: CHAR_DOT$1, /* . */
CHAR_LEFT_PARENTHESES: CHAR_LEFT_PARENTHESES$1, /* ( */
CHAR_RIGHT_PARENTHESES: CHAR_RIGHT_PARENTHESES$1, /* ) */
CHAR_LEFT_CURLY_BRACE: CHAR_LEFT_CURLY_BRACE$1, /* { */
CHAR_RIGHT_CURLY_BRACE: CHAR_RIGHT_CURLY_BRACE$1, /* } */
CHAR_LEFT_SQUARE_BRACKET: CHAR_LEFT_SQUARE_BRACKET$1, /* [ */
CHAR_RIGHT_SQUARE_BRACKET: CHAR_RIGHT_SQUARE_BRACKET$1, /* ] */
CHAR_DOUBLE_QUOTE, /* " */
CHAR_SINGLE_QUOTE, /* ' */
CHAR_NO_BREAK_SPACE,
CHAR_ZERO_WIDTH_NOBREAK_SPACE
} = constants$3;
/**
* parse
*/
const parse$3 = (input, options = {}) => {
if (typeof input !== 'string') {
throw new TypeError('Expected a string');
}
let opts = options || {};
let max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH$1, opts.maxLength) : MAX_LENGTH$1;
if (input.length > max) {
throw new SyntaxError(`Input length (${input.length}), exceeds max characters (${max})`);
}
let ast = { type: 'root', input, nodes: [] };
let stack = [ast];
let block = ast;
let prev = ast;
let brackets = 0;
let length = input.length;
let index = 0;
let depth = 0;
let value;
/**
* Helpers
*/
const advance = () => input[index++];
const push = node => {
if (node.type === 'text' && prev.type === 'dot') {
prev.type = 'text';
}
if (prev && prev.type === 'text' && node.type === 'text') {
prev.value += node.value;
return;
}
block.nodes.push(node);
node.parent = block;
node.prev = prev;
prev = node;
return node;
};
push({ type: 'bos' });
while (index < length) {
block = stack[stack.length - 1];
value = advance();
/**
* Invalid chars
*/
if (value === CHAR_ZERO_WIDTH_NOBREAK_SPACE || value === CHAR_NO_BREAK_SPACE) {
continue;
}
/**
* Escaped chars
*/
if (value === CHAR_BACKSLASH) {
push({ type: 'text', value: (options.keepEscaping ? value : '') + advance() });
continue;
}
/**
* Right square bracket (literal): ']'
*/
if (value === CHAR_RIGHT_SQUARE_BRACKET$1) {
push({ type: 'text', value: '\\' + value });
continue;
}
/**
* Left square bracket: '['
*/
if (value === CHAR_LEFT_SQUARE_BRACKET$1) {
brackets++;
let next;
while (index < length && (next = advance())) {
value += next;
if (next === CHAR_LEFT_SQUARE_BRACKET$1) {
brackets++;
continue;
}
if (next === CHAR_BACKSLASH) {
value += advance();
continue;
}
if (next === CHAR_RIGHT_SQUARE_BRACKET$1) {
brackets--;
if (brackets === 0) {
break;
}
}
}
push({ type: 'text', value });
continue;
}
/**
* Parentheses
*/
if (value === CHAR_LEFT_PARENTHESES$1) {
block = push({ type: 'paren', nodes: [] });
stack.push(block);
push({ type: 'text', value });
continue;
}
if (value === CHAR_RIGHT_PARENTHESES$1) {
if (block.type !== 'paren') {
push({ type: 'text', value });
continue;
}
block = stack.pop();
push({ type: 'text', value });
block = stack[stack.length - 1];
continue;
}
/**
* Quotes: '|"|`
*/
if (value === CHAR_DOUBLE_QUOTE || value === CHAR_SINGLE_QUOTE || value === CHAR_BACKTICK) {
let open = value;
let next;
if (options.keepQuotes !== true) {
value = '';
}
while (index < length && (next = advance())) {
if (next === CHAR_BACKSLASH) {
value += next + advance();
continue;
}
if (next === open) {
if (options.keepQuotes === true) value += next;
break;
}
value += next;
}
push({ type: 'text', value });
continue;
}
/**
* Left curly brace: '{'
*/
if (value === CHAR_LEFT_CURLY_BRACE$1) {
depth++;
let dollar = prev.value && prev.value.slice(-1) === '$' || block.dollar === true;
let brace = {
type: 'brace',
open: true,
close: false,
dollar,
depth,
commas: 0,
ranges: 0,
nodes: []
};
block = push(brace);
stack.push(block);
push({ type: 'open', value });
continue;
}
/**
* Right curly brace: '}'
*/
if (value === CHAR_RIGHT_CURLY_BRACE$1) {
if (block.type !== 'brace') {
push({ type: 'text', value });
continue;
}
let type = 'close';
block = stack.pop();
block.close = true;
push({ type, value });
depth--;
block = stack[stack.length - 1];
continue;
}
/**
* Comma: ','
*/
if (value === CHAR_COMMA$1 && depth > 0) {
if (block.ranges > 0) {
block.ranges = 0;
let open = block.nodes.shift();
block.nodes = [open, { type: 'text', value: stringify$1(block) }];
}
push({ type: 'comma', value });
block.commas++;
continue;
}
/**
* Dot: '.'
*/
if (value === CHAR_DOT$1 && depth > 0 && block.commas === 0) {
let siblings = block.nodes;
if (depth === 0 || siblings.length === 0) {
push({ type: 'text', value });
continue;
}
if (prev.type === 'dot') {
block.range = [];
prev.value += value;
prev.type = 'range';
if (block.nodes.length !== 3 && block.nodes.length !== 5) {
block.invalid = true;
block.ranges = 0;
prev.type = 'text';
continue;
}
block.ranges++;
block.args = [];
continue;
}
if (prev.type === 'range') {
siblings.pop();
let before = siblings[siblings.length - 1];
before.value += prev.value + value;
prev = before;
block.ranges--;
continue;
}
push({ type: 'dot', value });
continue;
}
/**
* Text
*/
push({ type: 'text', value });
}
// Mark imbalanced braces and brackets as invalid
do {
block = stack.pop();
if (block.type !== 'root') {
block.nodes.forEach(node => {
if (!node.nodes) {
if (node.type === 'open') node.isOpen = true;
if (node.type === 'close') node.isClose = true;
if (!node.nodes) node.type = 'text';
node.invalid = true;
}
});
// get the location of the block on parent.nodes (block's siblings)
let parent = stack[stack.length - 1];
let index = parent.nodes.indexOf(block);
// replace the (invalid) block with it's nodes
parent.nodes.splice(index, 1, ...block.nodes);
}
} while (stack.length > 0);
push({ type: 'eos' });
return ast;
};
var parse_1$1 = parse$3;
const stringify = stringify$4;
const compile = compile_1;
const expand = expand_1;
const parse$2 = parse_1$1;
/**
* Expand the given pattern or create a regex-compatible string.
*
* ```js
* const braces = require('braces');
* console.log(braces('{a,b,c}', { compile: true })); //=> ['(a|b|c)']
* console.log(braces('{a,b,c}')); //=> ['a', 'b', 'c']
* ```
* @param {String} `str`
* @param {Object} `options`
* @return {String}
* @api public
*/
const braces$1 = (input, options = {}) => {
let output = [];
if (Array.isArray(input)) {
for (let pattern of input) {
let result = braces$1.create(pattern, options);
if (Array.isArray(result)) {
output.push(...result);
} else {
output.push(result);
}
}
} else {
output = [].concat(braces$1.create(input, options));
}
if (options && options.expand === true && options.nodupes === true) {
output = [...new Set(output)];
}
return output;
};
/**
* Parse the given `str` with the given `options`.
*
* ```js
* // braces.parse(pattern, [, options]);
* const ast = braces.parse('a/{b,c}/d');
* console.log(ast);
* ```
* @param {String} pattern Brace pattern to parse
* @param {Object} options
* @return {Object} Returns an AST
* @api public
*/
braces$1.parse = (input, options = {}) => parse$2(input, options);
/**
* Creates a braces string from an AST, or an AST node.
*
* ```js
* const braces = require('braces');
* let ast = braces.parse('foo/{a,b}/bar');
* console.log(stringify(ast.nodes[2])); //=> '{a,b}'
* ```
* @param {String} `input` Brace pattern or AST.
* @param {Object} `options`
* @return {Array} Returns an array of expanded values.
* @api public
*/
braces$1.stringify = (input, options = {}) => {
if (typeof input === 'string') {
return stringify(braces$1.parse(input, options), options);
}
return stringify(input, options);
};
/**
* Compiles a brace pattern into a regex-compatible, optimized string.
* This method is called by the main [braces](#braces) function by default.
*
* ```js
* const braces = require('braces');
* console.log(braces.compile('a/{b,c}/d'));
* //=> ['a/(b|c)/d']
* ```
* @param {String} `input` Brace pattern or AST.
* @param {Object} `options`
* @return {Array} Returns an array of expanded values.
* @api public
*/
braces$1.compile = (input, options = {}) => {
if (typeof input === 'string') {
input = braces$1.parse(input, options);
}
return compile(input, options);
};
/**
* Expands a brace pattern into an array. This method is called by the
* main [braces](#braces) function when `options.expand` is true. Before
* using this method it's recommended that you read the [performance notes](#performance))
* and advantages of using [.compile](#compile) instead.
*
* ```js
* const braces = require('braces');
* console.log(braces.expand('a/{b,c}/d'));
* //=> ['a/b/d', 'a/c/d'];
* ```
* @param {String} `pattern` Brace pattern
* @param {Object} `options`
* @return {Array} Returns an array of expanded values.
* @api public
*/
braces$1.expand = (input, options = {}) => {
if (typeof input === 'string') {
input = braces$1.parse(input, options);
}
let result = expand(input, options);
// filter out empty strings if specified
if (options.noempty === true) {
result = result.filter(Boolean);
}
// filter out duplicates if specified
if (options.nodupes === true) {
result = [...new Set(result)];
}
return result;
};
/**
* Processes a brace pattern and returns either an expanded array
* (if `options.expand` is true), a highly optimized regex-compatible string.
* This method is called by the main [braces](#braces) function.
*
* ```js
* const braces = require('braces');
* console.log(braces.create('user-{200..300}/project-{a,b,c}-{1..10}'))
* //=> 'user-(20[0-9]|2[1-9][0-9]|300)/project-(a|b|c)-([1-9]|10)'
* ```
* @param {String} `pattern` Brace pattern
* @param {Object} `options`
* @return {Array} Returns an array of expanded values.
* @api public
*/
braces$1.create = (input, options = {}) => {
if (input === '' || input.length < 3) {
return [input];
}
return options.expand !== true
? braces$1.compile(input, options)
: braces$1.expand(input, options);
};
/**
* Expose "braces"
*/
var braces_1 = braces$1;
var utils$4 = {};
const path$1 = p;
const WIN_SLASH = '\\\\/';
const WIN_NO_SLASH = `[^${WIN_SLASH}]`;
/**
* Posix glob regex
*/
const DOT_LITERAL = '\\.';
const PLUS_LITERAL = '\\+';
const QMARK_LITERAL = '\\?';
const SLASH_LITERAL = '\\/';
const ONE_CHAR = '(?=.)';
const QMARK = '[^/]';
const END_ANCHOR = `(?:${SLASH_LITERAL}|$)`;
const START_ANCHOR = `(?:^|${SLASH_LITERAL})`;
const DOTS_SLASH = `${DOT_LITERAL}{1,2}${END_ANCHOR}`;
const NO_DOT = `(?!${DOT_LITERAL})`;
const NO_DOTS = `(?!${START_ANCHOR}${DOTS_SLASH})`;
const NO_DOT_SLASH = `(?!${DOT_LITERAL}{0,1}${END_ANCHOR})`;
const NO_DOTS_SLASH = `(?!${DOTS_SLASH})`;
const QMARK_NO_DOT = `[^.${SLASH_LITERAL}]`;
const STAR = `${QMARK}*?`;
const POSIX_CHARS = {
DOT_LITERAL,
PLUS_LITERAL,
QMARK_LITERAL,
SLASH_LITERAL,
ONE_CHAR,
QMARK,
END_ANCHOR,
DOTS_SLASH,
NO_DOT,
NO_DOTS,
NO_DOT_SLASH,
NO_DOTS_SLASH,
QMARK_NO_DOT,
STAR,
START_ANCHOR
};
/**
* Windows glob regex
*/
const WINDOWS_CHARS = {
...POSIX_CHARS,
SLASH_LITERAL: `[${WIN_SLASH}]`,
QMARK: WIN_NO_SLASH,
STAR: `${WIN_NO_SLASH}*?`,
DOTS_SLASH: `${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$)`,
NO_DOT: `(?!${DOT_LITERAL})`,
NO_DOTS: `(?!(?:^|[${WIN_SLASH}])${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`,
NO_DOT_SLASH: `(?!${DOT_LITERAL}{0,1}(?:[${WIN_SLASH}]|$))`,
NO_DOTS_SLASH: `(?!${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`,
QMARK_NO_DOT: `[^.${WIN_SLASH}]`,
START_ANCHOR: `(?:^|[${WIN_SLASH}])`,
END_ANCHOR: `(?:[${WIN_SLASH}]|$)`
};
/**
* POSIX Bracket Regex
*/
const POSIX_REGEX_SOURCE$1 = {
alnum: 'a-zA-Z0-9',
alpha: 'a-zA-Z',
ascii: '\\x00-\\x7F',
blank: ' \\t',
cntrl: '\\x00-\\x1F\\x7F',
digit: '0-9',
graph: '\\x21-\\x7E',
lower: 'a-z',
print: '\\x20-\\x7E ',
punct: '\\-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~',
space: ' \\t\\r\\n\\v\\f',
upper: 'A-Z',
word: 'A-Za-z0-9_',
xdigit: 'A-Fa-f0-9'
};
var constants$2 = {
MAX_LENGTH: 1024 * 64,
POSIX_REGEX_SOURCE: POSIX_REGEX_SOURCE$1,
// regular expressions
REGEX_BACKSLASH: /\\(?![*+?^${}(|)[\]])/g,
REGEX_NON_SPECIAL_CHARS: /^[^@![\].,$*+?^{}()|\\/]+/,
REGEX_SPECIAL_CHARS: /[-*+?.^${}(|)[\]]/,
REGEX_SPECIAL_CHARS_BACKREF: /(\\?)((\W)(\3*))/g,
REGEX_SPECIAL_CHARS_GLOBAL: /([-*+?.^${}(|)[\]])/g,
REGEX_REMOVE_BACKSLASH: /(?:\[.*?[^\\]\]|\\(?=.))/g,
// Replace globs with equivalent patterns to reduce parsing time.
REPLACEMENTS: {
'***': '*',
'**/**': '**',
'**/**/**': '**'
},
// Digits
CHAR_0: 48, /* 0 */
CHAR_9: 57, /* 9 */
// Alphabet chars.
CHAR_UPPERCASE_A: 65, /* A */
CHAR_LOWERCASE_A: 97, /* a */
CHAR_UPPERCASE_Z: 90, /* Z */
CHAR_LOWERCASE_Z: 122, /* z */
CHAR_LEFT_PARENTHESES: 40, /* ( */
CHAR_RIGHT_PARENTHESES: 41, /* ) */
CHAR_ASTERISK: 42, /* * */
// Non-alphabetic chars.
CHAR_AMPERSAND: 38, /* & */
CHAR_AT: 64, /* @ */
CHAR_BACKWARD_SLASH: 92, /* \ */
CHAR_CARRIAGE_RETURN: 13, /* \r */
CHAR_CIRCUMFLEX_ACCENT: 94, /* ^ */
CHAR_COLON: 58, /* : */
CHAR_COMMA: 44, /* , */
CHAR_DOT: 46, /* . */
CHAR_DOUBLE_QUOTE: 34, /* " */
CHAR_EQUAL: 61, /* = */
CHAR_EXCLAMATION_MARK: 33, /* ! */
CHAR_FORM_FEED: 12, /* \f */
CHAR_FORWARD_SLASH: 47, /* / */
CHAR_GRAVE_ACCENT: 96, /* ` */
CHAR_HASH: 35, /* # */
CHAR_HYPHEN_MINUS: 45, /* - */
CHAR_LEFT_ANGLE_BRACKET: 60, /* < */
CHAR_LEFT_CURLY_BRACE: 123, /* { */
CHAR_LEFT_SQUARE_BRACKET: 91, /* [ */
CHAR_LINE_FEED: 10, /* \n */
CHAR_NO_BREAK_SPACE: 160, /* \u00A0 */
CHAR_PERCENT: 37, /* % */
CHAR_PLUS: 43, /* + */
CHAR_QUESTION_MARK: 63, /* ? */
CHAR_RIGHT_ANGLE_BRACKET: 62, /* > */
CHAR_RIGHT_CURLY_BRACE: 125, /* } */
CHAR_RIGHT_SQUARE_BRACKET: 93, /* ] */
CHAR_SEMICOLON: 59, /* ; */
CHAR_SINGLE_QUOTE: 39, /* ' */
CHAR_SPACE: 32, /* */
CHAR_TAB: 9, /* \t */
CHAR_UNDERSCORE: 95, /* _ */
CHAR_VERTICAL_LINE: 124, /* | */
CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279, /* \uFEFF */
SEP: path$1.sep,
/**
* Create EXTGLOB_CHARS
*/
extglobChars(chars) {
return {
'!': { type: 'negate', open: '(?:(?!(?:', close: `))${chars.STAR})` },
'?': { type: 'qmark', open: '(?:', close: ')?' },
'+': { type: 'plus', open: '(?:', close: ')+' },
'*': { type: 'star', open: '(?:', close: ')*' },
'@': { type: 'at', open: '(?:', close: ')' }
};
},
/**
* Create GLOB_CHARS
*/
globChars(win32) {
return win32 === true ? WINDOWS_CHARS : POSIX_CHARS;
}
};
(function (exports) {
const path = p;
const win32 = process.platform === 'win32';
const {
REGEX_BACKSLASH,
REGEX_REMOVE_BACKSLASH,
REGEX_SPECIAL_CHARS,
REGEX_SPECIAL_CHARS_GLOBAL
} = constants$2;
exports.isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val);
exports.hasRegexChars = str => REGEX_SPECIAL_CHARS.test(str);
exports.isRegexChar = str => str.length === 1 && exports.hasRegexChars(str);
exports.escapeRegex = str => str.replace(REGEX_SPECIAL_CHARS_GLOBAL, '\\$1');
exports.toPosixSlashes = str => str.replace(REGEX_BACKSLASH, '/');
exports.removeBackslashes = str => {
return str.replace(REGEX_REMOVE_BACKSLASH, match => {
return match === '\\' ? '' : match;
});
};
exports.supportsLookbehinds = () => {
const segs = process.version.slice(1).split('.').map(Number);
if (segs.length === 3 && segs[0] >= 9 || (segs[0] === 8 && segs[1] >= 10)) {
return true;
}
return false;
};
exports.isWindows = options => {
if (options && typeof options.windows === 'boolean') {
return options.windows;
}
return win32 === true || path.sep === '\\';
};
exports.escapeLast = (input, char, lastIdx) => {
const idx = input.lastIndexOf(char, lastIdx);
if (idx === -1) return input;
if (input[idx - 1] === '\\') return exports.escapeLast(input, char, idx - 1);
return `${input.slice(0, idx)}\\${input.slice(idx)}`;
};
exports.removePrefix = (input, state = {}) => {
let output = input;
if (output.startsWith('./')) {
output = output.slice(2);
state.prefix = './';
}
return output;
};
exports.wrapOutput = (input, state = {}, options = {}) => {
const prepend = options.contains ? '' : '^';
const append = options.contains ? '' : '$';
let output = `${prepend}(?:${input})${append}`;
if (state.negated === true) {
output = `(?:^(?!${output}).*$)`;
}
return output;
};
} (utils$4));
const utils$3 = utils$4;
const {
CHAR_ASTERISK, /* * */
CHAR_AT, /* @ */
CHAR_BACKWARD_SLASH, /* \ */
CHAR_COMMA, /* , */
CHAR_DOT, /* . */
CHAR_EXCLAMATION_MARK, /* ! */
CHAR_FORWARD_SLASH, /* / */
CHAR_LEFT_CURLY_BRACE, /* { */
CHAR_LEFT_PARENTHESES, /* ( */
CHAR_LEFT_SQUARE_BRACKET, /* [ */
CHAR_PLUS, /* + */
CHAR_QUESTION_MARK, /* ? */
CHAR_RIGHT_CURLY_BRACE, /* } */
CHAR_RIGHT_PARENTHESES, /* ) */
CHAR_RIGHT_SQUARE_BRACKET /* ] */
} = constants$2;
const isPathSeparator = code => {
return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH;
};
const depth = token => {
if (token.isPrefix !== true) {
token.depth = token.isGlobstar ? Infinity : 1;
}
};
/**
* Quickly scans a glob pattern and returns an object with a handful of
* useful properties, like `isGlob`, `path` (the leading non-glob, if it exists),
* `glob` (the actual pattern), `negated` (true if the path starts with `!` but not
* with `!(`) and `negatedExtglob` (true if the path starts with `!(`).
*
* ```js
* const pm = require('picomatch');
* console.log(pm.scan('foo/bar/*.js'));
* { isGlob: true, input: 'foo/bar/*.js', base: 'foo/bar', glob: '*.js' }
* ```
* @param {String} `str`
* @param {Object} `options`
* @return {Object} Returns an object with tokens and regex source string.
* @api public
*/
const scan$1 = (input, options) => {
const opts = options || {};
const length = input.length - 1;
const scanToEnd = opts.parts === true || opts.scanToEnd === true;
const slashes = [];
const tokens = [];
const parts = [];
let str = input;
let index = -1;
let start = 0;
let lastIndex = 0;
let isBrace = false;
let isBracket = false;
let isGlob = false;
let isExtglob = false;
let isGlobstar = false;
let braceEscaped = false;
let backslashes = false;
let negated = false;
let negatedExtglob = false;
let finished = false;
let braces = 0;
let prev;
let code;
let token = { value: '', depth: 0, isGlob: false };
const eos = () => index >= length;
const peek = () => str.charCodeAt(index + 1);
const advance = () => {
prev = code;
return str.charCodeAt(++index);
};
while (index < length) {
code = advance();
let next;
if (code === CHAR_BACKWARD_SLASH) {
backslashes = token.backslashes = true;
code = advance();
if (code === CHAR_LEFT_CURLY_BRACE) {
braceEscaped = true;
}
continue;
}
if (braceEscaped === true || code === CHAR_LEFT_CURLY_BRACE) {
braces++;
while (eos() !== true && (code = advance())) {
if (code === CHAR_BACKWARD_SLASH) {
backslashes = token.backslashes = true;
advance();
continue;
}
if (code === CHAR_LEFT_CURLY_BRACE) {
braces++;
continue;
}
if (braceEscaped !== true && code === CHAR_DOT && (code = advance()) === CHAR_DOT) {
isBrace = token.isBrace = true;
isGlob = token.isGlob = true;
finished = true;
if (scanToEnd === true) {
continue;
}
break;
}
if (braceEscaped !== true && code === CHAR_COMMA) {
isBrace = token.isBrace = true;
isGlob = token.isGlob = true;
finished = true;
if (scanToEnd === true) {
continue;
}
break;
}
if (code === CHAR_RIGHT_CURLY_BRACE) {
braces--;
if (braces === 0) {
braceEscaped = false;
isBrace = token.isBrace = true;
finished = true;
break;
}
}
}
if (scanToEnd === true) {
continue;
}
break;
}
if (code === CHAR_FORWARD_SLASH) {
slashes.push(index);
tokens.push(token);
token = { value: '', depth: 0, isGlob: false };
if (finished === true) continue;
if (prev === CHAR_DOT && index === (start + 1)) {
start += 2;
continue;
}
lastIndex = index + 1;
continue;
}
if (opts.noext !== true) {
const isExtglobChar = code === CHAR_PLUS
|| code === CHAR_AT
|| code === CHAR_ASTERISK
|| code === CHAR_QUESTION_MARK
|| code === CHAR_EXCLAMATION_MARK;
if (isExtglobChar === true && peek() === CHAR_LEFT_PARENTHESES) {
isGlob = token.isGlob = true;
isExtglob = token.isExtglob = true;
finished = true;
if (code === CHAR_EXCLAMATION_MARK && index === start) {
negatedExtglob = true;
}
if (scanToEnd === true) {
while (eos() !== true && (code = advance())) {
if (code === CHAR_BACKWARD_SLASH) {
backslashes = token.backslashes = true;
code = advance();
continue;
}
if (code === CHAR_RIGHT_PARENTHESES) {
isGlob = token.isGlob = true;
finished = true;
break;
}
}
continue;
}
break;
}
}
if (code === CHAR_ASTERISK) {
if (prev === CHAR_ASTERISK) isGlobstar = token.isGlobstar = true;
isGlob = token.isGlob = true;
finished = true;
if (scanToEnd === true) {
continue;
}
break;
}
if (code === CHAR_QUESTION_MARK) {
isGlob = token.isGlob = true;
finished = true;
if (scanToEnd === true) {
continue;
}
break;
}
if (code === CHAR_LEFT_SQUARE_BRACKET) {
while (eos() !== true && (next = advance())) {
if (next === CHAR_BACKWARD_SLASH) {
backslashes = token.backslashes = true;
advance();
continue;
}
if (next === CHAR_RIGHT_SQUARE_BRACKET) {
isBracket = token.isBracket = true;
isGlob = token.isGlob = true;
finished = true;
break;
}
}
if (scanToEnd === true) {
continue;
}
break;
}
if (opts.nonegate !== true && code === CHAR_EXCLAMATION_MARK && index === start) {
negated = token.negated = true;
start++;
continue;
}
if (opts.noparen !== true && code === CHAR_LEFT_PARENTHESES) {
isGlob = token.isGlob = true;
if (scanToEnd === true) {
while (eos() !== true && (code = advance())) {
if (code === CHAR_LEFT_PARENTHESES) {
backslashes = token.backslashes = true;
code = advance();
continue;
}
if (code === CHAR_RIGHT_PARENTHESES) {
finished = true;
break;
}
}
continue;
}
break;
}
if (isGlob === true) {
finished = true;
if (scanToEnd === true) {
continue;
}
break;
}
}
if (opts.noext === true) {
isExtglob = false;
isGlob = false;
}
let base = str;
let prefix = '';
let glob = '';
if (start > 0) {
prefix = str.slice(0, start);
str = str.slice(start);
lastIndex -= start;
}
if (base && isGlob === true && lastIndex > 0) {
base = str.slice(0, lastIndex);
glob = str.slice(lastIndex);
} else if (isGlob === true) {
base = '';
glob = str;
} else {
base = str;
}
if (base && base !== '' && base !== '/' && base !== str) {
if (isPathSeparator(base.charCodeAt(base.length - 1))) {
base = base.slice(0, -1);
}
}
if (opts.unescape === true) {
if (glob) glob = utils$3.removeBackslashes(glob);
if (base && backslashes === true) {
base = utils$3.removeBackslashes(base);
}
}
const state = {
prefix,
input,
start,
base,
glob,
isBrace,
isBracket,
isGlob,
isExtglob,
isGlobstar,
negated,
negatedExtglob
};
if (opts.tokens === true) {
state.maxDepth = 0;
if (!isPathSeparator(code)) {
tokens.push(token);
}
state.tokens = tokens;
}
if (opts.parts === true || opts.tokens === true) {
let prevIndex;
for (let idx = 0; idx < slashes.length; idx++) {
const n = prevIndex ? prevIndex + 1 : start;
const i = slashes[idx];
const value = input.slice(n, i);
if (opts.tokens) {
if (idx === 0 && start !== 0) {
tokens[idx].isPrefix = true;
tokens[idx].value = prefix;
} else {
tokens[idx].value = value;
}
depth(tokens[idx]);
state.maxDepth += tokens[idx].depth;
}
if (idx !== 0 || value !== '') {
parts.push(value);
}
prevIndex = i;
}
if (prevIndex && prevIndex + 1 < input.length) {
const value = input.slice(prevIndex + 1);
parts.push(value);
if (opts.tokens) {
tokens[tokens.length - 1].value = value;
depth(tokens[tokens.length - 1]);
state.maxDepth += tokens[tokens.length - 1].depth;
}
}
state.slashes = slashes;
state.parts = parts;
}
return state;
};
var scan_1 = scan$1;
const constants$1 = constants$2;
const utils$2 = utils$4;
/**
* Constants
*/
const {
MAX_LENGTH,
POSIX_REGEX_SOURCE,
REGEX_NON_SPECIAL_CHARS,
REGEX_SPECIAL_CHARS_BACKREF,
REPLACEMENTS
} = constants$1;
/**
* Helpers
*/
const expandRange = (args, options) => {
if (typeof options.expandRange === 'function') {
return options.expandRange(...args, options);
}
args.sort();
const value = `[${args.join('-')}]`;
try {
/* eslint-disable-next-line no-new */
new RegExp(value);
} catch (ex) {
return args.map(v => utils$2.escapeRegex(v)).join('..');
}
return value;
};
/**
* Create the message for a syntax error
*/
const syntaxError = (type, char) => {
return `Missing ${type}: "${char}" - use "\\\\${char}" to match literal characters`;
};
/**
* Parse the given input string.
* @param {String} input
* @param {Object} options
* @return {Object}
*/
const parse$1 = (input, options) => {
if (typeof input !== 'string') {
throw new TypeError('Expected a string');
}
input = REPLACEMENTS[input] || input;
const opts = { ...options };
const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH;
let len = input.length;
if (len > max) {
throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`);
}
const bos = { type: 'bos', value: '', output: opts.prepend || '' };
const tokens = [bos];
const capture = opts.capture ? '' : '?:';
const win32 = utils$2.isWindows(options);
// create constants based on platform, for windows or posix
const PLATFORM_CHARS = constants$1.globChars(win32);
const EXTGLOB_CHARS = constants$1.extglobChars(PLATFORM_CHARS);
const {
DOT_LITERAL,
PLUS_LITERAL,
SLASH_LITERAL,
ONE_CHAR,
DOTS_SLASH,
NO_DOT,
NO_DOT_SLASH,
NO_DOTS_SLASH,
QMARK,
QMARK_NO_DOT,
STAR,
START_ANCHOR
} = PLATFORM_CHARS;
const globstar = opts => {
return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`;
};
const nodot = opts.dot ? '' : NO_DOT;
const qmarkNoDot = opts.dot ? QMARK : QMARK_NO_DOT;
let star = opts.bash === true ? globstar(opts) : STAR;
if (opts.capture) {
star = `(${star})`;
}
// minimatch options support
if (typeof opts.noext === 'boolean') {
opts.noextglob = opts.noext;
}
const state = {
input,
index: -1,
start: 0,
dot: opts.dot === true,
consumed: '',
output: '',
prefix: '',
backtrack: false,
negated: false,
brackets: 0,
braces: 0,
parens: 0,
quotes: 0,
globstar: false,
tokens
};
input = utils$2.removePrefix(input, state);
len = input.length;
const extglobs = [];
const braces = [];
const stack = [];
let prev = bos;
let value;
/**
* Tokenizing helpers
*/
const eos = () => state.index === len - 1;
const peek = state.peek = (n = 1) => input[state.index + n];
const advance = state.advance = () => input[++state.index] || '';
const remaining = () => input.slice(state.index + 1);
const consume = (value = '', num = 0) => {
state.consumed += value;
state.index += num;
};
const append = token => {
state.output += token.output != null ? token.output : token.value;
consume(token.value);
};
const negate = () => {
let count = 1;
while (peek() === '!' && (peek(2) !== '(' || peek(3) === '?')) {
advance();
state.start++;
count++;
}
if (count % 2 === 0) {
return false;
}
state.negated = true;
state.start++;
return true;
};
const increment = type => {
state[type]++;
stack.push(type);
};
const decrement = type => {
state[type]--;
stack.pop();
};
/**
* Push tokens onto the tokens array. This helper speeds up
* tokenizing by 1) helping us avoid backtracking as much as possible,
* and 2) helping us avoid creating extra tokens when consecutive
* characters are plain text. This improves performance and simplifies
* lookbehinds.
*/
const push = tok => {
if (prev.type === 'globstar') {
const isBrace = state.braces > 0 && (tok.type === 'comma' || tok.type === 'brace');
const isExtglob = tok.extglob === true || (extglobs.length && (tok.type === 'pipe' || tok.type === 'paren'));
if (tok.type !== 'slash' && tok.type !== 'paren' && !isBrace && !isExtglob) {
state.output = state.output.slice(0, -prev.output.length);
prev.type = 'star';
prev.value = '*';
prev.output = star;
state.output += prev.output;
}
}
if (extglobs.length && tok.type !== 'paren') {
extglobs[extglobs.length - 1].inner += tok.value;
}
if (tok.value || tok.output) append(tok);
if (prev && prev.type === 'text' && tok.type === 'text') {
prev.value += tok.value;
prev.output = (prev.output || '') + tok.value;
return;
}
tok.prev = prev;
tokens.push(tok);
prev = tok;
};
const extglobOpen = (type, value) => {
const token = { ...EXTGLOB_CHARS[value], conditions: 1, inner: '' };
token.prev = prev;
token.parens = state.parens;
token.output = state.output;
const output = (opts.capture ? '(' : '') + token.open;
increment('parens');
push({ type, value, output: state.output ? '' : ONE_CHAR });
push({ type: 'paren', extglob: true, value: advance(), output });
extglobs.push(token);
};
const extglobClose = token => {
let output = token.close + (opts.capture ? ')' : '');
let rest;
if (token.type === 'negate') {
let extglobStar = star;
if (token.inner && token.inner.length > 1 && token.inner.includes('/')) {
extglobStar = globstar(opts);
}
if (extglobStar !== star || eos() || /^\)+$/.test(remaining())) {
output = token.close = `)$))${extglobStar}`;
}
if (token.inner.includes('*') && (rest = remaining()) && /^\.[^\\/.]+$/.test(rest)) {
// Any non-magical string (`.ts`) or even nested expression (`.{ts,tsx}`) can follow after the closing parenthesis.
// In this case, we need to parse the string and use it in the output of the original pattern.
// Suitable patterns: `/!(*.d).ts`, `/!(*.d).{ts,tsx}`, `**/!(*-dbg).@(js)`.
//
// Disabling the `fastpaths` option due to a problem with parsing strings as `.ts` in the pattern like `**/!(*.d).ts`.
const expression = parse$1(rest, { ...options, fastpaths: false }).output;
output = token.close = `)${expression})${extglobStar})`;
}
if (token.prev.type === 'bos') {
state.negatedExtglob = true;
}
}
push({ type: 'paren', extglob: true, value, output });
decrement('parens');
};
/**
* Fast paths
*/
if (opts.fastpaths !== false && !/(^[*!]|[/()[\]{}"])/.test(input)) {
let backslashes = false;
let output = input.replace(REGEX_SPECIAL_CHARS_BACKREF, (m, esc, chars, first, rest, index) => {
if (first === '\\') {
backslashes = true;
return m;
}
if (first === '?') {
if (esc) {
return esc + first + (rest ? QMARK.repeat(rest.length) : '');
}
if (index === 0) {
return qmarkNoDot + (rest ? QMARK.repeat(rest.length) : '');
}
return QMARK.repeat(chars.length);
}
if (first === '.') {
return DOT_LITERAL.repeat(chars.length);
}
if (first === '*') {
if (esc) {
return esc + first + (rest ? star : '');
}
return star;
}
return esc ? m : `\\${m}`;
});
if (backslashes === true) {
if (opts.unescape === true) {
output = output.replace(/\\/g, '');
} else {
output = output.replace(/\\+/g, m => {
return m.length % 2 === 0 ? '\\\\' : (m ? '\\' : '');
});
}
}
if (output === input && opts.contains === true) {
state.output = input;
return state;
}
state.output = utils$2.wrapOutput(output, state, options);
return state;
}
/**
* Tokenize input until we reach end-of-string
*/
while (!eos()) {
value = advance();
if (value === '\u0000') {
continue;
}
/**
* Escaped characters
*/
if (value === '\\') {
const next = peek();
if (next === '/' && opts.bash !== true) {
continue;
}
if (next === '.' || next === ';') {
continue;
}
if (!next) {
value += '\\';
push({ type: 'text', value });
continue;
}
// collapse slashes to reduce potential for exploits
const match = /^\\+/.exec(remaining());
let slashes = 0;
if (match && match[0].length > 2) {
slashes = match[0].length;
state.index += slashes;
if (slashes % 2 !== 0) {
value += '\\';
}
}
if (opts.unescape === true) {
value = advance();
} else {
value += advance();
}
if (state.brackets === 0) {
push({ type: 'text', value });
continue;
}
}
/**
* If we're inside a regex character class, continue
* until we reach the closing bracket.
*/
if (state.brackets > 0 && (value !== ']' || prev.value === '[' || prev.value === '[^')) {
if (opts.posix !== false && value === ':') {
const inner = prev.value.slice(1);
if (inner.includes('[')) {
prev.posix = true;
if (inner.includes(':')) {
const idx = prev.value.lastIndexOf('[');
const pre = prev.value.slice(0, idx);
const rest = prev.value.slice(idx + 2);
const posix = POSIX_REGEX_SOURCE[rest];
if (posix) {
prev.value = pre + posix;
state.backtrack = true;
advance();
if (!bos.output && tokens.indexOf(prev) === 1) {
bos.output = ONE_CHAR;
}
continue;
}
}
}
}
if ((value === '[' && peek() !== ':') || (value === '-' && peek() === ']')) {
value = `\\${value}`;
}
if (value === ']' && (prev.value === '[' || prev.value === '[^')) {
value = `\\${value}`;
}
if (opts.posix === true && value === '!' && prev.value === '[') {
value = '^';
}
prev.value += value;
append({ value });
continue;
}
/**
* If we're inside a quoted string, continue
* until we reach the closing double quote.
*/
if (state.quotes === 1 && value !== '"') {
value = utils$2.escapeRegex(value);
prev.value += value;
append({ value });
continue;
}
/**
* Double quotes
*/
if (value === '"') {
state.quotes = state.quotes === 1 ? 0 : 1;
if (opts.keepQuotes === true) {
push({ type: 'text', value });
}
continue;
}
/**
* Parentheses
*/
if (value === '(') {
increment('parens');
push({ type: 'paren', value });
continue;
}
if (value === ')') {
if (state.parens === 0 && opts.strictBrackets === true) {
throw new SyntaxError(syntaxError('opening', '('));
}
const extglob = extglobs[extglobs.length - 1];
if (extglob && state.parens === extglob.parens + 1) {
extglobClose(extglobs.pop());
continue;
}
push({ type: 'paren', value, output: state.parens ? ')' : '\\)' });
decrement('parens');
continue;
}
/**
* Square brackets
*/
if (value === '[') {
if (opts.nobracket === true || !remaining().includes(']')) {
if (opts.nobracket !== true && opts.strictBrackets === true) {
throw new SyntaxError(syntaxError('closing', ']'));
}
value = `\\${value}`;
} else {
increment('brackets');
}
push({ type: 'bracket', value });
continue;
}
if (value === ']') {
if (opts.nobracket === true || (prev && prev.type === 'bracket' && prev.value.length === 1)) {
push({ type: 'text', value, output: `\\${value}` });
continue;
}
if (state.brackets === 0) {
if (opts.strictBrackets === true) {
throw new SyntaxError(syntaxError('opening', '['));
}
push({ type: 'text', value, output: `\\${value}` });
continue;
}
decrement('brackets');
const prevValue = prev.value.slice(1);
if (prev.posix !== true && prevValue[0] === '^' && !prevValue.includes('/')) {
value = `/${value}`;
}
prev.value += value;
append({ value });
// when literal brackets are explicitly disabled
// assume we should match with a regex character class
if (opts.literalBrackets === false || utils$2.hasRegexChars(prevValue)) {
continue;
}
const escaped = utils$2.escapeRegex(prev.value);
state.output = state.output.slice(0, -prev.value.length);
// when literal brackets are explicitly enabled
// assume we should escape the brackets to match literal characters
if (opts.literalBrackets === true) {
state.output += escaped;
prev.value = escaped;
continue;
}
// when the user specifies nothing, try to match both
prev.value = `(${capture}${escaped}|${prev.value})`;
state.output += prev.value;
continue;
}
/**
* Braces
*/
if (value === '{' && opts.nobrace !== true) {
increment('braces');
const open = {
type: 'brace',
value,
output: '(',
outputIndex: state.output.length,
tokensIndex: state.tokens.length
};
braces.push(open);
push(open);
continue;
}
if (value === '}') {
const brace = braces[braces.length - 1];
if (opts.nobrace === true || !brace) {
push({ type: 'text', value, output: value });
continue;
}
let output = ')';
if (brace.dots === true) {
const arr = tokens.slice();
const range = [];
for (let i = arr.length - 1; i >= 0; i--) {
tokens.pop();
if (arr[i].type === 'brace') {
break;
}
if (arr[i].type !== 'dots') {
range.unshift(arr[i].value);
}
}
output = expandRange(range, opts);
state.backtrack = true;
}
if (brace.comma !== true && brace.dots !== true) {
const out = state.output.slice(0, brace.outputIndex);
const toks = state.tokens.slice(brace.tokensIndex);
brace.value = brace.output = '\\{';
value = output = '\\}';
state.output = out;
for (const t of toks) {
state.output += (t.output || t.value);
}
}
push({ type: 'brace', value, output });
decrement('braces');
braces.pop();
continue;
}
/**
* Pipes
*/
if (value === '|') {
if (extglobs.length > 0) {
extglobs[extglobs.length - 1].conditions++;
}
push({ type: 'text', value });
continue;
}
/**
* Commas
*/
if (value === ',') {
let output = value;
const brace = braces[braces.length - 1];
if (brace && stack[stack.length - 1] === 'braces') {
brace.comma = true;
output = '|';
}
push({ type: 'comma', value, output });
continue;
}
/**
* Slashes
*/
if (value === '/') {
// if the beginning of the glob is "./", advance the start
// to the current index, and don't add the "./" characters
// to the state. This greatly simplifies lookbehinds when
// checking for BOS characters like "!" and "." (not "./")
if (prev.type === 'dot' && state.index === state.start + 1) {
state.start = state.index + 1;
state.consumed = '';
state.output = '';
tokens.pop();
prev = bos; // reset "prev" to the first token
continue;
}
push({ type: 'slash', value, output: SLASH_LITERAL });
continue;
}
/**
* Dots
*/
if (value === '.') {
if (state.braces > 0 && prev.type === 'dot') {
if (prev.value === '.') prev.output = DOT_LITERAL;
const brace = braces[braces.length - 1];
prev.type = 'dots';
prev.output += value;
prev.value += value;
brace.dots = true;
continue;
}
if ((state.braces + state.parens) === 0 && prev.type !== 'bos' && prev.type !== 'slash') {
push({ type: 'text', value, output: DOT_LITERAL });
continue;
}
push({ type: 'dot', value, output: DOT_LITERAL });
continue;
}
/**
* Question marks
*/
if (value === '?') {
const isGroup = prev && prev.value === '(';
if (!isGroup && opts.noextglob !== true && peek() === '(' && peek(2) !== '?') {
extglobOpen('qmark', value);
continue;
}
if (prev && prev.type === 'paren') {
const next = peek();
let output = value;
if (next === '<' && !utils$2.supportsLookbehinds()) {
throw new Error('Node.js v10 or higher is required for regex lookbehinds');
}
if ((prev.value === '(' && !/[!=<:]/.test(next)) || (next === '<' && !/<([!=]|\w+>)/.test(remaining()))) {
output = `\\${value}`;
}
push({ type: 'text', value, output });
continue;
}
if (opts.dot !== true && (prev.type === 'slash' || prev.type === 'bos')) {
push({ type: 'qmark', value, output: QMARK_NO_DOT });
continue;
}
push({ type: 'qmark', value, output: QMARK });
continue;
}
/**
* Exclamation
*/
if (value === '!') {
if (opts.noextglob !== true && peek() === '(') {
if (peek(2) !== '?' || !/[!=<:]/.test(peek(3))) {
extglobOpen('negate', value);
continue;
}
}
if (opts.nonegate !== true && state.index === 0) {
negate();
continue;
}
}
/**
* Plus
*/
if (value === '+') {
if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') {
extglobOpen('plus', value);
continue;
}
if ((prev && prev.value === '(') || opts.regex === false) {
push({ type: 'plus', value, output: PLUS_LITERAL });
continue;
}
if ((prev && (prev.type === 'bracket' || prev.type === 'paren' || prev.type === 'brace')) || state.parens > 0) {
push({ type: 'plus', value });
continue;
}
push({ type: 'plus', value: PLUS_LITERAL });
continue;
}
/**
* Plain text
*/
if (value === '@') {
if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') {
push({ type: 'at', extglob: true, value, output: '' });
continue;
}
push({ type: 'text', value });
continue;
}
/**
* Plain text
*/
if (value !== '*') {
if (value === '$' || value === '^') {
value = `\\${value}`;
}
const match = REGEX_NON_SPECIAL_CHARS.exec(remaining());
if (match) {
value += match[0];
state.index += match[0].length;
}
push({ type: 'text', value });
continue;
}
/**
* Stars
*/
if (prev && (prev.type === 'globstar' || prev.star === true)) {
prev.type = 'star';
prev.star = true;
prev.value += value;
prev.output = star;
state.backtrack = true;
state.globstar = true;
consume(value);
continue;
}
let rest = remaining();
if (opts.noextglob !== true && /^\([^?]/.test(rest)) {
extglobOpen('star', value);
continue;
}
if (prev.type === 'star') {
if (opts.noglobstar === true) {
consume(value);
continue;
}
const prior = prev.prev;
const before = prior.prev;
const isStart = prior.type === 'slash' || prior.type === 'bos';
const afterStar = before && (before.type === 'star' || before.type === 'globstar');
if (opts.bash === true && (!isStart || (rest[0] && rest[0] !== '/'))) {
push({ type: 'star', value, output: '' });
continue;
}
const isBrace = state.braces > 0 && (prior.type === 'comma' || prior.type === 'brace');
const isExtglob = extglobs.length && (prior.type === 'pipe' || prior.type === 'paren');
if (!isStart && prior.type !== 'paren' && !isBrace && !isExtglob) {
push({ type: 'star', value, output: '' });
continue;
}
// strip consecutive `/**/`
while (rest.slice(0, 3) === '/**') {
const after = input[state.index + 4];
if (after && after !== '/') {
break;
}
rest = rest.slice(3);
consume('/**', 3);
}
if (prior.type === 'bos' && eos()) {
prev.type = 'globstar';
prev.value += value;
prev.output = globstar(opts);
state.output = prev.output;
state.globstar = true;
consume(value);
continue;
}
if (prior.type === 'slash' && prior.prev.type !== 'bos' && !afterStar && eos()) {
state.output = state.output.slice(0, -(prior.output + prev.output).length);
prior.output = `(?:${prior.output}`;
prev.type = 'globstar';
prev.output = globstar(opts) + (opts.strictSlashes ? ')' : '|$)');
prev.value += value;
state.globstar = true;
state.output += prior.output + prev.output;
consume(value);
continue;
}
if (prior.type === 'slash' && prior.prev.type !== 'bos' && rest[0] === '/') {
const end = rest[1] !== void 0 ? '|$' : '';
state.output = state.output.slice(0, -(prior.output + prev.output).length);
prior.output = `(?:${prior.output}`;
prev.type = 'globstar';
prev.output = `${globstar(opts)}${SLASH_LITERAL}|${SLASH_LITERAL}${end})`;
prev.value += value;
state.output += prior.output + prev.output;
state.globstar = true;
consume(value + advance());
push({ type: 'slash', value: '/', output: '' });
continue;
}
if (prior.type === 'bos' && rest[0] === '/') {
prev.type = 'globstar';
prev.value += value;
prev.output = `(?:^|${SLASH_LITERAL}|${globstar(opts)}${SLASH_LITERAL})`;
state.output = prev.output;
state.globstar = true;
consume(value + advance());
push({ type: 'slash', value: '/', output: '' });
continue;
}
// remove single star from output
state.output = state.output.slice(0, -prev.output.length);
// reset previous token to globstar
prev.type = 'globstar';
prev.output = globstar(opts);
prev.value += value;
// reset output with globstar
state.output += prev.output;
state.globstar = true;
consume(value);
continue;
}
const token = { type: 'star', value, output: star };
if (opts.bash === true) {
token.output = '.*?';
if (prev.type === 'bos' || prev.type === 'slash') {
token.output = nodot + token.output;
}
push(token);
continue;
}
if (prev && (prev.type === 'bracket' || prev.type === 'paren') && opts.regex === true) {
token.output = value;
push(token);
continue;
}
if (state.index === state.start || prev.type === 'slash' || prev.type === 'dot') {
if (prev.type === 'dot') {
state.output += NO_DOT_SLASH;
prev.output += NO_DOT_SLASH;
} else if (opts.dot === true) {
state.output += NO_DOTS_SLASH;
prev.output += NO_DOTS_SLASH;
} else {
state.output += nodot;
prev.output += nodot;
}
if (peek() !== '*') {
state.output += ONE_CHAR;
prev.output += ONE_CHAR;
}
}
push(token);
}
while (state.brackets > 0) {
if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ']'));
state.output = utils$2.escapeLast(state.output, '[');
decrement('brackets');
}
while (state.parens > 0) {
if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ')'));
state.output = utils$2.escapeLast(state.output, '(');
decrement('parens');
}
while (state.braces > 0) {
if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', '}'));
state.output = utils$2.escapeLast(state.output, '{');
decrement('braces');
}
if (opts.strictSlashes !== true && (prev.type === 'star' || prev.type === 'bracket')) {
push({ type: 'maybe_slash', value: '', output: `${SLASH_LITERAL}?` });
}
// rebuild the output if we had to backtrack at any point
if (state.backtrack === true) {
state.output = '';
for (const token of state.tokens) {
state.output += token.output != null ? token.output : token.value;
if (token.suffix) {
state.output += token.suffix;
}
}
}
return state;
};
/**
* Fast paths for creating regular expressions for common glob patterns.
* This can significantly speed up processing and has very little downside
* impact when none of the fast paths match.
*/
parse$1.fastpaths = (input, options) => {
const opts = { ...options };
const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH;
const len = input.length;
if (len > max) {
throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`);
}
input = REPLACEMENTS[input] || input;
const win32 = utils$2.isWindows(options);
// create constants based on platform, for windows or posix
const {
DOT_LITERAL,
SLASH_LITERAL,
ONE_CHAR,
DOTS_SLASH,
NO_DOT,
NO_DOTS,
NO_DOTS_SLASH,
STAR,
START_ANCHOR
} = constants$1.globChars(win32);
const nodot = opts.dot ? NO_DOTS : NO_DOT;
const slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT;
const capture = opts.capture ? '' : '?:';
const state = { negated: false, prefix: '' };
let star = opts.bash === true ? '.*?' : STAR;
if (opts.capture) {
star = `(${star})`;
}
const globstar = opts => {
if (opts.noglobstar === true) return star;
return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`;
};
const create = str => {
switch (str) {
case '*':
return `${nodot}${ONE_CHAR}${star}`;
case '.*':
return `${DOT_LITERAL}${ONE_CHAR}${star}`;
case '*.*':
return `${nodot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`;
case '*/*':
return `${nodot}${star}${SLASH_LITERAL}${ONE_CHAR}${slashDot}${star}`;
case '**':
return nodot + globstar(opts);
case '**/*':
return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${ONE_CHAR}${star}`;
case '**/*.*':
return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`;
case '**/.*':
return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${DOT_LITERAL}${ONE_CHAR}${star}`;
default: {
const match = /^(.*?)\.(\w+)$/.exec(str);
if (!match) return;
const source = create(match[1]);
if (!source) return;
return source + DOT_LITERAL + match[2];
}
}
};
const output = utils$2.removePrefix(input, state);
let source = create(output);
if (source && opts.strictSlashes !== true) {
source += `${SLASH_LITERAL}?`;
}
return source;
};
var parse_1 = parse$1;
const path = p;
const scan = scan_1;
const parse = parse_1;
const utils$1 = utils$4;
const constants = constants$2;
const isObject = val => val && typeof val === 'object' && !Array.isArray(val);
/**
* Creates a matcher function from one or more glob patterns. The
* returned function takes a string to match as its first argument,
* and returns true if the string is a match. The returned matcher
* function also takes a boolean as the second argument that, when true,
* returns an object with additional information.
*
* ```js
* const picomatch = require('picomatch');
* // picomatch(glob[, options]);
*
* const isMatch = picomatch('*.!(*a)');
* console.log(isMatch('a.a')); //=> false
* console.log(isMatch('a.b')); //=> true
* ```
* @name picomatch
* @param {String|Array} `globs` One or more glob patterns.
* @param {Object=} `options`
* @return {Function=} Returns a matcher function.
* @api public
*/
const picomatch$2 = (glob, options, returnState = false) => {
if (Array.isArray(glob)) {
const fns = glob.map(input => picomatch$2(input, options, returnState));
const arrayMatcher = str => {
for (const isMatch of fns) {
const state = isMatch(str);
if (state) return state;
}
return false;
};
return arrayMatcher;
}
const isState = isObject(glob) && glob.tokens && glob.input;
if (glob === '' || (typeof glob !== 'string' && !isState)) {
throw new TypeError('Expected pattern to be a non-empty string');
}
const opts = options || {};
const posix = utils$1.isWindows(options);
const regex = isState
? picomatch$2.compileRe(glob, options)
: picomatch$2.makeRe(glob, options, false, true);
const state = regex.state;
delete regex.state;
let isIgnored = () => false;
if (opts.ignore) {
const ignoreOpts = { ...options, ignore: null, onMatch: null, onResult: null };
isIgnored = picomatch$2(opts.ignore, ignoreOpts, returnState);
}
const matcher = (input, returnObject = false) => {
const { isMatch, match, output } = picomatch$2.test(input, regex, options, { glob, posix });
const result = { glob, state, regex, posix, input, output, match, isMatch };
if (typeof opts.onResult === 'function') {
opts.onResult(result);
}
if (isMatch === false) {
result.isMatch = false;
return returnObject ? result : false;
}
if (isIgnored(input)) {
if (typeof opts.onIgnore === 'function') {
opts.onIgnore(result);
}
result.isMatch = false;
return returnObject ? result : false;
}
if (typeof opts.onMatch === 'function') {
opts.onMatch(result);
}
return returnObject ? result : true;
};
if (returnState) {
matcher.state = state;
}
return matcher;
};
/**
* Test `input` with the given `regex`. This is used by the main
* `picomatch()` function to test the input string.
*
* ```js
* const picomatch = require('picomatch');
* // picomatch.test(input, regex[, options]);
*
* console.log(picomatch.test('foo/bar', /^(?:([^/]*?)\/([^/]*?))$/));
* // { isMatch: true, match: [ 'foo/', 'foo', 'bar' ], output: 'foo/bar' }
* ```
* @param {String} `input` String to test.
* @param {RegExp} `regex`
* @return {Object} Returns an object with matching info.
* @api public
*/
picomatch$2.test = (input, regex, options, { glob, posix } = {}) => {
if (typeof input !== 'string') {
throw new TypeError('Expected input to be a string');
}
if (input === '') {
return { isMatch: false, output: '' };
}
const opts = options || {};
const format = opts.format || (posix ? utils$1.toPosixSlashes : null);
let match = input === glob;
let output = (match && format) ? format(input) : input;
if (match === false) {
output = format ? format(input) : input;
match = output === glob;
}
if (match === false || opts.capture === true) {
if (opts.matchBase === true || opts.basename === true) {
match = picomatch$2.matchBase(input, regex, options, posix);
} else {
match = regex.exec(output);
}
}
return { isMatch: Boolean(match), match, output };
};
/**
* Match the basename of a filepath.
*
* ```js
* const picomatch = require('picomatch');
* // picomatch.matchBase(input, glob[, options]);
* console.log(picomatch.matchBase('foo/bar.js', '*.js'); // true
* ```
* @param {String} `input` String to test.
* @param {RegExp|String} `glob` Glob pattern or regex created by [.makeRe](#makeRe).
* @return {Boolean}
* @api public
*/
picomatch$2.matchBase = (input, glob, options, posix = utils$1.isWindows(options)) => {
const regex = glob instanceof RegExp ? glob : picomatch$2.makeRe(glob, options);
return regex.test(path.basename(input));
};
/**
* Returns true if **any** of the given glob `patterns` match the specified `string`.
*
* ```js
* const picomatch = require('picomatch');
* // picomatch.isMatch(string, patterns[, options]);
*
* console.log(picomatch.isMatch('a.a', ['b.*', '*.a'])); //=> true
* console.log(picomatch.isMatch('a.a', 'b.*')); //=> false
* ```
* @param {String|Array} str The string to test.
* @param {String|Array} patterns One or more glob patterns to use for matching.
* @param {Object} [options] See available [options](#options).
* @return {Boolean} Returns true if any patterns match `str`
* @api public
*/
picomatch$2.isMatch = (str, patterns, options) => picomatch$2(patterns, options)(str);
/**
* Parse a glob pattern to create the source string for a regular
* expression.
*
* ```js
* const picomatch = require('picomatch');
* const result = picomatch.parse(pattern[, options]);
* ```
* @param {String} `pattern`
* @param {Object} `options`
* @return {Object} Returns an object with useful properties and output to be used as a regex source string.
* @api public
*/
picomatch$2.parse = (pattern, options) => {
if (Array.isArray(pattern)) return pattern.map(p => picomatch$2.parse(p, options));
return parse(pattern, { ...options, fastpaths: false });
};
/**
* Scan a glob pattern to separate the pattern into segments.
*
* ```js
* const picomatch = require('picomatch');
* // picomatch.scan(input[, options]);
*
* const result = picomatch.scan('!./foo/*.js');
* console.log(result);
* { prefix: '!./',
* input: '!./foo/*.js',
* start: 3,
* base: 'foo',
* glob: '*.js',
* isBrace: false,
* isBracket: false,
* isGlob: true,
* isExtglob: false,
* isGlobstar: false,
* negated: true }
* ```
* @param {String} `input` Glob pattern to scan.
* @param {Object} `options`
* @return {Object} Returns an object with
* @api public
*/
picomatch$2.scan = (input, options) => scan(input, options);
/**
* Compile a regular expression from the `state` object returned by the
* [parse()](#parse) method.
*
* @param {Object} `state`
* @param {Object} `options`
* @param {Boolean} `returnOutput` Intended for implementors, this argument allows you to return the raw output from the parser.
* @param {Boolean} `returnState` Adds the state to a `state` property on the returned regex. Useful for implementors and debugging.
* @return {RegExp}
* @api public
*/
picomatch$2.compileRe = (state, options, returnOutput = false, returnState = false) => {
if (returnOutput === true) {
return state.output;
}
const opts = options || {};
const prepend = opts.contains ? '' : '^';
const append = opts.contains ? '' : '$';
let source = `${prepend}(?:${state.output})${append}`;
if (state && state.negated === true) {
source = `^(?!${source}).*$`;
}
const regex = picomatch$2.toRegex(source, options);
if (returnState === true) {
regex.state = state;
}
return regex;
};
/**
* Create a regular expression from a parsed glob pattern.
*
* ```js
* const picomatch = require('picomatch');
* const state = picomatch.parse('*.js');
* // picomatch.compileRe(state[, options]);
*
* console.log(picomatch.compileRe(state));
* //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/
* ```
* @param {String} `state` The object returned from the `.parse` method.
* @param {Object} `options`
* @param {Boolean} `returnOutput` Implementors may use this argument to return the compiled output, instead of a regular expression. This is not exposed on the options to prevent end-users from mutating the result.
* @param {Boolean} `returnState` Implementors may use this argument to return the state from the parsed glob with the returned regular expression.
* @return {RegExp} Returns a regex created from the given pattern.
* @api public
*/
picomatch$2.makeRe = (input, options = {}, returnOutput = false, returnState = false) => {
if (!input || typeof input !== 'string') {
throw new TypeError('Expected a non-empty string');
}
let parsed = { negated: false, fastpaths: true };
if (options.fastpaths !== false && (input[0] === '.' || input[0] === '*')) {
parsed.output = parse.fastpaths(input, options);
}
if (!parsed.output) {
parsed = parse(input, options);
}
return picomatch$2.compileRe(parsed, options, returnOutput, returnState);
};
/**
* Create a regular expression from the given regex source string.
*
* ```js
* const picomatch = require('picomatch');
* // picomatch.toRegex(source[, options]);
*
* const { output } = picomatch.parse('*.js');
* console.log(picomatch.toRegex(output));
* //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/
* ```
* @param {String} `source` Regular expression source string.
* @param {Object} `options`
* @return {RegExp}
* @api public
*/
picomatch$2.toRegex = (source, options) => {
try {
const opts = options || {};
return new RegExp(source, opts.flags || (opts.nocase ? 'i' : ''));
} catch (err) {
if (options && options.debug === true) throw err;
return /$^/;
}
};
/**
* Picomatch constants.
* @return {Object}
*/
picomatch$2.constants = constants;
/**
* Expose "picomatch"
*/
var picomatch_1 = picomatch$2;
var picomatch$1 = picomatch_1;
const util = require$$0;
const braces = braces_1;
const picomatch = picomatch$1;
const utils = utils$4;
const isEmptyString = val => val === '' || val === './';
/**
* Returns an array of strings that match one or more glob patterns.
*
* ```js
* const mm = require('micromatch');
* // mm(list, patterns[, options]);
*
* console.log(mm(['a.js', 'a.txt'], ['*.js']));
* //=> [ 'a.js' ]
* ```
* @param {String|Array<string>} `list` List of strings to match.
* @param {String|Array<string>} `patterns` One or more glob patterns to use for matching.
* @param {Object} `options` See available [options](#options)
* @return {Array} Returns an array of matches
* @summary false
* @api public
*/
const micromatch = (list, patterns, options) => {
patterns = [].concat(patterns);
list = [].concat(list);
let omit = new Set();
let keep = new Set();
let items = new Set();
let negatives = 0;
let onResult = state => {
items.add(state.output);
if (options && options.onResult) {
options.onResult(state);
}
};
for (let i = 0; i < patterns.length; i++) {
let isMatch = picomatch(String(patterns[i]), { ...options, onResult }, true);
let negated = isMatch.state.negated || isMatch.state.negatedExtglob;
if (negated) negatives++;
for (let item of list) {
let matched = isMatch(item, true);
let match = negated ? !matched.isMatch : matched.isMatch;
if (!match) continue;
if (negated) {
omit.add(matched.output);
} else {
omit.delete(matched.output);
keep.add(matched.output);
}
}
}
let result = negatives === patterns.length ? [...items] : [...keep];
let matches = result.filter(item => !omit.has(item));
if (options && matches.length === 0) {
if (options.failglob === true) {
throw new Error(`No matches found for "${patterns.join(', ')}"`);
}
if (options.nonull === true || options.nullglob === true) {
return options.unescape ? patterns.map(p => p.replace(/\\/g, '')) : patterns;
}
}
return matches;
};
/**
* Backwards compatibility
*/
micromatch.match = micromatch;
/**
* Returns a matcher function from the given glob `pattern` and `options`.
* The returned function takes a string to match as its only argument and returns
* true if the string is a match.
*
* ```js
* const mm = require('micromatch');
* // mm.matcher(pattern[, options]);
*
* const isMatch = mm.matcher('*.!(*a)');
* console.log(isMatch('a.a')); //=> false
* console.log(isMatch('a.b')); //=> true
* ```
* @param {String} `pattern` Glob pattern
* @param {Object} `options`
* @return {Function} Returns a matcher function.
* @api public
*/
micromatch.matcher = (pattern, options) => picomatch(pattern, options);
/**
* Returns true if **any** of the given glob `patterns` match the specified `string`.
*
* ```js
* const mm = require('micromatch');
* // mm.isMatch(string, patterns[, options]);
*
* console.log(mm.isMatch('a.a', ['b.*', '*.a'])); //=> true
* console.log(mm.isMatch('a.a', 'b.*')); //=> false
* ```
* @param {String} `str` The string to test.
* @param {String|Array} `patterns` One or more glob patterns to use for matching.
* @param {Object} `[options]` See available [options](#options).
* @return {Boolean} Returns true if any patterns match `str`
* @api public
*/
micromatch.isMatch = (str, patterns, options) => picomatch(patterns, options)(str);
/**
* Backwards compatibility
*/
micromatch.any = micromatch.isMatch;
/**
* Returns a list of strings that _**do not match any**_ of the given `patterns`.
*
* ```js
* const mm = require('micromatch');
* // mm.not(list, patterns[, options]);
*
* console.log(mm.not(['a.a', 'b.b', 'c.c'], '*.a'));
* //=> ['b.b', 'c.c']
* ```
* @param {Array} `list` Array of strings to match.
* @param {String|Array} `patterns` One or more glob pattern to use for matching.
* @param {Object} `options` See available [options](#options) for changing how matches are performed
* @return {Array} Returns an array of strings that **do not match** the given patterns.
* @api public
*/
micromatch.not = (list, patterns, options = {}) => {
patterns = [].concat(patterns).map(String);
let result = new Set();
let items = [];
let onResult = state => {
if (options.onResult) options.onResult(state);
items.push(state.output);
};
let matches = new Set(micromatch(list, patterns, { ...options, onResult }));
for (let item of items) {
if (!matches.has(item)) {
result.add(item);
}
}
return [...result];
};
/**
* Returns true if the given `string` contains the given pattern. Similar
* to [.isMatch](#isMatch) but the pattern can match any part of the string.
*
* ```js
* var mm = require('micromatch');
* // mm.contains(string, pattern[, options]);
*
* console.log(mm.contains('aa/bb/cc', '*b'));
* //=> true
* console.log(mm.contains('aa/bb/cc', '*d'));
* //=> false
* ```
* @param {String} `str` The string to match.
* @param {String|Array} `patterns` Glob pattern to use for matching.
* @param {Object} `options` See available [options](#options) for changing how matches are performed
* @return {Boolean} Returns true if any of the patterns matches any part of `str`.
* @api public
*/
micromatch.contains = (str, pattern, options) => {
if (typeof str !== 'string') {
throw new TypeError(`Expected a string: "${util.inspect(str)}"`);
}
if (Array.isArray(pattern)) {
return pattern.some(p => micromatch.contains(str, p, options));
}
if (typeof pattern === 'string') {
if (isEmptyString(str) || isEmptyString(pattern)) {
return false;
}
if (str.includes(pattern) || (str.startsWith('./') && str.slice(2).includes(pattern))) {
return true;
}
}
return micromatch.isMatch(str, pattern, { ...options, contains: true });
};
/**
* Filter the keys of the given object with the given `glob` pattern
* and `options`. Does not attempt to match nested keys. If you need this feature,
* use [glob-object][] instead.
*
* ```js
* const mm = require('micromatch');
* // mm.matchKeys(object, patterns[, options]);
*
* const obj = { aa: 'a', ab: 'b', ac: 'c' };
* console.log(mm.matchKeys(obj, '*b'));
* //=> { ab: 'b' }
* ```
* @param {Object} `object` The object with keys to filter.
* @param {String|Array} `patterns` One or more glob patterns to use for matching.
* @param {Object} `options` See available [options](#options) for changing how matches are performed
* @return {Object} Returns an object with only keys that match the given patterns.
* @api public
*/
micromatch.matchKeys = (obj, patterns, options) => {
if (!utils.isObject(obj)) {
throw new TypeError('Expected the first argument to be an object');
}
let keys = micromatch(Object.keys(obj), patterns, options);
let res = {};
for (let key of keys) res[key] = obj[key];
return res;
};
/**
* Returns true if some of the strings in the given `list` match any of the given glob `patterns`.
*
* ```js
* const mm = require('micromatch');
* // mm.some(list, patterns[, options]);
*
* console.log(mm.some(['foo.js', 'bar.js'], ['*.js', '!foo.js']));
* // true
* console.log(mm.some(['foo.js'], ['*.js', '!foo.js']));
* // false
* ```
* @param {String|Array} `list` The string or array of strings to test. Returns as soon as the first match is found.
* @param {String|Array} `patterns` One or more glob patterns to use for matching.
* @param {Object} `options` See available [options](#options) for changing how matches are performed
* @return {Boolean} Returns true if any `patterns` matches any of the strings in `list`
* @api public
*/
micromatch.some = (list, patterns, options) => {
let items = [].concat(list);
for (let pattern of [].concat(patterns)) {
let isMatch = picomatch(String(pattern), options);
if (items.some(item => isMatch(item))) {
return true;
}
}
return false;
};
/**
* Returns true if every string in the given `list` matches
* any of the given glob `patterns`.
*
* ```js
* const mm = require('micromatch');
* // mm.every(list, patterns[, options]);
*
* console.log(mm.every('foo.js', ['foo.js']));
* // true
* console.log(mm.every(['foo.js', 'bar.js'], ['*.js']));
* // true
* console.log(mm.every(['foo.js', 'bar.js'], ['*.js', '!foo.js']));
* // false
* console.log(mm.every(['foo.js'], ['*.js', '!foo.js']));
* // false
* ```
* @param {String|Array} `list` The string or array of strings to test.
* @param {String|Array} `patterns` One or more glob patterns to use for matching.
* @param {Object} `options` See available [options](#options) for changing how matches are performed
* @return {Boolean} Returns true if all `patterns` matches all of the strings in `list`
* @api public
*/
micromatch.every = (list, patterns, options) => {
let items = [].concat(list);
for (let pattern of [].concat(patterns)) {
let isMatch = picomatch(String(pattern), options);
if (!items.every(item => isMatch(item))) {
return false;
}
}
return true;
};
/**
* Returns true if **all** of the given `patterns` match
* the specified string.
*
* ```js
* const mm = require('micromatch');
* // mm.all(string, patterns[, options]);
*
* console.log(mm.all('foo.js', ['foo.js']));
* // true
*
* console.log(mm.all('foo.js', ['*.js', '!foo.js']));
* // false
*
* console.log(mm.all('foo.js', ['*.js', 'foo.js']));
* // true
*
* console.log(mm.all('foo.js', ['*.js', 'f*', '*o*', '*o.js']));
* // true
* ```
* @param {String|Array} `str` The string to test.
* @param {String|Array} `patterns` One or more glob patterns to use for matching.
* @param {Object} `options` See available [options](#options) for changing how matches are performed
* @return {Boolean} Returns true if any patterns match `str`
* @api public
*/
micromatch.all = (str, patterns, options) => {
if (typeof str !== 'string') {
throw new TypeError(`Expected a string: "${util.inspect(str)}"`);
}
return [].concat(patterns).every(p => picomatch(p, options)(str));
};
/**
* Returns an array of matches captured by `pattern` in `string, or `null` if the pattern did not match.
*
* ```js
* const mm = require('micromatch');
* // mm.capture(pattern, string[, options]);
*
* console.log(mm.capture('test/*.js', 'test/foo.js'));
* //=> ['foo']
* console.log(mm.capture('test/*.js', 'foo/bar.css'));
* //=> null
* ```
* @param {String} `glob` Glob pattern to use for matching.
* @param {String} `input` String to match
* @param {Object} `options` See available [options](#options) for changing how matches are performed
* @return {Array|null} Returns an array of captures if the input matches the glob pattern, otherwise `null`.
* @api public
*/
micromatch.capture = (glob, input, options) => {
let posix = utils.isWindows(options);
let regex = picomatch.makeRe(String(glob), { ...options, capture: true });
let match = regex.exec(posix ? utils.toPosixSlashes(input) : input);
if (match) {
return match.slice(1).map(v => v === void 0 ? '' : v);
}
};
/**
* Create a regular expression from the given glob `pattern`.
*
* ```js
* const mm = require('micromatch');
* // mm.makeRe(pattern[, options]);
*
* console.log(mm.makeRe('*.js'));
* //=> /^(?:(\.[\\\/])?(?!\.)(?=.)[^\/]*?\.js)$/
* ```
* @param {String} `pattern` A glob pattern to convert to regex.
* @param {Object} `options`
* @return {RegExp} Returns a regex created from the given pattern.
* @api public
*/
micromatch.makeRe = (...args) => picomatch.makeRe(...args);
/**
* Scan a glob pattern to separate the pattern into segments. Used
* by the [split](#split) method.
*
* ```js
* const mm = require('micromatch');
* const state = mm.scan(pattern[, options]);
* ```
* @param {String} `pattern`
* @param {Object} `options`
* @return {Object} Returns an object with
* @api public
*/
micromatch.scan = (...args) => picomatch.scan(...args);
/**
* Parse a glob pattern to create the source string for a regular
* expression.
*
* ```js
* const mm = require('micromatch');
* const state = mm.parse(pattern[, options]);
* ```
* @param {String} `glob`
* @param {Object} `options`
* @return {Object} Returns an object with useful properties and output to be used as regex source string.
* @api public
*/
micromatch.parse = (patterns, options) => {
let res = [];
for (let pattern of [].concat(patterns || [])) {
for (let str of braces(String(pattern), options)) {
res.push(picomatch.parse(str, options));
}
}
return res;
};
/**
* Process the given brace `pattern`.
*
* ```js
* const { braces } = require('micromatch');
* console.log(braces('foo/{a,b,c}/bar'));
* //=> [ 'foo/(a|b|c)/bar' ]
*
* console.log(braces('foo/{a,b,c}/bar', { expand: true }));
* //=> [ 'foo/a/bar', 'foo/b/bar', 'foo/c/bar' ]
* ```
* @param {String} `pattern` String with brace pattern to process.
* @param {Object} `options` Any [options](#options) to change how expansion is performed. See the [braces][] library for all available options.
* @return {Array}
* @api public
*/
micromatch.braces = (pattern, options) => {
if (typeof pattern !== 'string') throw new TypeError('Expected a string');
if ((options && options.nobrace === true) || !/\{.*\}/.test(pattern)) {
return [pattern];
}
return braces(pattern, options);
};
/**
* Expand braces
*/
micromatch.braceExpand = (pattern, options) => {
if (typeof pattern !== 'string') throw new TypeError('Expected a string');
return micromatch.braces(pattern, { ...options, expand: true });
};
/**
* Expose micromatch
*/
var micromatch_1 = micromatch;
var mm = /*@__PURE__*/getDefaultExportFromCjs(micromatch_1);
export { micromatch_1 as a, mm as m };
@@ -0,0 +1,54 @@
import { createRequire } from 'node:module';
const __require = createRequire(import.meta.url);
let inspector;
let session;
function setupInspect(ctx) {
const config = ctx.config;
const isEnabled = config.inspector.enabled;
if (isEnabled) {
inspector = __require("node:inspector");
const isOpen = inspector.url() !== void 0;
if (!isOpen) {
inspector.open(
config.inspector.port,
config.inspector.host,
config.inspector.waitForDebugger
);
if (config.inspectBrk) {
const firstTestFile = ctx.files[0];
if (firstTestFile) {
session = new inspector.Session();
session.connect();
session.post("Debugger.enable");
session.post("Debugger.setBreakpointByUrl", {
lineNumber: 0,
url: new URL(firstTestFile, import.meta.url).href
});
}
}
}
}
const keepOpen = shouldKeepOpen(config);
return function cleanup() {
if (isEnabled && !keepOpen && inspector) {
inspector.close();
session == null ? void 0 : session.disconnect();
}
};
}
function closeInspector(config) {
const keepOpen = shouldKeepOpen(config);
if (inspector && !keepOpen) {
inspector.close();
session == null ? void 0 : session.disconnect();
}
}
function shouldKeepOpen(config) {
var _a, _b, _c, _d, _e, _f, _g, _h;
const isIsolatedSingleThread = config.pool === "threads" && ((_b = (_a = config.poolOptions) == null ? void 0 : _a.threads) == null ? void 0 : _b.isolate) === false && ((_d = (_c = config.poolOptions) == null ? void 0 : _c.threads) == null ? void 0 : _d.singleThread);
const isIsolatedSingleFork = config.pool === "forks" && ((_f = (_e = config.poolOptions) == null ? void 0 : _e.forks) == null ? void 0 : _f.isolate) === false && ((_h = (_g = config.poolOptions) == null ? void 0 : _g.forks) == null ? void 0 : _h.singleFork);
return config.watch && (isIsolatedSingleFork || isIsolatedSingleThread);
}
export { closeInspector as c, setupInspect as s };
@@ -0,0 +1,94 @@
import { getSafeTimers } from '@vitest/utils';
import { c as createBirpc } from './index.8bPxjt7g.js';
import { g as getWorkerState } from './global.CkGT_TMy.js';
const { get } = Reflect;
function withSafeTimers(fn) {
var _a;
const { setTimeout, clearTimeout, nextTick, setImmediate, clearImmediate } = getSafeTimers();
const currentSetTimeout = globalThis.setTimeout;
const currentClearTimeout = globalThis.clearTimeout;
const currentSetImmediate = globalThis.setImmediate;
const currentClearImmediate = globalThis.clearImmediate;
const currentNextTick = (_a = globalThis.process) == null ? void 0 : _a.nextTick;
try {
globalThis.setTimeout = setTimeout;
globalThis.clearTimeout = clearTimeout;
globalThis.setImmediate = setImmediate;
globalThis.clearImmediate = clearImmediate;
if (globalThis.process)
globalThis.process.nextTick = nextTick;
const result = fn();
return result;
} finally {
globalThis.setTimeout = currentSetTimeout;
globalThis.clearTimeout = currentClearTimeout;
globalThis.setImmediate = currentSetImmediate;
globalThis.clearImmediate = currentClearImmediate;
if (globalThis.process) {
nextTick(() => {
globalThis.process.nextTick = currentNextTick;
});
}
}
}
const promises = /* @__PURE__ */ new Set();
async function rpcDone() {
if (!promises.size)
return;
const awaitable = Array.from(promises);
return Promise.all(awaitable);
}
function createRuntimeRpc(options) {
let setCancel = (_reason) => {
};
const onCancel = new Promise((resolve) => {
setCancel = resolve;
});
const rpc2 = createSafeRpc(createBirpc(
{
onCancel: setCancel
},
{
eventNames: ["onUserConsoleLog", "onFinished", "onCollected", "onCancel"],
onTimeoutError(functionName, args) {
var _a;
let message = `[vitest-worker]: Timeout calling "${functionName}"`;
if (functionName === "fetch" || functionName === "transform" || functionName === "resolveId")
message += ` with "${JSON.stringify(args)}"`;
if (functionName === "onUnhandledError")
message += ` with "${((_a = args[0]) == null ? void 0 : _a.message) || args[0]}"`;
throw new Error(message);
},
...options
}
));
return {
rpc: rpc2,
onCancel
};
}
function createSafeRpc(rpc2) {
return new Proxy(rpc2, {
get(target, p, handler) {
const sendCall = get(target, p, handler);
const safeSendCall = (...args) => withSafeTimers(async () => {
const result = sendCall(...args);
promises.add(result);
try {
return await result;
} finally {
promises.delete(result);
}
});
safeSendCall.asEvent = sendCall.asEvent;
return safeSendCall;
}
});
}
function rpc() {
const { rpc: rpc2 } = getWorkerState();
return rpc2;
}
export { rpcDone as a, createRuntimeRpc as c, rpc as r };
@@ -0,0 +1,27 @@
import { g as getWorkerState } from './global.CkGT_TMy.js';
const filesCount = /* @__PURE__ */ new Map();
const cache = /* @__PURE__ */ new Map();
function runOnce(fn, key) {
const filepath = getWorkerState().filepath || "__unknown_files__";
if (!key) {
filesCount.set(filepath, (filesCount.get(filepath) || 0) + 1);
key = String(filesCount.get(filepath));
}
const id = `${filepath}:${key}`;
if (!cache.has(id))
cache.set(id, fn());
return cache.get(id);
}
function isFirstRun() {
let firstRun = false;
runOnce(() => {
firstRun = true;
}, "__vitest_first_run__");
return firstRun;
}
function resetRunOnceCounter() {
filesCount.clear();
}
export { runOnce as a, isFirstRun as i, resetRunOnceCounter as r };
@@ -0,0 +1,55 @@
import { setSafeTimers } from '@vitest/utils';
import { addSerializer } from '@vitest/snapshot';
import { r as resetRunOnceCounter } from './run-once.Olz_Zkd8.js';
let globalSetup = false;
async function setupCommonEnv(config) {
resetRunOnceCounter();
setupDefines(config.defines);
setupEnv(config.env);
if (globalSetup)
return;
globalSetup = true;
setSafeTimers();
if (config.globals)
(await import('../chunks/integrations-globals.kw4co3rx.js')).registerApiGlobally();
}
function setupDefines(defines) {
for (const key in defines)
globalThis[key] = defines[key];
}
function setupEnv(env) {
if (typeof process === "undefined")
return;
const { PROD, DEV, ...restEnvs } = env;
process.env.PROD = PROD ? "1" : "";
process.env.DEV = DEV ? "1" : "";
for (const key in restEnvs)
process.env[key] = env[key];
}
async function loadDiffConfig(config, executor) {
if (typeof config.diff !== "string")
return;
const diffModule = await executor.executeId(config.diff);
if (diffModule && typeof diffModule.default === "object" && diffModule.default != null)
return diffModule.default;
else
throw new Error(`invalid diff config file ${config.diff}. Must have a default export with config object`);
}
async function loadSnapshotSerializers(config, executor) {
const files = config.snapshotSerializers;
const snapshotSerializers = await Promise.all(
files.map(async (file) => {
const mo = await executor.executeId(file);
if (!mo || typeof mo.default !== "object" || mo.default === null)
throw new Error(`invalid snapshot serializer file ${file}. Must export a default object`);
const config2 = mo.default;
if (typeof config2.test !== "function" || typeof config2.serialize !== "function" && typeof config2.print !== "function")
throw new Error(`invalid snapshot serializer in ${file}. Must have a 'test' method along with either a 'serialize' or 'print' method.`);
return config2;
})
);
snapshotSerializers.forEach((serializer) => addSerializer(serializer));
}
export { loadSnapshotSerializers as a, loadDiffConfig as l, setupCommonEnv as s };
@@ -0,0 +1,14 @@
import { getNames, getTests } from '@vitest/runner/utils';
import '@vitest/utils';
function hasFailedSnapshot(suite) {
return getTests(suite).some((s) => {
var _a, _b;
return (_b = (_a = s.result) == null ? void 0 : _a.errors) == null ? void 0 : _b.some((e) => typeof (e == null ? void 0 : e.message) === "string" && e.message.match(/Snapshot .* mismatched/));
});
}
function getFullName(task, separator = " > ") {
return getNames(task).join(separator);
}
export { getFullName as g, hasFailedSnapshot as h };
@@ -0,0 +1,49 @@
import { parseRegexp } from '@vitest/utils';
var _a, _b;
const REGEXP_WRAP_PREFIX = "$$vitest:";
const processSend = (_a = process.send) == null ? void 0 : _a.bind(process);
const processOn = (_b = process.on) == null ? void 0 : _b.bind(process);
function createThreadsRpcOptions({ port }) {
return {
post: (v) => {
port.postMessage(v);
},
on: (fn) => {
port.addListener("message", fn);
}
};
}
function createForksRpcOptions(nodeV8) {
return {
serialize: nodeV8.serialize,
deserialize: (v) => nodeV8.deserialize(Buffer.from(v)),
post(v) {
processSend(v);
},
on(fn) {
processOn("message", (message, ...extras) => {
if (message == null ? void 0 : message.__tinypool_worker_message__)
return;
return fn(message, ...extras);
});
}
};
}
function unwrapSerializableConfig(config) {
if (config.testNamePattern && typeof config.testNamePattern === "string") {
const testNamePattern = config.testNamePattern;
if (testNamePattern.startsWith(REGEXP_WRAP_PREFIX))
config.testNamePattern = parseRegexp(testNamePattern.slice(REGEXP_WRAP_PREFIX.length));
}
if (config.defines && Array.isArray(config.defines.keys) && config.defines.original) {
const { keys, original } = config.defines;
const defines = {};
for (const key of keys)
defines[key] = original[key];
config.defines = defines;
}
return config;
}
export { createThreadsRpcOptions as a, createForksRpcOptions as c, unwrapSerializableConfig as u };
@@ -0,0 +1,217 @@
import { isAbsolute, relative, dirname, basename } from 'pathe';
import c from 'picocolors';
import { a as slash } from './base.5NT-gWu5.js';
const F_RIGHT = "\u2192";
const F_DOWN = "\u2193";
const F_DOWN_RIGHT = "\u21B3";
const F_POINTER = "\u276F";
const F_DOT = "\xB7";
const F_CHECK = "\u2713";
const F_CROSS = "\xD7";
const F_LONG_DASH = "\u23AF";
function ansiRegex({onlyFirst = false} = {}) {
const pattern = [
'[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)',
'(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))'
].join('|');
return new RegExp(pattern, onlyFirst ? undefined : 'g');
}
const regex = ansiRegex();
function stripAnsi(string) {
if (typeof string !== 'string') {
throw new TypeError(`Expected a \`string\`, got \`${typeof string}\``);
}
// Even though the regex is global, we don't need to reset the `.lastIndex`
// because unlike `.exec()` and `.test()`, `.replace()` does it automatically
// and doing it manually has a performance penalty.
return string.replace(regex, '');
}
const spinnerMap = /* @__PURE__ */ new WeakMap();
const hookSpinnerMap = /* @__PURE__ */ new WeakMap();
const pointer = c.yellow(F_POINTER);
const skipped = c.dim(c.gray(F_DOWN));
function getCols(delta = 0) {
var _a;
let length = (_a = process.stdout) == null ? void 0 : _a.columns;
if (!length || Number.isNaN(length))
length = 30;
return Math.max(length + delta, 0);
}
function divider(text, left, right) {
const cols = getCols();
if (text) {
const textLength = stripAnsi(text).length;
if (left == null && right != null) {
left = cols - textLength - right;
} else {
left = left ?? Math.floor((cols - textLength) / 2);
right = cols - textLength - left;
}
left = Math.max(0, left);
right = Math.max(0, right);
return `${F_LONG_DASH.repeat(left)}${text}${F_LONG_DASH.repeat(right)}`;
}
return F_LONG_DASH.repeat(cols);
}
function formatTestPath(root, path) {
var _a;
if (isAbsolute(path))
path = relative(root, path);
const dir = dirname(path);
const ext = ((_a = path.match(/(\.(spec|test)\.[cm]?[tj]sx?)$/)) == null ? void 0 : _a[0]) || "";
const base = basename(path, ext);
return slash(c.dim(`${dir}/`) + c.bold(base)) + c.dim(ext);
}
function renderSnapshotSummary(rootDir, snapshots) {
const summary = [];
if (snapshots.added)
summary.push(c.bold(c.green(`${snapshots.added} written`)));
if (snapshots.unmatched)
summary.push(c.bold(c.red(`${snapshots.unmatched} failed`)));
if (snapshots.updated)
summary.push(c.bold(c.green(`${snapshots.updated} updated `)));
if (snapshots.filesRemoved) {
if (snapshots.didUpdate)
summary.push(c.bold(c.green(`${snapshots.filesRemoved} files removed `)));
else
summary.push(c.bold(c.yellow(`${snapshots.filesRemoved} files obsolete `)));
}
if (snapshots.filesRemovedList && snapshots.filesRemovedList.length) {
const [head, ...tail] = snapshots.filesRemovedList;
summary.push(`${c.gray(F_DOWN_RIGHT)} ${formatTestPath(rootDir, head)}`);
tail.forEach((key) => {
summary.push(` ${c.gray(F_DOT)} ${formatTestPath(rootDir, key)}`);
});
}
if (snapshots.unchecked) {
if (snapshots.didUpdate)
summary.push(c.bold(c.green(`${snapshots.unchecked} removed`)));
else
summary.push(c.bold(c.yellow(`${snapshots.unchecked} obsolete`)));
snapshots.uncheckedKeysByFile.forEach((uncheckedFile) => {
summary.push(`${c.gray(F_DOWN_RIGHT)} ${formatTestPath(rootDir, uncheckedFile.filePath)}`);
uncheckedFile.keys.forEach((key) => summary.push(` ${c.gray(F_DOT)} ${key}`));
});
}
return summary;
}
function countTestErrors(tasks) {
return tasks.reduce((c2, i) => {
var _a, _b;
return c2 + (((_b = (_a = i.result) == null ? void 0 : _a.errors) == null ? void 0 : _b.length) || 0);
}, 0);
}
function getStateString(tasks, name = "tests", showTotal = true) {
if (tasks.length === 0)
return c.dim(`no ${name}`);
const passed = tasks.filter((i) => {
var _a;
return ((_a = i.result) == null ? void 0 : _a.state) === "pass";
});
const failed = tasks.filter((i) => {
var _a;
return ((_a = i.result) == null ? void 0 : _a.state) === "fail";
});
const skipped2 = tasks.filter((i) => i.mode === "skip");
const todo = tasks.filter((i) => i.mode === "todo");
return [
failed.length ? c.bold(c.red(`${failed.length} failed`)) : null,
passed.length ? c.bold(c.green(`${passed.length} passed`)) : null,
skipped2.length ? c.yellow(`${skipped2.length} skipped`) : null,
todo.length ? c.gray(`${todo.length} todo`) : null
].filter(Boolean).join(c.dim(" | ")) + (showTotal ? c.gray(` (${tasks.length})`) : "");
}
function getStateSymbol(task) {
var _a;
if (task.mode === "skip" || task.mode === "todo")
return skipped;
if (!task.result)
return c.gray("\xB7");
if (task.result.state === "run") {
if (task.type === "suite")
return pointer;
let spinner = spinnerMap.get(task);
if (!spinner) {
spinner = elegantSpinner();
spinnerMap.set(task, spinner);
}
return c.yellow(spinner());
}
if (task.result.state === "pass") {
return ((_a = task.meta) == null ? void 0 : _a.benchmark) ? c.green(F_DOT) : c.green(F_CHECK);
}
if (task.result.state === "fail") {
return task.type === "suite" ? pointer : c.red(F_CROSS);
}
return " ";
}
function getHookStateSymbol(task, hookName) {
var _a, _b;
const state = (_b = (_a = task.result) == null ? void 0 : _a.hooks) == null ? void 0 : _b[hookName];
if (state && state === "run") {
let spinnerMap2 = hookSpinnerMap.get(task);
if (!spinnerMap2) {
spinnerMap2 = /* @__PURE__ */ new Map();
hookSpinnerMap.set(task, spinnerMap2);
}
let spinner = spinnerMap2.get(hookName);
if (!spinner) {
spinner = elegantSpinner();
spinnerMap2.set(hookName, spinner);
}
return c.yellow(spinner());
}
}
const spinnerFrames = process.platform === "win32" ? ["-", "\\", "|", "/"] : ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
function elegantSpinner() {
let index = 0;
return () => {
index = ++index % spinnerFrames.length;
return spinnerFrames[index];
};
}
function formatTimeString(date) {
return date.toTimeString().split(" ")[0];
}
function formatProjectName(name, suffix = " ") {
if (!name)
return "";
const index = name.split("").reduce((acc, v, idx) => acc + v.charCodeAt(0) + idx, 0);
const colors = [
c.blue,
c.yellow,
c.cyan,
c.green,
c.magenta
];
return colors[index % colors.length](`|${name}|`) + suffix;
}
var utils = /*#__PURE__*/Object.freeze({
__proto__: null,
countTestErrors: countTestErrors,
divider: divider,
elegantSpinner: elegantSpinner,
formatProjectName: formatProjectName,
formatTestPath: formatTestPath,
formatTimeString: formatTimeString,
getCols: getCols,
getHookStateSymbol: getHookStateSymbol,
getStateString: getStateString,
getStateSymbol: getStateSymbol,
hookSpinnerMap: hookSpinnerMap,
pointer: pointer,
renderSnapshotSummary: renderSnapshotSummary,
skipped: skipped,
spinnerFrames: spinnerFrames,
spinnerMap: spinnerMap
});
export { F_RIGHT as F, getStateString as a, formatTimeString as b, countTestErrors as c, divider as d, getCols as e, formatProjectName as f, getStateSymbol as g, getHookStateSymbol as h, F_POINTER as i, pointer as p, renderSnapshotSummary as r, stripAnsi as s, utils as u };
+3551
View File
@@ -0,0 +1,3551 @@
import * as chai$1 from 'chai';
import { c as commonjsGlobal, g as getDefaultExportFromCjs } from './_commonjsHelpers.jjO7Zipk.js';
import { equals, iterableEquality, subsetEquality, JestExtend, JestChaiExpect, JestAsymmetricMatchers, GLOBAL_EXPECT as GLOBAL_EXPECT$1, ASYMMETRIC_MATCHERS_OBJECT as ASYMMETRIC_MATCHERS_OBJECT$1, getState, setState, addCustomEqualityTesters } from '@vitest/expect';
import { stripSnapshotIndentation, addSerializer, SnapshotClient } from '@vitest/snapshot';
import { getNames } from '@vitest/runner/utils';
import '@vitest/utils/error';
import { getCurrentTest } from '@vitest/runner';
import { g as getFullName } from './tasks.IknbGB2n.js';
import { g as getWorkerState, a as getCurrentEnvironment } from './global.CkGT_TMy.js';
import { getSafeTimers, assertTypes, createSimpleStackTrace } from '@vitest/utils';
import { parseSingleStack } from '@vitest/utils/source-map';
import { i as isChildProcess } from './base.5NT-gWu5.js';
import { R as RealDate, r as resetDate, m as mockDate } from './date.Ns1pGd_X.js';
import { spyOn, fn, isMockFunction, mocks } from '@vitest/spy';
function resetModules(modules, resetMocks = false) {
const skipPaths = [
// Vitest
/\/vitest\/dist\//,
/\/vite-node\/dist\//,
// yarn's .store folder
/vitest-virtual-\w+\/dist/,
// cnpm
/@vitest\/dist/,
// don't clear mocks
...!resetMocks ? [/^mock:/] : []
];
modules.forEach((mod, path) => {
if (skipPaths.some((re) => re.test(path)))
return;
modules.invalidateModule(mod);
});
}
function waitNextTick() {
const { setTimeout } = getSafeTimers();
return new Promise((resolve) => setTimeout(resolve, 0));
}
async function waitForImportsToResolve() {
await waitNextTick();
const state = getWorkerState();
const promises = [];
let resolvingCount = 0;
for (const mod of state.moduleCache.values()) {
if (mod.promise && !mod.evaluated)
promises.push(mod.promise);
if (mod.resolving)
resolvingCount++;
}
if (!promises.length && !resolvingCount)
return;
await Promise.allSettled(promises);
await waitForImportsToResolve();
}
function commonjsRequire(path) {
throw new Error('Could not dynamically require "' + path + '". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.');
}
var chaiSubset = {exports: {}};
(function (module, exports) {
(function() {
(function(chaiSubset) {
if (typeof commonjsRequire === 'function' && 'object' === 'object' && 'object' === 'object') {
return module.exports = chaiSubset;
} else {
return chai.use(chaiSubset);
}
})(function(chai, utils) {
var Assertion = chai.Assertion;
var assertionPrototype = Assertion.prototype;
Assertion.addMethod('containSubset', function (expected) {
var actual = utils.flag(this, 'object');
var showDiff = chai.config.showDiff;
assertionPrototype.assert.call(this,
compare(expected, actual),
'expected #{act} to contain subset #{exp}',
'expected #{act} to not contain subset #{exp}',
expected,
actual,
showDiff
);
});
chai.assert.containSubset = function(val, exp, msg) {
new chai.Assertion(val, msg).to.be.containSubset(exp);
};
function compare(expected, actual) {
if (expected === actual) {
return true;
}
if (typeof(actual) !== typeof(expected)) {
return false;
}
if (typeof(expected) !== 'object' || expected === null) {
return expected === actual;
}
if (!!expected && !actual) {
return false;
}
if (Array.isArray(expected)) {
if (typeof(actual.length) !== 'number') {
return false;
}
var aa = Array.prototype.slice.call(actual);
return expected.every(function (exp) {
return aa.some(function (act) {
return compare(exp, act);
});
});
}
if (expected instanceof Date) {
if (actual instanceof Date) {
return expected.getTime() === actual.getTime();
} else {
return false;
}
}
return Object.keys(expected).every(function (key) {
var eo = expected[key];
var ao = actual[key];
if (typeof(eo) === 'object' && eo !== null && ao !== null) {
return compare(eo, ao);
}
if (typeof(eo) === 'function') {
return eo(ao);
}
return ao === eo;
});
}
});
}).call(commonjsGlobal);
} (chaiSubset));
var chaiSubsetExports = chaiSubset.exports;
var Subset = /*@__PURE__*/getDefaultExportFromCjs(chaiSubsetExports);
const MATCHERS_OBJECT = Symbol.for("matchers-object");
const JEST_MATCHERS_OBJECT = Symbol.for("$$jest-matchers-object");
const GLOBAL_EXPECT = Symbol.for("expect-global");
const ASYMMETRIC_MATCHERS_OBJECT = Symbol.for("asymmetric-matchers-object");
if (!Object.prototype.hasOwnProperty.call(globalThis, MATCHERS_OBJECT)) {
const globalState = /* @__PURE__ */ new WeakMap();
const matchers = /* @__PURE__ */ Object.create(null);
const customEqualityTesters = [];
const assymetricMatchers = /* @__PURE__ */ Object.create(null);
Object.defineProperty(globalThis, MATCHERS_OBJECT, {
get: () => globalState
});
Object.defineProperty(globalThis, JEST_MATCHERS_OBJECT, {
configurable: true,
get: () => ({
state: globalState.get(globalThis[GLOBAL_EXPECT]),
matchers,
customEqualityTesters
})
});
Object.defineProperty(globalThis, ASYMMETRIC_MATCHERS_OBJECT, {
get: () => assymetricMatchers
});
}
function recordAsyncExpect(test, promise) {
if (test && promise instanceof Promise) {
promise = promise.finally(() => {
const index = test.promises.indexOf(promise);
if (index !== -1)
test.promises.splice(index, 1);
});
if (!test.promises)
test.promises = [];
test.promises.push(promise);
}
return promise;
}
let _client;
function getSnapshotClient() {
if (!_client) {
_client = new SnapshotClient({
isEqual: (received, expected) => {
return equals(received, expected, [iterableEquality, subsetEquality]);
}
});
}
return _client;
}
function getError(expected, promise) {
if (typeof expected !== "function") {
if (!promise)
throw new Error(`expected must be a function, received ${typeof expected}`);
return expected;
}
try {
expected();
} catch (e) {
return e;
}
throw new Error("snapshot function didn't throw");
}
const SnapshotPlugin = (chai, utils) => {
const getTestNames = (test) => {
var _a;
if (!test)
return {};
return {
filepath: (_a = test.file) == null ? void 0 : _a.filepath,
name: getNames(test).slice(1).join(" > ")
};
};
for (const key of ["matchSnapshot", "toMatchSnapshot"]) {
utils.addMethod(
chai.Assertion.prototype,
key,
function(properties, message) {
const isNot = utils.flag(this, "negate");
if (isNot)
throw new Error(`${key} cannot be used with "not"`);
const expected = utils.flag(this, "object");
const test = utils.flag(this, "vitest-test");
if (typeof properties === "string" && typeof message === "undefined") {
message = properties;
properties = void 0;
}
const errorMessage = utils.flag(this, "message");
getSnapshotClient().assert({
received: expected,
message,
isInline: false,
properties,
errorMessage,
...getTestNames(test)
});
}
);
}
utils.addMethod(
chai.Assertion.prototype,
"toMatchFileSnapshot",
function(file, message) {
const isNot = utils.flag(this, "negate");
if (isNot)
throw new Error('toMatchFileSnapshot cannot be used with "not"');
const expected = utils.flag(this, "object");
const test = utils.flag(this, "vitest-test");
const errorMessage = utils.flag(this, "message");
const promise = getSnapshotClient().assertRaw({
received: expected,
message,
isInline: false,
rawSnapshot: {
file
},
errorMessage,
...getTestNames(test)
});
return recordAsyncExpect(test, promise);
}
);
utils.addMethod(
chai.Assertion.prototype,
"toMatchInlineSnapshot",
function __INLINE_SNAPSHOT__(properties, inlineSnapshot, message) {
var _a;
const isNot = utils.flag(this, "negate");
if (isNot)
throw new Error('toMatchInlineSnapshot cannot be used with "not"');
const test = utils.flag(this, "vitest-test");
const isInsideEach = test && (test.each || ((_a = test.suite) == null ? void 0 : _a.each));
if (isInsideEach)
throw new Error("InlineSnapshot cannot be used inside of test.each or describe.each");
const expected = utils.flag(this, "object");
const error = utils.flag(this, "error");
if (typeof properties === "string") {
message = inlineSnapshot;
inlineSnapshot = properties;
properties = void 0;
}
if (inlineSnapshot)
inlineSnapshot = stripSnapshotIndentation(inlineSnapshot);
const errorMessage = utils.flag(this, "message");
getSnapshotClient().assert({
received: expected,
message,
isInline: true,
properties,
inlineSnapshot,
error,
errorMessage,
...getTestNames(test)
});
}
);
utils.addMethod(
chai.Assertion.prototype,
"toThrowErrorMatchingSnapshot",
function(message) {
const isNot = utils.flag(this, "negate");
if (isNot)
throw new Error('toThrowErrorMatchingSnapshot cannot be used with "not"');
const expected = utils.flag(this, "object");
const test = utils.flag(this, "vitest-test");
const promise = utils.flag(this, "promise");
const errorMessage = utils.flag(this, "message");
getSnapshotClient().assert({
received: getError(expected, promise),
message,
errorMessage,
...getTestNames(test)
});
}
);
utils.addMethod(
chai.Assertion.prototype,
"toThrowErrorMatchingInlineSnapshot",
function __INLINE_SNAPSHOT__(inlineSnapshot, message) {
var _a;
const isNot = utils.flag(this, "negate");
if (isNot)
throw new Error('toThrowErrorMatchingInlineSnapshot cannot be used with "not"');
const test = utils.flag(this, "vitest-test");
const isInsideEach = test && (test.each || ((_a = test.suite) == null ? void 0 : _a.each));
if (isInsideEach)
throw new Error("InlineSnapshot cannot be used inside of test.each or describe.each");
const expected = utils.flag(this, "object");
const error = utils.flag(this, "error");
const promise = utils.flag(this, "promise");
const errorMessage = utils.flag(this, "message");
if (inlineSnapshot)
inlineSnapshot = stripSnapshotIndentation(inlineSnapshot);
getSnapshotClient().assert({
received: getError(expected, promise),
message,
inlineSnapshot,
isInline: true,
error,
errorMessage,
...getTestNames(test)
});
}
);
utils.addMethod(
chai.expect,
"addSnapshotSerializer",
addSerializer
);
};
chai$1.use(JestExtend);
chai$1.use(JestChaiExpect);
chai$1.use(Subset);
chai$1.use(SnapshotPlugin);
chai$1.use(JestAsymmetricMatchers);
function createExpect(test) {
var _a;
const expect = (value, message) => {
const { assertionCalls } = getState(expect);
setState({ assertionCalls: assertionCalls + 1, soft: false }, expect);
const assert2 = chai$1.expect(value, message);
const _test = test || getCurrentTest();
if (_test)
return assert2.withTest(_test);
else
return assert2;
};
Object.assign(expect, chai$1.expect);
Object.assign(expect, globalThis[ASYMMETRIC_MATCHERS_OBJECT$1]);
expect.getState = () => getState(expect);
expect.setState = (state) => setState(state, expect);
const globalState = getState(globalThis[GLOBAL_EXPECT$1]) || {};
setState({
// this should also add "snapshotState" that is added conditionally
...globalState,
assertionCalls: 0,
isExpectingAssertions: false,
isExpectingAssertionsError: null,
expectedAssertionsNumber: null,
expectedAssertionsNumberErrorGen: null,
environment: getCurrentEnvironment(),
testPath: test ? (_a = test.suite.file) == null ? void 0 : _a.filepath : globalState.testPath,
currentTestName: test ? getFullName(test) : globalState.currentTestName
}, expect);
expect.extend = (matchers) => chai$1.expect.extend(expect, matchers);
expect.addEqualityTesters = (customTesters) => addCustomEqualityTesters(customTesters);
expect.soft = (...args) => {
const assert2 = expect(...args);
expect.setState({
soft: true
});
return assert2;
};
expect.unreachable = (message) => {
chai$1.assert.fail(`expected${message ? ` "${message}" ` : " "}not to be reached`);
};
function assertions(expected) {
const errorGen = () => new Error(`expected number of assertions to be ${expected}, but got ${expect.getState().assertionCalls}`);
if (Error.captureStackTrace)
Error.captureStackTrace(errorGen(), assertions);
expect.setState({
expectedAssertionsNumber: expected,
expectedAssertionsNumberErrorGen: errorGen
});
}
function hasAssertions() {
const error = new Error("expected any number of assertion, but got none");
if (Error.captureStackTrace)
Error.captureStackTrace(error, hasAssertions);
expect.setState({
isExpectingAssertions: true,
isExpectingAssertionsError: error
});
}
chai$1.util.addMethod(expect, "assertions", assertions);
chai$1.util.addMethod(expect, "hasAssertions", hasAssertions);
return expect;
}
const globalExpect = createExpect();
Object.defineProperty(globalThis, GLOBAL_EXPECT$1, {
value: globalExpect,
writable: true,
configurable: true
});
/**
* A reference to the global object
*
* @type {object} globalObject
*/
var globalObject$1;
/* istanbul ignore else */
if (typeof commonjsGlobal !== "undefined") {
// Node
globalObject$1 = commonjsGlobal;
} else if (typeof window !== "undefined") {
// Browser
globalObject$1 = window;
} else {
// WebWorker
globalObject$1 = self;
}
var global = globalObject$1;
/**
* Is true when the environment causes an error to be thrown for accessing the
* __proto__ property.
*
* This is necessary in order to support `node --disable-proto=throw`.
*
* See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto
*
* @type {boolean}
*/
let throwsOnProto$1;
try {
const object = {};
// eslint-disable-next-line no-proto, no-unused-expressions
object.__proto__;
throwsOnProto$1 = false;
} catch (_) {
// This branch is covered when tests are run with `--disable-proto=throw`,
// however we can test both branches at the same time, so this is ignored
/* istanbul ignore next */
throwsOnProto$1 = true;
}
var throwsOnProto_1 = throwsOnProto$1;
var call = Function.call;
var throwsOnProto = throwsOnProto_1;
var disallowedProperties = [
// ignore size because it throws from Map
"size",
"caller",
"callee",
"arguments",
];
// This branch is covered when tests are run with `--disable-proto=throw`,
// however we can test both branches at the same time, so this is ignored
/* istanbul ignore next */
if (throwsOnProto) {
disallowedProperties.push("__proto__");
}
var copyPrototypeMethods = function copyPrototypeMethods(prototype) {
// eslint-disable-next-line @sinonjs/no-prototype-methods/no-prototype-methods
return Object.getOwnPropertyNames(prototype).reduce(function (
result,
name
) {
if (disallowedProperties.includes(name)) {
return result;
}
if (typeof prototype[name] !== "function") {
return result;
}
result[name] = call.bind(prototype[name]);
return result;
},
Object.create(null));
};
var copyPrototype$5 = copyPrototypeMethods;
var array = copyPrototype$5(Array.prototype);
var every$1 = array.every;
/**
* @private
*/
function hasCallsLeft(callMap, spy) {
if (callMap[spy.id] === undefined) {
callMap[spy.id] = 0;
}
return callMap[spy.id] < spy.callCount;
}
/**
* @private
*/
function checkAdjacentCalls(callMap, spy, index, spies) {
var calledBeforeNext = true;
if (index !== spies.length - 1) {
calledBeforeNext = spy.calledBefore(spies[index + 1]);
}
if (hasCallsLeft(callMap, spy) && calledBeforeNext) {
callMap[spy.id] += 1;
return true;
}
return false;
}
/**
* A Sinon proxy object (fake, spy, stub)
*
* @typedef {object} SinonProxy
* @property {Function} calledBefore - A method that determines if this proxy was called before another one
* @property {string} id - Some id
* @property {number} callCount - Number of times this proxy has been called
*/
/**
* Returns true when the spies have been called in the order they were supplied in
*
* @param {SinonProxy[] | SinonProxy} spies An array of proxies, or several proxies as arguments
* @returns {boolean} true when spies are called in order, false otherwise
*/
function calledInOrder(spies) {
var callMap = {};
// eslint-disable-next-line no-underscore-dangle
var _spies = arguments.length > 1 ? arguments : spies;
return every$1(_spies, checkAdjacentCalls.bind(null, callMap));
}
var calledInOrder_1 = calledInOrder;
/**
* Returns a display name for a function
*
* @param {Function} func
* @returns {string}
*/
var functionName$1 = function functionName(func) {
if (!func) {
return "";
}
try {
return (
func.displayName ||
func.name ||
// Use function decomposition as a last resort to get function
// name. Does not rely on function decomposition to work - if it
// doesn't debugging will be slightly less informative
// (i.e. toString will say 'spy' rather than 'myFunc').
(String(func).match(/function ([^\s(]+)/) || [])[1]
);
} catch (e) {
// Stringify may fail and we might get an exception, as a last-last
// resort fall back to empty string.
return "";
}
};
var functionName = functionName$1;
/**
* Returns a display name for a value from a constructor
*
* @param {object} value A value to examine
* @returns {(string|null)} A string or null
*/
function className(value) {
return (
(value.constructor && value.constructor.name) ||
// The next branch is for IE11 support only:
// Because the name property is not set on the prototype
// of the Function object, we finally try to grab the
// name from its definition. This will never be reached
// in node, so we are not able to test this properly.
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name
(typeof value.constructor === "function" &&
/* istanbul ignore next */
functionName(value.constructor)) ||
null
);
}
var className_1 = className;
var deprecated = {};
/* eslint-disable no-console */
(function (exports) {
/**
* Returns a function that will invoke the supplied function and print a
* deprecation warning to the console each time it is called.
*
* @param {Function} func
* @param {string} msg
* @returns {Function}
*/
exports.wrap = function (func, msg) {
var wrapped = function () {
exports.printWarning(msg);
return func.apply(this, arguments);
};
if (func.prototype) {
wrapped.prototype = func.prototype;
}
return wrapped;
};
/**
* Returns a string which can be supplied to `wrap()` to notify the user that a
* particular part of the sinon API has been deprecated.
*
* @param {string} packageName
* @param {string} funcName
* @returns {string}
*/
exports.defaultMsg = function (packageName, funcName) {
return `${packageName}.${funcName} is deprecated and will be removed from the public API in a future version of ${packageName}.`;
};
/**
* Prints a warning on the console, when it exists
*
* @param {string} msg
* @returns {undefined}
*/
exports.printWarning = function (msg) {
/* istanbul ignore next */
if (typeof process === "object" && process.emitWarning) {
// Emit Warnings in Node
process.emitWarning(msg);
} else if (console.info) {
console.info(msg);
} else {
console.log(msg);
}
};
} (deprecated));
/**
* Returns true when fn returns true for all members of obj.
* This is an every implementation that works for all iterables
*
* @param {object} obj
* @param {Function} fn
* @returns {boolean}
*/
var every = function every(obj, fn) {
var pass = true;
try {
// eslint-disable-next-line @sinonjs/no-prototype-methods/no-prototype-methods
obj.forEach(function () {
if (!fn.apply(this, arguments)) {
// Throwing an error is the only way to break `forEach`
throw new Error();
}
});
} catch (e) {
pass = false;
}
return pass;
};
var sort = array.sort;
var slice = array.slice;
/**
* @private
*/
function comparator(a, b) {
// uuid, won't ever be equal
var aCall = a.getCall(0);
var bCall = b.getCall(0);
var aId = (aCall && aCall.callId) || -1;
var bId = (bCall && bCall.callId) || -1;
return aId < bId ? -1 : 1;
}
/**
* A Sinon proxy object (fake, spy, stub)
*
* @typedef {object} SinonProxy
* @property {Function} getCall - A method that can return the first call
*/
/**
* Sorts an array of SinonProxy instances (fake, spy, stub) by their first call
*
* @param {SinonProxy[] | SinonProxy} spies
* @returns {SinonProxy[]}
*/
function orderByFirstCall(spies) {
return sort(slice(spies), comparator);
}
var orderByFirstCall_1 = orderByFirstCall;
var copyPrototype$4 = copyPrototypeMethods;
var _function = copyPrototype$4(Function.prototype);
var copyPrototype$3 = copyPrototypeMethods;
var map = copyPrototype$3(Map.prototype);
var copyPrototype$2 = copyPrototypeMethods;
var object = copyPrototype$2(Object.prototype);
var copyPrototype$1 = copyPrototypeMethods;
var set = copyPrototype$1(Set.prototype);
var copyPrototype = copyPrototypeMethods;
var string = copyPrototype(String.prototype);
var prototypes = {
array: array,
function: _function,
map: map,
object: object,
set: set,
string: string,
};
var typeDetect = {exports: {}};
(function (module, exports) {
(function (global, factory) {
module.exports = factory() ;
}(commonjsGlobal, (function () {
/* !
* type-detect
* Copyright(c) 2013 jake luer <jake@alogicalparadox.com>
* MIT Licensed
*/
var promiseExists = typeof Promise === 'function';
/* eslint-disable no-undef */
var globalObject = typeof self === 'object' ? self : commonjsGlobal; // eslint-disable-line id-blacklist
var symbolExists = typeof Symbol !== 'undefined';
var mapExists = typeof Map !== 'undefined';
var setExists = typeof Set !== 'undefined';
var weakMapExists = typeof WeakMap !== 'undefined';
var weakSetExists = typeof WeakSet !== 'undefined';
var dataViewExists = typeof DataView !== 'undefined';
var symbolIteratorExists = symbolExists && typeof Symbol.iterator !== 'undefined';
var symbolToStringTagExists = symbolExists && typeof Symbol.toStringTag !== 'undefined';
var setEntriesExists = setExists && typeof Set.prototype.entries === 'function';
var mapEntriesExists = mapExists && typeof Map.prototype.entries === 'function';
var setIteratorPrototype = setEntriesExists && Object.getPrototypeOf(new Set().entries());
var mapIteratorPrototype = mapEntriesExists && Object.getPrototypeOf(new Map().entries());
var arrayIteratorExists = symbolIteratorExists && typeof Array.prototype[Symbol.iterator] === 'function';
var arrayIteratorPrototype = arrayIteratorExists && Object.getPrototypeOf([][Symbol.iterator]());
var stringIteratorExists = symbolIteratorExists && typeof String.prototype[Symbol.iterator] === 'function';
var stringIteratorPrototype = stringIteratorExists && Object.getPrototypeOf(''[Symbol.iterator]());
var toStringLeftSliceLength = 8;
var toStringRightSliceLength = -1;
/**
* ### typeOf (obj)
*
* Uses `Object.prototype.toString` to determine the type of an object,
* normalising behaviour across engine versions & well optimised.
*
* @param {Mixed} object
* @return {String} object type
* @api public
*/
function typeDetect(obj) {
/* ! Speed optimisation
* Pre:
* string literal x 3,039,035 ops/sec ±1.62% (78 runs sampled)
* boolean literal x 1,424,138 ops/sec ±4.54% (75 runs sampled)
* number literal x 1,653,153 ops/sec ±1.91% (82 runs sampled)
* undefined x 9,978,660 ops/sec ±1.92% (75 runs sampled)
* function x 2,556,769 ops/sec ±1.73% (77 runs sampled)
* Post:
* string literal x 38,564,796 ops/sec ±1.15% (79 runs sampled)
* boolean literal x 31,148,940 ops/sec ±1.10% (79 runs sampled)
* number literal x 32,679,330 ops/sec ±1.90% (78 runs sampled)
* undefined x 32,363,368 ops/sec ±1.07% (82 runs sampled)
* function x 31,296,870 ops/sec ±0.96% (83 runs sampled)
*/
var typeofObj = typeof obj;
if (typeofObj !== 'object') {
return typeofObj;
}
/* ! Speed optimisation
* Pre:
* null x 28,645,765 ops/sec ±1.17% (82 runs sampled)
* Post:
* null x 36,428,962 ops/sec ±1.37% (84 runs sampled)
*/
if (obj === null) {
return 'null';
}
/* ! Spec Conformance
* Test: `Object.prototype.toString.call(window)``
* - Node === "[object global]"
* - Chrome === "[object global]"
* - Firefox === "[object Window]"
* - PhantomJS === "[object Window]"
* - Safari === "[object Window]"
* - IE 11 === "[object Window]"
* - IE Edge === "[object Window]"
* Test: `Object.prototype.toString.call(this)``
* - Chrome Worker === "[object global]"
* - Firefox Worker === "[object DedicatedWorkerGlobalScope]"
* - Safari Worker === "[object DedicatedWorkerGlobalScope]"
* - IE 11 Worker === "[object WorkerGlobalScope]"
* - IE Edge Worker === "[object WorkerGlobalScope]"
*/
if (obj === globalObject) {
return 'global';
}
/* ! Speed optimisation
* Pre:
* array literal x 2,888,352 ops/sec ±0.67% (82 runs sampled)
* Post:
* array literal x 22,479,650 ops/sec ±0.96% (81 runs sampled)
*/
if (
Array.isArray(obj) &&
(symbolToStringTagExists === false || !(Symbol.toStringTag in obj))
) {
return 'Array';
}
// Not caching existence of `window` and related properties due to potential
// for `window` to be unset before tests in quasi-browser environments.
if (typeof window === 'object' && window !== null) {
/* ! Spec Conformance
* (https://html.spec.whatwg.org/multipage/browsers.html#location)
* WhatWG HTML$7.7.3 - The `Location` interface
* Test: `Object.prototype.toString.call(window.location)``
* - IE <=11 === "[object Object]"
* - IE Edge <=13 === "[object Object]"
*/
if (typeof window.location === 'object' && obj === window.location) {
return 'Location';
}
/* ! Spec Conformance
* (https://html.spec.whatwg.org/#document)
* WhatWG HTML$3.1.1 - The `Document` object
* Note: Most browsers currently adher to the W3C DOM Level 2 spec
* (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-26809268)
* which suggests that browsers should use HTMLTableCellElement for
* both TD and TH elements. WhatWG separates these.
* WhatWG HTML states:
* > For historical reasons, Window objects must also have a
* > writable, configurable, non-enumerable property named
* > HTMLDocument whose value is the Document interface object.
* Test: `Object.prototype.toString.call(document)``
* - Chrome === "[object HTMLDocument]"
* - Firefox === "[object HTMLDocument]"
* - Safari === "[object HTMLDocument]"
* - IE <=10 === "[object Document]"
* - IE 11 === "[object HTMLDocument]"
* - IE Edge <=13 === "[object HTMLDocument]"
*/
if (typeof window.document === 'object' && obj === window.document) {
return 'Document';
}
if (typeof window.navigator === 'object') {
/* ! Spec Conformance
* (https://html.spec.whatwg.org/multipage/webappapis.html#mimetypearray)
* WhatWG HTML$8.6.1.5 - Plugins - Interface MimeTypeArray
* Test: `Object.prototype.toString.call(navigator.mimeTypes)``
* - IE <=10 === "[object MSMimeTypesCollection]"
*/
if (typeof window.navigator.mimeTypes === 'object' &&
obj === window.navigator.mimeTypes) {
return 'MimeTypeArray';
}
/* ! Spec Conformance
* (https://html.spec.whatwg.org/multipage/webappapis.html#pluginarray)
* WhatWG HTML$8.6.1.5 - Plugins - Interface PluginArray
* Test: `Object.prototype.toString.call(navigator.plugins)``
* - IE <=10 === "[object MSPluginsCollection]"
*/
if (typeof window.navigator.plugins === 'object' &&
obj === window.navigator.plugins) {
return 'PluginArray';
}
}
if ((typeof window.HTMLElement === 'function' ||
typeof window.HTMLElement === 'object') &&
obj instanceof window.HTMLElement) {
/* ! Spec Conformance
* (https://html.spec.whatwg.org/multipage/webappapis.html#pluginarray)
* WhatWG HTML$4.4.4 - The `blockquote` element - Interface `HTMLQuoteElement`
* Test: `Object.prototype.toString.call(document.createElement('blockquote'))``
* - IE <=10 === "[object HTMLBlockElement]"
*/
if (obj.tagName === 'BLOCKQUOTE') {
return 'HTMLQuoteElement';
}
/* ! Spec Conformance
* (https://html.spec.whatwg.org/#htmltabledatacellelement)
* WhatWG HTML$4.9.9 - The `td` element - Interface `HTMLTableDataCellElement`
* Note: Most browsers currently adher to the W3C DOM Level 2 spec
* (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-82915075)
* which suggests that browsers should use HTMLTableCellElement for
* both TD and TH elements. WhatWG separates these.
* Test: Object.prototype.toString.call(document.createElement('td'))
* - Chrome === "[object HTMLTableCellElement]"
* - Firefox === "[object HTMLTableCellElement]"
* - Safari === "[object HTMLTableCellElement]"
*/
if (obj.tagName === 'TD') {
return 'HTMLTableDataCellElement';
}
/* ! Spec Conformance
* (https://html.spec.whatwg.org/#htmltableheadercellelement)
* WhatWG HTML$4.9.9 - The `td` element - Interface `HTMLTableHeaderCellElement`
* Note: Most browsers currently adher to the W3C DOM Level 2 spec
* (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-82915075)
* which suggests that browsers should use HTMLTableCellElement for
* both TD and TH elements. WhatWG separates these.
* Test: Object.prototype.toString.call(document.createElement('th'))
* - Chrome === "[object HTMLTableCellElement]"
* - Firefox === "[object HTMLTableCellElement]"
* - Safari === "[object HTMLTableCellElement]"
*/
if (obj.tagName === 'TH') {
return 'HTMLTableHeaderCellElement';
}
}
}
/* ! Speed optimisation
* Pre:
* Float64Array x 625,644 ops/sec ±1.58% (80 runs sampled)
* Float32Array x 1,279,852 ops/sec ±2.91% (77 runs sampled)
* Uint32Array x 1,178,185 ops/sec ±1.95% (83 runs sampled)
* Uint16Array x 1,008,380 ops/sec ±2.25% (80 runs sampled)
* Uint8Array x 1,128,040 ops/sec ±2.11% (81 runs sampled)
* Int32Array x 1,170,119 ops/sec ±2.88% (80 runs sampled)
* Int16Array x 1,176,348 ops/sec ±5.79% (86 runs sampled)
* Int8Array x 1,058,707 ops/sec ±4.94% (77 runs sampled)
* Uint8ClampedArray x 1,110,633 ops/sec ±4.20% (80 runs sampled)
* Post:
* Float64Array x 7,105,671 ops/sec ±13.47% (64 runs sampled)
* Float32Array x 5,887,912 ops/sec ±1.46% (82 runs sampled)
* Uint32Array x 6,491,661 ops/sec ±1.76% (79 runs sampled)
* Uint16Array x 6,559,795 ops/sec ±1.67% (82 runs sampled)
* Uint8Array x 6,463,966 ops/sec ±1.43% (85 runs sampled)
* Int32Array x 5,641,841 ops/sec ±3.49% (81 runs sampled)
* Int16Array x 6,583,511 ops/sec ±1.98% (80 runs sampled)
* Int8Array x 6,606,078 ops/sec ±1.74% (81 runs sampled)
* Uint8ClampedArray x 6,602,224 ops/sec ±1.77% (83 runs sampled)
*/
var stringTag = (symbolToStringTagExists && obj[Symbol.toStringTag]);
if (typeof stringTag === 'string') {
return stringTag;
}
var objPrototype = Object.getPrototypeOf(obj);
/* ! Speed optimisation
* Pre:
* regex literal x 1,772,385 ops/sec ±1.85% (77 runs sampled)
* regex constructor x 2,143,634 ops/sec ±2.46% (78 runs sampled)
* Post:
* regex literal x 3,928,009 ops/sec ±0.65% (78 runs sampled)
* regex constructor x 3,931,108 ops/sec ±0.58% (84 runs sampled)
*/
if (objPrototype === RegExp.prototype) {
return 'RegExp';
}
/* ! Speed optimisation
* Pre:
* date x 2,130,074 ops/sec ±4.42% (68 runs sampled)
* Post:
* date x 3,953,779 ops/sec ±1.35% (77 runs sampled)
*/
if (objPrototype === Date.prototype) {
return 'Date';
}
/* ! Spec Conformance
* (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-promise.prototype-@@tostringtag)
* ES6$25.4.5.4 - Promise.prototype[@@toStringTag] should be "Promise":
* Test: `Object.prototype.toString.call(Promise.resolve())``
* - Chrome <=47 === "[object Object]"
* - Edge <=20 === "[object Object]"
* - Firefox 29-Latest === "[object Promise]"
* - Safari 7.1-Latest === "[object Promise]"
*/
if (promiseExists && objPrototype === Promise.prototype) {
return 'Promise';
}
/* ! Speed optimisation
* Pre:
* set x 2,222,186 ops/sec ±1.31% (82 runs sampled)
* Post:
* set x 4,545,879 ops/sec ±1.13% (83 runs sampled)
*/
if (setExists && objPrototype === Set.prototype) {
return 'Set';
}
/* ! Speed optimisation
* Pre:
* map x 2,396,842 ops/sec ±1.59% (81 runs sampled)
* Post:
* map x 4,183,945 ops/sec ±6.59% (82 runs sampled)
*/
if (mapExists && objPrototype === Map.prototype) {
return 'Map';
}
/* ! Speed optimisation
* Pre:
* weakset x 1,323,220 ops/sec ±2.17% (76 runs sampled)
* Post:
* weakset x 4,237,510 ops/sec ±2.01% (77 runs sampled)
*/
if (weakSetExists && objPrototype === WeakSet.prototype) {
return 'WeakSet';
}
/* ! Speed optimisation
* Pre:
* weakmap x 1,500,260 ops/sec ±2.02% (78 runs sampled)
* Post:
* weakmap x 3,881,384 ops/sec ±1.45% (82 runs sampled)
*/
if (weakMapExists && objPrototype === WeakMap.prototype) {
return 'WeakMap';
}
/* ! Spec Conformance
* (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-dataview.prototype-@@tostringtag)
* ES6$24.2.4.21 - DataView.prototype[@@toStringTag] should be "DataView":
* Test: `Object.prototype.toString.call(new DataView(new ArrayBuffer(1)))``
* - Edge <=13 === "[object Object]"
*/
if (dataViewExists && objPrototype === DataView.prototype) {
return 'DataView';
}
/* ! Spec Conformance
* (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%mapiteratorprototype%-@@tostringtag)
* ES6$23.1.5.2.2 - %MapIteratorPrototype%[@@toStringTag] should be "Map Iterator":
* Test: `Object.prototype.toString.call(new Map().entries())``
* - Edge <=13 === "[object Object]"
*/
if (mapExists && objPrototype === mapIteratorPrototype) {
return 'Map Iterator';
}
/* ! Spec Conformance
* (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%setiteratorprototype%-@@tostringtag)
* ES6$23.2.5.2.2 - %SetIteratorPrototype%[@@toStringTag] should be "Set Iterator":
* Test: `Object.prototype.toString.call(new Set().entries())``
* - Edge <=13 === "[object Object]"
*/
if (setExists && objPrototype === setIteratorPrototype) {
return 'Set Iterator';
}
/* ! Spec Conformance
* (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%arrayiteratorprototype%-@@tostringtag)
* ES6$22.1.5.2.2 - %ArrayIteratorPrototype%[@@toStringTag] should be "Array Iterator":
* Test: `Object.prototype.toString.call([][Symbol.iterator]())``
* - Edge <=13 === "[object Object]"
*/
if (arrayIteratorExists && objPrototype === arrayIteratorPrototype) {
return 'Array Iterator';
}
/* ! Spec Conformance
* (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%stringiteratorprototype%-@@tostringtag)
* ES6$21.1.5.2.2 - %StringIteratorPrototype%[@@toStringTag] should be "String Iterator":
* Test: `Object.prototype.toString.call(''[Symbol.iterator]())``
* - Edge <=13 === "[object Object]"
*/
if (stringIteratorExists && objPrototype === stringIteratorPrototype) {
return 'String Iterator';
}
/* ! Speed optimisation
* Pre:
* object from null x 2,424,320 ops/sec ±1.67% (76 runs sampled)
* Post:
* object from null x 5,838,000 ops/sec ±0.99% (84 runs sampled)
*/
if (objPrototype === null) {
return 'Object';
}
return Object
.prototype
.toString
.call(obj)
.slice(toStringLeftSliceLength, toStringRightSliceLength);
}
return typeDetect;
})));
} (typeDetect));
var typeDetectExports = typeDetect.exports;
var type = typeDetectExports;
/**
* Returns the lower-case result of running type from type-detect on the value
*
* @param {*} value
* @returns {string}
*/
var typeOf = function typeOf(value) {
return type(value).toLowerCase();
};
/**
* Returns a string representation of the value
*
* @param {*} value
* @returns {string}
*/
function valueToString(value) {
if (value && value.toString) {
// eslint-disable-next-line @sinonjs/no-prototype-methods/no-prototype-methods
return value.toString();
}
return String(value);
}
var valueToString_1 = valueToString;
var lib = {
global: global,
calledInOrder: calledInOrder_1,
className: className_1,
deprecated: deprecated,
every: every,
functionName: functionName$1,
orderByFirstCall: orderByFirstCall_1,
prototypes: prototypes,
typeOf: typeOf,
valueToString: valueToString_1,
};
const globalObject = lib.global;
let timersModule;
if (typeof __vitest_required__ !== 'undefined') {
try {
timersModule = __vitest_required__.timers;
} catch (e) {
// ignored
}
}
/**
* @typedef {object} IdleDeadline
* @property {boolean} didTimeout - whether or not the callback was called before reaching the optional timeout
* @property {function():number} timeRemaining - a floating-point value providing an estimate of the number of milliseconds remaining in the current idle period
*/
/**
* Queues a function to be called during a browser's idle periods
*
* @callback RequestIdleCallback
* @param {function(IdleDeadline)} callback
* @param {{timeout: number}} options - an options object
* @returns {number} the id
*/
/**
* @callback NextTick
* @param {VoidVarArgsFunc} callback - the callback to run
* @param {...*} arguments - optional arguments to call the callback with
* @returns {void}
*/
/**
* @callback SetImmediate
* @param {VoidVarArgsFunc} callback - the callback to run
* @param {...*} arguments - optional arguments to call the callback with
* @returns {NodeImmediate}
*/
/**
* @callback VoidVarArgsFunc
* @param {...*} callback - the callback to run
* @returns {void}
*/
/**
* @typedef RequestAnimationFrame
* @property {function(number):void} requestAnimationFrame
* @returns {number} - the id
*/
/**
* @typedef Performance
* @property {function(): number} now
*/
/* eslint-disable jsdoc/require-property-description */
/**
* @typedef {object} Clock
* @property {number} now - the current time
* @property {Date} Date - the Date constructor
* @property {number} loopLimit - the maximum number of timers before assuming an infinite loop
* @property {RequestIdleCallback} requestIdleCallback
* @property {function(number):void} cancelIdleCallback
* @property {setTimeout} setTimeout
* @property {clearTimeout} clearTimeout
* @property {NextTick} nextTick
* @property {queueMicrotask} queueMicrotask
* @property {setInterval} setInterval
* @property {clearInterval} clearInterval
* @property {SetImmediate} setImmediate
* @property {function(NodeImmediate):void} clearImmediate
* @property {function():number} countTimers
* @property {RequestAnimationFrame} requestAnimationFrame
* @property {function(number):void} cancelAnimationFrame
* @property {function():void} runMicrotasks
* @property {function(string | number): number} tick
* @property {function(string | number): Promise<number>} tickAsync
* @property {function(): number} next
* @property {function(): Promise<number>} nextAsync
* @property {function(): number} runAll
* @property {function(): number} runToFrame
* @property {function(): Promise<number>} runAllAsync
* @property {function(): number} runToLast
* @property {function(): Promise<number>} runToLastAsync
* @property {function(): void} reset
* @property {function(number | Date): void} setSystemTime
* @property {function(number): void} jump
* @property {Performance} performance
* @property {function(number[]): number[]} hrtime - process.hrtime (legacy)
* @property {function(): void} uninstall Uninstall the clock.
* @property {Function[]} methods - the methods that are faked
* @property {boolean} [shouldClearNativeTimers] inherited from config
* @property {{methodName:string, original:any}[] | undefined} timersModuleMethods
*/
/* eslint-enable jsdoc/require-property-description */
/**
* Configuration object for the `install` method.
*
* @typedef {object} Config
* @property {number|Date} [now] a number (in milliseconds) or a Date object (default epoch)
* @property {string[]} [toFake] names of the methods that should be faked.
* @property {number} [loopLimit] the maximum number of timers that will be run when calling runAll()
* @property {boolean} [shouldAdvanceTime] tells FakeTimers to increment mocked time automatically (default false)
* @property {number} [advanceTimeDelta] increment mocked time every <<advanceTimeDelta>> ms (default: 20ms)
* @property {boolean} [shouldClearNativeTimers] forwards clear timer calls to native functions if they are not fakes (default: false)
*/
/* eslint-disable jsdoc/require-property-description */
/**
* The internal structure to describe a scheduled fake timer
*
* @typedef {object} Timer
* @property {Function} func
* @property {*[]} args
* @property {number} delay
* @property {number} callAt
* @property {number} createdAt
* @property {boolean} immediate
* @property {number} id
* @property {Error} [error]
*/
/**
* A Node timer
*
* @typedef {object} NodeImmediate
* @property {function(): boolean} hasRef
* @property {function(): NodeImmediate} ref
* @property {function(): NodeImmediate} unref
*/
/* eslint-enable jsdoc/require-property-description */
/* eslint-disable complexity */
/**
* Mocks available features in the specified global namespace.
*
* @param {*} _global Namespace to mock (e.g. `window`)
* @returns {FakeTimers}
*/
function withGlobal(_global) {
const maxTimeout = Math.pow(2, 31) - 1; //see https://heycam.github.io/webidl/#abstract-opdef-converttoint
const idCounterStart = 1e12; // arbitrarily large number to avoid collisions with native timer IDs
const NOOP = function () {
return undefined;
};
const NOOP_ARRAY = function () {
return [];
};
const timeoutResult = _global.setTimeout(NOOP, 0);
const addTimerReturnsObject = typeof timeoutResult === "object";
const hrtimePresent =
_global.process && typeof _global.process.hrtime === "function";
const hrtimeBigintPresent =
hrtimePresent && typeof _global.process.hrtime.bigint === "function";
const nextTickPresent =
_global.process && typeof _global.process.nextTick === "function";
const utilPromisify = _global.process && _global.__vitest_required__ && _global.__vitest_required__.util.promisify;
const performancePresent =
_global.performance && typeof _global.performance.now === "function";
const hasPerformancePrototype =
_global.Performance &&
(typeof _global.Performance).match(/^(function|object)$/);
const hasPerformanceConstructorPrototype =
_global.performance &&
_global.performance.constructor &&
_global.performance.constructor.prototype;
const queueMicrotaskPresent = _global.hasOwnProperty("queueMicrotask");
const requestAnimationFramePresent =
_global.requestAnimationFrame &&
typeof _global.requestAnimationFrame === "function";
const cancelAnimationFramePresent =
_global.cancelAnimationFrame &&
typeof _global.cancelAnimationFrame === "function";
const requestIdleCallbackPresent =
_global.requestIdleCallback &&
typeof _global.requestIdleCallback === "function";
const cancelIdleCallbackPresent =
_global.cancelIdleCallback &&
typeof _global.cancelIdleCallback === "function";
const setImmediatePresent =
_global.setImmediate && typeof _global.setImmediate === "function";
const intlPresent = _global.Intl && typeof _global.Intl === "object";
_global.clearTimeout(timeoutResult);
const NativeDate = _global.Date;
const NativeIntl = _global.Intl;
let uniqueTimerId = idCounterStart;
/**
* @param {number} num
* @returns {boolean}
*/
function isNumberFinite(num) {
if (Number.isFinite) {
return Number.isFinite(num);
}
return isFinite(num);
}
let isNearInfiniteLimit = false;
/**
* @param {Clock} clock
* @param {number} i
*/
function checkIsNearInfiniteLimit(clock, i) {
if (clock.loopLimit && i === clock.loopLimit - 1) {
isNearInfiniteLimit = true;
}
}
/**
*
*/
function resetIsNearInfiniteLimit() {
isNearInfiniteLimit = false;
}
/**
* Parse strings like "01:10:00" (meaning 1 hour, 10 minutes, 0 seconds) into
* number of milliseconds. This is used to support human-readable strings passed
* to clock.tick()
*
* @param {string} str
* @returns {number}
*/
function parseTime(str) {
if (!str) {
return 0;
}
const strings = str.split(":");
const l = strings.length;
let i = l;
let ms = 0;
let parsed;
if (l > 3 || !/^(\d\d:){0,2}\d\d?$/.test(str)) {
throw new Error(
"tick only understands numbers, 'm:s' and 'h:m:s'. Each part must be two digits"
);
}
while (i--) {
parsed = parseInt(strings[i], 10);
if (parsed >= 60) {
throw new Error(`Invalid time ${str}`);
}
ms += parsed * Math.pow(60, l - i - 1);
}
return ms * 1000;
}
/**
* Get the decimal part of the millisecond value as nanoseconds
*
* @param {number} msFloat the number of milliseconds
* @returns {number} an integer number of nanoseconds in the range [0,1e6)
*
* Example: nanoRemainer(123.456789) -> 456789
*/
function nanoRemainder(msFloat) {
const modulo = 1e6;
const remainder = (msFloat * 1e6) % modulo;
const positiveRemainder =
remainder < 0 ? remainder + modulo : remainder;
return Math.floor(positiveRemainder);
}
/**
* Used to grok the `now` parameter to createClock.
*
* @param {Date|number} epoch the system time
* @returns {number}
*/
function getEpoch(epoch) {
if (!epoch) {
return 0;
}
if (typeof epoch.getTime === "function") {
return epoch.getTime();
}
if (typeof epoch === "number") {
return epoch;
}
throw new TypeError("now should be milliseconds since UNIX epoch");
}
/**
* @param {number} from
* @param {number} to
* @param {Timer} timer
* @returns {boolean}
*/
function inRange(from, to, timer) {
return timer && timer.callAt >= from && timer.callAt <= to;
}
/**
* @param {Clock} clock
* @param {Timer} job
*/
function getInfiniteLoopError(clock, job) {
const infiniteLoopError = new Error(
`Aborting after running ${clock.loopLimit} timers, assuming an infinite loop!`
);
if (!job.error) {
return infiniteLoopError;
}
// pattern never matched in Node
const computedTargetPattern = /target\.*[<|(|[].*?[>|\]|)]\s*/;
let clockMethodPattern = new RegExp(
String(Object.keys(clock).join("|"))
);
if (addTimerReturnsObject) {
// node.js environment
clockMethodPattern = new RegExp(
`\\s+at (Object\\.)?(?:${Object.keys(clock).join("|")})\\s+`
);
}
let matchedLineIndex = -1;
job.error.stack.split("\n").some(function (line, i) {
// If we've matched a computed target line (e.g. setTimeout) then we
// don't need to look any further. Return true to stop iterating.
const matchedComputedTarget = line.match(computedTargetPattern);
/* istanbul ignore if */
if (matchedComputedTarget) {
matchedLineIndex = i;
return true;
}
// If we've matched a clock method line, then there may still be
// others further down the trace. Return false to keep iterating.
const matchedClockMethod = line.match(clockMethodPattern);
if (matchedClockMethod) {
matchedLineIndex = i;
return false;
}
// If we haven't matched anything on this line, but we matched
// previously and set the matched line index, then we can stop.
// If we haven't matched previously, then we should keep iterating.
return matchedLineIndex >= 0;
});
const stack = `${infiniteLoopError}\n${job.type || "Microtask"} - ${
job.func.name || "anonymous"
}\n${job.error.stack
.split("\n")
.slice(matchedLineIndex + 1)
.join("\n")}`;
try {
Object.defineProperty(infiniteLoopError, "stack", {
value: stack,
});
} catch (e) {
// noop
}
return infiniteLoopError;
}
/**
* @param {Date} target
* @param {Date} source
* @returns {Date} the target after modifications
*/
function mirrorDateProperties(target, source) {
let prop;
for (prop in source) {
if (source.hasOwnProperty(prop)) {
target[prop] = source[prop];
}
}
// set special now implementation
if (source.now) {
target.now = function now() {
return target.clock.now;
};
} else {
delete target.now;
}
// set special toSource implementation
if (source.toSource) {
target.toSource = function toSource() {
return source.toSource();
};
} else {
delete target.toSource;
}
// set special toString implementation
target.toString = function toString() {
return source.toString();
};
target.prototype = source.prototype;
target.parse = source.parse;
target.UTC = source.UTC;
target.prototype.toUTCString = source.prototype.toUTCString;
target.isFake = true;
return target;
}
//eslint-disable-next-line jsdoc/require-jsdoc
function createDate() {
/**
* @param {number} year
* @param {number} month
* @param {number} date
* @param {number} hour
* @param {number} minute
* @param {number} second
* @param {number} ms
* @returns {Date}
*/
function ClockDate(year, month, date, hour, minute, second, ms) {
// the Date constructor called as a function, ref Ecma-262 Edition 5.1, section 15.9.2.
// This remains so in the 10th edition of 2019 as well.
if (!(this instanceof ClockDate)) {
return new NativeDate(ClockDate.clock.now).toString();
}
// if Date is called as a constructor with 'new' keyword
// Defensive and verbose to avoid potential harm in passing
// explicit undefined when user does not pass argument
switch (arguments.length) {
case 0:
return new NativeDate(ClockDate.clock.now);
case 1:
return new NativeDate(year);
case 2:
return new NativeDate(year, month);
case 3:
return new NativeDate(year, month, date);
case 4:
return new NativeDate(year, month, date, hour);
case 5:
return new NativeDate(year, month, date, hour, minute);
case 6:
return new NativeDate(
year,
month,
date,
hour,
minute,
second
);
default:
return new NativeDate(
year,
month,
date,
hour,
minute,
second,
ms
);
}
}
return mirrorDateProperties(ClockDate, NativeDate);
}
//eslint-disable-next-line jsdoc/require-jsdoc
function createIntl() {
const ClockIntl = { ...NativeIntl };
ClockIntl.DateTimeFormat = function (...args) {
const realFormatter = new NativeIntl.DateTimeFormat(...args);
const formatter = {};
["formatRange", "formatRangeToParts", "resolvedOptions"].forEach(
(method) => {
formatter[method] =
realFormatter[method].bind(realFormatter);
}
);
["format", "formatToParts"].forEach((method) => {
formatter[method] = function (date) {
return realFormatter[method](date || ClockIntl.clock.now);
};
});
return formatter;
};
ClockIntl.DateTimeFormat.prototype = Object.create(
NativeIntl.DateTimeFormat.prototype
);
ClockIntl.DateTimeFormat.supportedLocalesOf =
NativeIntl.DateTimeFormat.supportedLocalesOf;
return ClockIntl;
}
//eslint-disable-next-line jsdoc/require-jsdoc
function enqueueJob(clock, job) {
// enqueues a microtick-deferred task - ecma262/#sec-enqueuejob
if (!clock.jobs) {
clock.jobs = [];
}
clock.jobs.push(job);
}
//eslint-disable-next-line jsdoc/require-jsdoc
function runJobs(clock) {
// runs all microtick-deferred tasks - ecma262/#sec-runjobs
if (!clock.jobs) {
return;
}
for (let i = 0; i < clock.jobs.length; i++) {
const job = clock.jobs[i];
job.func.apply(null, job.args);
checkIsNearInfiniteLimit(clock, i);
if (clock.loopLimit && i > clock.loopLimit) {
throw getInfiniteLoopError(clock, job);
}
}
resetIsNearInfiniteLimit();
clock.jobs = [];
}
/**
* @param {Clock} clock
* @param {Timer} timer
* @returns {number} id of the created timer
*/
function addTimer(clock, timer) {
if (timer.func === undefined) {
throw new Error("Callback must be provided to timer calls");
}
if (addTimerReturnsObject) {
// Node.js environment
if (typeof timer.func !== "function") {
throw new TypeError(
`[ERR_INVALID_CALLBACK]: Callback must be a function. Received ${
timer.func
} of type ${typeof timer.func}`
);
}
}
if (isNearInfiniteLimit) {
timer.error = new Error();
}
timer.type = timer.immediate ? "Immediate" : "Timeout";
if (timer.hasOwnProperty("delay")) {
if (typeof timer.delay !== "number") {
timer.delay = parseInt(timer.delay, 10);
}
if (!isNumberFinite(timer.delay)) {
timer.delay = 0;
}
timer.delay = timer.delay > maxTimeout ? 1 : timer.delay;
timer.delay = Math.max(0, timer.delay);
}
if (timer.hasOwnProperty("interval")) {
timer.type = "Interval";
timer.interval = timer.interval > maxTimeout ? 1 : timer.interval;
}
if (timer.hasOwnProperty("animation")) {
timer.type = "AnimationFrame";
timer.animation = true;
}
if (timer.hasOwnProperty("idleCallback")) {
timer.type = "IdleCallback";
timer.idleCallback = true;
}
if (!clock.timers) {
clock.timers = {};
}
timer.id = uniqueTimerId++;
timer.createdAt = clock.now;
timer.callAt =
clock.now + (parseInt(timer.delay) || (clock.duringTick ? 1 : 0));
clock.timers[timer.id] = timer;
if (addTimerReturnsObject) {
const res = {
refed: true,
ref: function () {
this.refed = true;
return res;
},
unref: function () {
this.refed = false;
return res;
},
hasRef: function () {
return this.refed;
},
refresh: function () {
timer.callAt =
clock.now +
(parseInt(timer.delay) || (clock.duringTick ? 1 : 0));
// it _might_ have been removed, but if not the assignment is perfectly fine
clock.timers[timer.id] = timer;
return res;
},
[Symbol.toPrimitive]: function () {
return timer.id;
},
};
return res;
}
return timer.id;
}
/* eslint consistent-return: "off" */
/**
* Timer comparitor
*
* @param {Timer} a
* @param {Timer} b
* @returns {number}
*/
function compareTimers(a, b) {
// Sort first by absolute timing
if (a.callAt < b.callAt) {
return -1;
}
if (a.callAt > b.callAt) {
return 1;
}
// Sort next by immediate, immediate timers take precedence
if (a.immediate && !b.immediate) {
return -1;
}
if (!a.immediate && b.immediate) {
return 1;
}
// Sort next by creation time, earlier-created timers take precedence
if (a.createdAt < b.createdAt) {
return -1;
}
if (a.createdAt > b.createdAt) {
return 1;
}
// Sort next by id, lower-id timers take precedence
if (a.id < b.id) {
return -1;
}
if (a.id > b.id) {
return 1;
}
// As timer ids are unique, no fallback `0` is necessary
}
/**
* @param {Clock} clock
* @param {number} from
* @param {number} to
* @returns {Timer}
*/
function firstTimerInRange(clock, from, to) {
const timers = clock.timers;
let timer = null;
let id, isInRange;
for (id in timers) {
if (timers.hasOwnProperty(id)) {
isInRange = inRange(from, to, timers[id]);
if (
isInRange &&
(!timer || compareTimers(timer, timers[id]) === 1)
) {
timer = timers[id];
}
}
}
return timer;
}
/**
* @param {Clock} clock
* @returns {Timer}
*/
function firstTimer(clock) {
const timers = clock.timers;
let timer = null;
let id;
for (id in timers) {
if (timers.hasOwnProperty(id)) {
if (!timer || compareTimers(timer, timers[id]) === 1) {
timer = timers[id];
}
}
}
return timer;
}
/**
* @param {Clock} clock
* @returns {Timer}
*/
function lastTimer(clock) {
const timers = clock.timers;
let timer = null;
let id;
for (id in timers) {
if (timers.hasOwnProperty(id)) {
if (!timer || compareTimers(timer, timers[id]) === -1) {
timer = timers[id];
}
}
}
return timer;
}
/**
* @param {Clock} clock
* @param {Timer} timer
*/
function callTimer(clock, timer) {
if (typeof timer.interval === "number") {
clock.timers[timer.id].callAt += timer.interval;
} else {
delete clock.timers[timer.id];
}
if (typeof timer.func === "function") {
timer.func.apply(null, timer.args);
} else {
/* eslint no-eval: "off" */
const eval2 = eval;
(function () {
eval2(timer.func);
})();
}
}
/**
* Gets clear handler name for a given timer type
*
* @param {string} ttype
*/
function getClearHandler(ttype) {
if (ttype === "IdleCallback" || ttype === "AnimationFrame") {
return `cancel${ttype}`;
}
return `clear${ttype}`;
}
/**
* Gets schedule handler name for a given timer type
*
* @param {string} ttype
*/
function getScheduleHandler(ttype) {
if (ttype === "IdleCallback" || ttype === "AnimationFrame") {
return `request${ttype}`;
}
return `set${ttype}`;
}
/**
* Creates an anonymous function to warn only once
*/
function createWarnOnce() {
let calls = 0;
return function (msg) {
// eslint-disable-next-line
!calls++ && console.warn(msg);
};
}
const warnOnce = createWarnOnce();
/**
* @param {Clock} clock
* @param {number} timerId
* @param {string} ttype
*/
function clearTimer(clock, timerId, ttype) {
if (!timerId) {
// null appears to be allowed in most browsers, and appears to be
// relied upon by some libraries, like Bootstrap carousel
return;
}
if (!clock.timers) {
clock.timers = {};
}
// in Node, the ID is stored as the primitive value for `Timeout` objects
// for `Immediate` objects, no ID exists, so it gets coerced to NaN
const id = Number(timerId);
if (Number.isNaN(id) || id < idCounterStart) {
const handlerName = getClearHandler(ttype);
if (clock.shouldClearNativeTimers === true) {
const nativeHandler = clock[`_${handlerName}`];
return typeof nativeHandler === "function"
? nativeHandler(timerId)
: undefined;
}
warnOnce(
`FakeTimers: ${handlerName} was invoked to clear a native timer instead of one created by this library.` +
"\nTo automatically clean-up native timers, use `shouldClearNativeTimers`."
);
}
if (clock.timers.hasOwnProperty(id)) {
// check that the ID matches a timer of the correct type
const timer = clock.timers[id];
if (
timer.type === ttype ||
(timer.type === "Timeout" && ttype === "Interval") ||
(timer.type === "Interval" && ttype === "Timeout")
) {
delete clock.timers[id];
} else {
const clear = getClearHandler(ttype);
const schedule = getScheduleHandler(timer.type);
throw new Error(
`Cannot clear timer: timer created with ${schedule}() but cleared with ${clear}()`
);
}
}
}
/**
* @param {Clock} clock
* @param {Config} config
* @returns {Timer[]}
*/
function uninstall(clock, config) {
let method, i, l;
const installedHrTime = "_hrtime";
const installedNextTick = "_nextTick";
for (i = 0, l = clock.methods.length; i < l; i++) {
method = clock.methods[i];
if (method === "hrtime" && _global.process) {
_global.process.hrtime = clock[installedHrTime];
} else if (method === "nextTick" && _global.process) {
_global.process.nextTick = clock[installedNextTick];
} else if (method === "performance") {
const originalPerfDescriptor = Object.getOwnPropertyDescriptor(
clock,
`_${method}`
);
if (
originalPerfDescriptor &&
originalPerfDescriptor.get &&
!originalPerfDescriptor.set
) {
Object.defineProperty(
_global,
method,
originalPerfDescriptor
);
} else if (originalPerfDescriptor.configurable) {
_global[method] = clock[`_${method}`];
}
} else {
if (_global[method] && _global[method].hadOwnProperty) {
_global[method] = clock[`_${method}`];
} else {
try {
delete _global[method];
} catch (ignore) {
/* eslint no-empty: "off" */
}
}
}
if (clock.timersModuleMethods !== undefined) {
for (let j = 0; j < clock.timersModuleMethods.length; j++) {
const entry = clock.timersModuleMethods[j];
timersModule[entry.methodName] = entry.original;
}
}
}
if (config.shouldAdvanceTime === true) {
_global.clearInterval(clock.attachedInterval);
}
// Prevent multiple executions which will completely remove these props
clock.methods = [];
// return pending timers, to enable checking what timers remained on uninstall
if (!clock.timers) {
return [];
}
return Object.keys(clock.timers).map(function mapper(key) {
return clock.timers[key];
});
}
/**
* @param {object} target the target containing the method to replace
* @param {string} method the keyname of the method on the target
* @param {Clock} clock
*/
function hijackMethod(target, method, clock) {
clock[method].hadOwnProperty = Object.prototype.hasOwnProperty.call(
target,
method
);
clock[`_${method}`] = target[method];
if (method === "Date") {
const date = mirrorDateProperties(clock[method], target[method]);
target[method] = date;
} else if (method === "Intl") {
target[method] = clock[method];
} else if (method === "performance") {
const originalPerfDescriptor = Object.getOwnPropertyDescriptor(
target,
method
);
// JSDOM has a read only performance field so we have to save/copy it differently
if (
originalPerfDescriptor &&
originalPerfDescriptor.get &&
!originalPerfDescriptor.set
) {
Object.defineProperty(
clock,
`_${method}`,
originalPerfDescriptor
);
const perfDescriptor = Object.getOwnPropertyDescriptor(
clock,
method
);
Object.defineProperty(target, method, perfDescriptor);
} else {
target[method] = clock[method];
}
} else {
target[method] = function () {
return clock[method].apply(clock, arguments);
};
Object.defineProperties(
target[method],
Object.getOwnPropertyDescriptors(clock[method])
);
}
target[method].clock = clock;
}
/**
* @param {Clock} clock
* @param {number} advanceTimeDelta
*/
function doIntervalTick(clock, advanceTimeDelta) {
clock.tick(advanceTimeDelta);
}
/**
* @typedef {object} Timers
* @property {setTimeout} setTimeout
* @property {clearTimeout} clearTimeout
* @property {setInterval} setInterval
* @property {clearInterval} clearInterval
* @property {Date} Date
* @property {Intl} Intl
* @property {SetImmediate=} setImmediate
* @property {function(NodeImmediate): void=} clearImmediate
* @property {function(number[]):number[]=} hrtime
* @property {NextTick=} nextTick
* @property {Performance=} performance
* @property {RequestAnimationFrame=} requestAnimationFrame
* @property {boolean=} queueMicrotask
* @property {function(number): void=} cancelAnimationFrame
* @property {RequestIdleCallback=} requestIdleCallback
* @property {function(number): void=} cancelIdleCallback
*/
/** @type {Timers} */
const timers = {
setTimeout: _global.setTimeout,
clearTimeout: _global.clearTimeout,
setInterval: _global.setInterval,
clearInterval: _global.clearInterval,
Date: _global.Date,
};
if (setImmediatePresent) {
timers.setImmediate = _global.setImmediate;
timers.clearImmediate = _global.clearImmediate;
}
if (hrtimePresent) {
timers.hrtime = _global.process.hrtime;
}
if (nextTickPresent) {
timers.nextTick = _global.process.nextTick;
}
if (performancePresent) {
timers.performance = _global.performance;
}
if (requestAnimationFramePresent) {
timers.requestAnimationFrame = _global.requestAnimationFrame;
}
if (queueMicrotaskPresent) {
timers.queueMicrotask = true;
}
if (cancelAnimationFramePresent) {
timers.cancelAnimationFrame = _global.cancelAnimationFrame;
}
if (requestIdleCallbackPresent) {
timers.requestIdleCallback = _global.requestIdleCallback;
}
if (cancelIdleCallbackPresent) {
timers.cancelIdleCallback = _global.cancelIdleCallback;
}
if (intlPresent) {
timers.Intl = _global.Intl;
}
const originalSetTimeout = _global.setImmediate || _global.setTimeout;
/**
* @param {Date|number} [start] the system time - non-integer values are floored
* @param {number} [loopLimit] maximum number of timers that will be run when calling runAll()
* @returns {Clock}
*/
function createClock(start, loopLimit) {
// eslint-disable-next-line no-param-reassign
start = Math.floor(getEpoch(start));
// eslint-disable-next-line no-param-reassign
loopLimit = loopLimit || 1000;
let nanos = 0;
const adjustedSystemTime = [0, 0]; // [millis, nanoremainder]
if (NativeDate === undefined) {
throw new Error(
"The global scope doesn't have a `Date` object" +
" (see https://github.com/sinonjs/sinon/issues/1852#issuecomment-419622780)"
);
}
const clock = {
now: start,
Date: createDate(),
loopLimit: loopLimit,
};
clock.Date.clock = clock;
//eslint-disable-next-line jsdoc/require-jsdoc
function getTimeToNextFrame() {
return 16 - ((clock.now - start) % 16);
}
//eslint-disable-next-line jsdoc/require-jsdoc
function hrtime(prev) {
const millisSinceStart = clock.now - adjustedSystemTime[0] - start;
const secsSinceStart = Math.floor(millisSinceStart / 1000);
const remainderInNanos =
(millisSinceStart - secsSinceStart * 1e3) * 1e6 +
nanos -
adjustedSystemTime[1];
if (Array.isArray(prev)) {
if (prev[1] > 1e9) {
throw new TypeError(
"Number of nanoseconds can't exceed a billion"
);
}
const oldSecs = prev[0];
let nanoDiff = remainderInNanos - prev[1];
let secDiff = secsSinceStart - oldSecs;
if (nanoDiff < 0) {
nanoDiff += 1e9;
secDiff -= 1;
}
return [secDiff, nanoDiff];
}
return [secsSinceStart, remainderInNanos];
}
function fakePerformanceNow() {
const hrt = hrtime();
const millis = hrt[0] * 1000 + hrt[1] / 1e6;
return millis;
}
if (hrtimeBigintPresent) {
hrtime.bigint = function () {
const parts = hrtime();
return BigInt(parts[0]) * BigInt(1e9) + BigInt(parts[1]); // eslint-disable-line
};
}
if (intlPresent) {
clock.Intl = createIntl();
clock.Intl.clock = clock;
}
clock.requestIdleCallback = function requestIdleCallback(
func,
timeout
) {
let timeToNextIdlePeriod = 0;
if (clock.countTimers() > 0) {
timeToNextIdlePeriod = 50; // const for now
}
const result = addTimer(clock, {
func: func,
args: Array.prototype.slice.call(arguments, 2),
delay:
typeof timeout === "undefined"
? timeToNextIdlePeriod
: Math.min(timeout, timeToNextIdlePeriod),
idleCallback: true,
});
return Number(result);
};
clock.cancelIdleCallback = function cancelIdleCallback(timerId) {
return clearTimer(clock, timerId, "IdleCallback");
};
clock.setTimeout = function setTimeout(func, timeout) {
return addTimer(clock, {
func: func,
args: Array.prototype.slice.call(arguments, 2),
delay: timeout,
});
};
if (typeof _global.Promise !== "undefined" && utilPromisify) {
clock.setTimeout[utilPromisify.custom] =
function promisifiedSetTimeout(timeout, arg) {
return new _global.Promise(function setTimeoutExecutor(
resolve
) {
addTimer(clock, {
func: resolve,
args: [arg],
delay: timeout,
});
});
};
}
clock.clearTimeout = function clearTimeout(timerId) {
return clearTimer(clock, timerId, "Timeout");
};
clock.nextTick = function nextTick(func) {
return enqueueJob(clock, {
func: func,
args: Array.prototype.slice.call(arguments, 1),
error: isNearInfiniteLimit ? new Error() : null,
});
};
clock.queueMicrotask = function queueMicrotask(func) {
return clock.nextTick(func); // explicitly drop additional arguments
};
clock.setInterval = function setInterval(func, timeout) {
// eslint-disable-next-line no-param-reassign
timeout = parseInt(timeout, 10);
return addTimer(clock, {
func: func,
args: Array.prototype.slice.call(arguments, 2),
delay: timeout,
interval: timeout,
});
};
clock.clearInterval = function clearInterval(timerId) {
return clearTimer(clock, timerId, "Interval");
};
if (setImmediatePresent) {
clock.setImmediate = function setImmediate(func) {
return addTimer(clock, {
func: func,
args: Array.prototype.slice.call(arguments, 1),
immediate: true,
});
};
if (typeof _global.Promise !== "undefined" && utilPromisify) {
clock.setImmediate[utilPromisify.custom] =
function promisifiedSetImmediate(arg) {
return new _global.Promise(
function setImmediateExecutor(resolve) {
addTimer(clock, {
func: resolve,
args: [arg],
immediate: true,
});
}
);
};
}
clock.clearImmediate = function clearImmediate(timerId) {
return clearTimer(clock, timerId, "Immediate");
};
}
clock.countTimers = function countTimers() {
return (
Object.keys(clock.timers || {}).length +
(clock.jobs || []).length
);
};
clock.requestAnimationFrame = function requestAnimationFrame(func) {
const result = addTimer(clock, {
func: func,
delay: getTimeToNextFrame(),
get args() {
return [fakePerformanceNow()];
},
animation: true,
});
return Number(result);
};
clock.cancelAnimationFrame = function cancelAnimationFrame(timerId) {
return clearTimer(clock, timerId, "AnimationFrame");
};
clock.runMicrotasks = function runMicrotasks() {
runJobs(clock);
};
/**
* @param {number|string} tickValue milliseconds or a string parseable by parseTime
* @param {boolean} isAsync
* @param {Function} resolve
* @param {Function} reject
* @returns {number|undefined} will return the new `now` value or nothing for async
*/
function doTick(tickValue, isAsync, resolve, reject) {
const msFloat =
typeof tickValue === "number"
? tickValue
: parseTime(tickValue);
const ms = Math.floor(msFloat);
const remainder = nanoRemainder(msFloat);
let nanosTotal = nanos + remainder;
let tickTo = clock.now + ms;
if (msFloat < 0) {
throw new TypeError("Negative ticks are not supported");
}
// adjust for positive overflow
if (nanosTotal >= 1e6) {
tickTo += 1;
nanosTotal -= 1e6;
}
nanos = nanosTotal;
let tickFrom = clock.now;
let previous = clock.now;
// ESLint fails to detect this correctly
/* eslint-disable prefer-const */
let timer,
firstException,
oldNow,
nextPromiseTick,
compensationCheck,
postTimerCall;
/* eslint-enable prefer-const */
clock.duringTick = true;
// perform microtasks
oldNow = clock.now;
runJobs(clock);
if (oldNow !== clock.now) {
// compensate for any setSystemTime() call during microtask callback
tickFrom += clock.now - oldNow;
tickTo += clock.now - oldNow;
}
//eslint-disable-next-line jsdoc/require-jsdoc
function doTickInner() {
// perform each timer in the requested range
timer = firstTimerInRange(clock, tickFrom, tickTo);
// eslint-disable-next-line no-unmodified-loop-condition
while (timer && tickFrom <= tickTo) {
if (clock.timers[timer.id]) {
tickFrom = timer.callAt;
clock.now = timer.callAt;
oldNow = clock.now;
try {
runJobs(clock);
callTimer(clock, timer);
} catch (e) {
firstException = firstException || e;
}
if (isAsync) {
// finish up after native setImmediate callback to allow
// all native es6 promises to process their callbacks after
// each timer fires.
originalSetTimeout(nextPromiseTick);
return;
}
compensationCheck();
}
postTimerCall();
}
// perform process.nextTick()s again
oldNow = clock.now;
runJobs(clock);
if (oldNow !== clock.now) {
// compensate for any setSystemTime() call during process.nextTick() callback
tickFrom += clock.now - oldNow;
tickTo += clock.now - oldNow;
}
clock.duringTick = false;
// corner case: during runJobs new timers were scheduled which could be in the range [clock.now, tickTo]
timer = firstTimerInRange(clock, tickFrom, tickTo);
if (timer) {
try {
clock.tick(tickTo - clock.now); // do it all again - for the remainder of the requested range
} catch (e) {
firstException = firstException || e;
}
} else {
// no timers remaining in the requested range: move the clock all the way to the end
clock.now = tickTo;
// update nanos
nanos = nanosTotal;
}
if (firstException) {
throw firstException;
}
if (isAsync) {
resolve(clock.now);
} else {
return clock.now;
}
}
nextPromiseTick =
isAsync &&
function () {
try {
compensationCheck();
postTimerCall();
doTickInner();
} catch (e) {
reject(e);
}
};
compensationCheck = function () {
// compensate for any setSystemTime() call during timer callback
if (oldNow !== clock.now) {
tickFrom += clock.now - oldNow;
tickTo += clock.now - oldNow;
previous += clock.now - oldNow;
}
};
postTimerCall = function () {
timer = firstTimerInRange(clock, previous, tickTo);
previous = tickFrom;
};
return doTickInner();
}
/**
* @param {string|number} tickValue number of milliseconds or a human-readable value like "01:11:15"
* @returns {number} will return the new `now` value
*/
clock.tick = function tick(tickValue) {
return doTick(tickValue, false);
};
if (typeof _global.Promise !== "undefined") {
/**
* @param {string|number} tickValue number of milliseconds or a human-readable value like "01:11:15"
* @returns {Promise}
*/
clock.tickAsync = function tickAsync(tickValue) {
return new _global.Promise(function (resolve, reject) {
originalSetTimeout(function () {
try {
doTick(tickValue, true, resolve, reject);
} catch (e) {
reject(e);
}
});
});
};
}
clock.next = function next() {
runJobs(clock);
const timer = firstTimer(clock);
if (!timer) {
return clock.now;
}
clock.duringTick = true;
try {
clock.now = timer.callAt;
callTimer(clock, timer);
runJobs(clock);
return clock.now;
} finally {
clock.duringTick = false;
}
};
if (typeof _global.Promise !== "undefined") {
clock.nextAsync = function nextAsync() {
return new _global.Promise(function (resolve, reject) {
originalSetTimeout(function () {
try {
const timer = firstTimer(clock);
if (!timer) {
resolve(clock.now);
return;
}
let err;
clock.duringTick = true;
clock.now = timer.callAt;
try {
callTimer(clock, timer);
} catch (e) {
err = e;
}
clock.duringTick = false;
originalSetTimeout(function () {
if (err) {
reject(err);
} else {
resolve(clock.now);
}
});
} catch (e) {
reject(e);
}
});
});
};
}
clock.runAll = function runAll() {
let numTimers, i;
runJobs(clock);
for (i = 0; i < clock.loopLimit; i++) {
if (!clock.timers) {
resetIsNearInfiniteLimit();
return clock.now;
}
numTimers = Object.keys(clock.timers).length;
if (numTimers === 0) {
resetIsNearInfiniteLimit();
return clock.now;
}
clock.next();
checkIsNearInfiniteLimit(clock, i);
}
const excessJob = firstTimer(clock);
throw getInfiniteLoopError(clock, excessJob);
};
clock.runToFrame = function runToFrame() {
return clock.tick(getTimeToNextFrame());
};
if (typeof _global.Promise !== "undefined") {
clock.runAllAsync = function runAllAsync() {
return new _global.Promise(function (resolve, reject) {
let i = 0;
/**
*
*/
function doRun() {
originalSetTimeout(function () {
try {
let numTimers;
if (i < clock.loopLimit) {
if (!clock.timers) {
resetIsNearInfiniteLimit();
resolve(clock.now);
return;
}
numTimers = Object.keys(
clock.timers
).length;
if (numTimers === 0) {
resetIsNearInfiniteLimit();
resolve(clock.now);
return;
}
clock.next();
i++;
doRun();
checkIsNearInfiniteLimit(clock, i);
return;
}
const excessJob = firstTimer(clock);
reject(getInfiniteLoopError(clock, excessJob));
} catch (e) {
reject(e);
}
});
}
doRun();
});
};
}
clock.runToLast = function runToLast() {
const timer = lastTimer(clock);
if (!timer) {
runJobs(clock);
return clock.now;
}
return clock.tick(timer.callAt - clock.now);
};
if (typeof _global.Promise !== "undefined") {
clock.runToLastAsync = function runToLastAsync() {
return new _global.Promise(function (resolve, reject) {
originalSetTimeout(function () {
try {
const timer = lastTimer(clock);
if (!timer) {
resolve(clock.now);
}
resolve(clock.tickAsync(timer.callAt - clock.now));
} catch (e) {
reject(e);
}
});
});
};
}
clock.reset = function reset() {
nanos = 0;
clock.timers = {};
clock.jobs = [];
clock.now = start;
};
clock.setSystemTime = function setSystemTime(systemTime) {
// determine time difference
const newNow = getEpoch(systemTime);
const difference = newNow - clock.now;
let id, timer;
adjustedSystemTime[0] = adjustedSystemTime[0] + difference;
adjustedSystemTime[1] = adjustedSystemTime[1] + nanos;
// update 'system clock'
clock.now = newNow;
nanos = 0;
// update timers and intervals to keep them stable
for (id in clock.timers) {
if (clock.timers.hasOwnProperty(id)) {
timer = clock.timers[id];
timer.createdAt += difference;
timer.callAt += difference;
}
}
};
/**
* @param {string|number} tickValue number of milliseconds or a human-readable value like "01:11:15"
* @returns {number} will return the new `now` value
*/
clock.jump = function jump(tickValue) {
const msFloat =
typeof tickValue === "number"
? tickValue
: parseTime(tickValue);
const ms = Math.floor(msFloat);
for (const timer of Object.values(clock.timers)) {
if (clock.now + ms > timer.callAt) {
timer.callAt = clock.now + ms;
}
}
clock.tick(ms);
};
if (performancePresent) {
clock.performance = Object.create(null);
clock.performance.now = fakePerformanceNow;
}
if (hrtimePresent) {
clock.hrtime = hrtime;
}
return clock;
}
/* eslint-disable complexity */
/**
* @param {Config=} [config] Optional config
* @returns {Clock}
*/
function install(config) {
if (
arguments.length > 1 ||
config instanceof Date ||
Array.isArray(config) ||
typeof config === "number"
) {
throw new TypeError(
`FakeTimers.install called with ${String(
config
)} install requires an object parameter`
);
}
if (_global.Date.isFake === true) {
// Timers are already faked; this is a problem.
// Make the user reset timers before continuing.
throw new TypeError(
"Can't install fake timers twice on the same global object."
);
}
// eslint-disable-next-line no-param-reassign
config = typeof config !== "undefined" ? config : {};
config.shouldAdvanceTime = config.shouldAdvanceTime || false;
config.advanceTimeDelta = config.advanceTimeDelta || 20;
config.shouldClearNativeTimers =
config.shouldClearNativeTimers || false;
if (config.target) {
throw new TypeError(
"config.target is no longer supported. Use `withGlobal(target)` instead."
);
}
let i, l;
const clock = createClock(config.now, config.loopLimit);
clock.shouldClearNativeTimers = config.shouldClearNativeTimers;
clock.uninstall = function () {
return uninstall(clock, config);
};
clock.methods = config.toFake || [];
if (clock.methods.length === 0) {
// do not fake nextTick by default - GitHub#126
clock.methods = Object.keys(timers).filter(function (key) {
return key !== "nextTick" && key !== "queueMicrotask";
});
}
if (config.shouldAdvanceTime === true) {
const intervalTick = doIntervalTick.bind(
null,
clock,
config.advanceTimeDelta
);
const intervalId = _global.setInterval(
intervalTick,
config.advanceTimeDelta
);
clock.attachedInterval = intervalId;
}
if (clock.methods.includes("performance")) {
const proto = (() => {
if (hasPerformanceConstructorPrototype) {
return _global.performance.constructor.prototype;
}
if (hasPerformancePrototype) {
return _global.Performance.prototype;
}
})();
if (proto) {
Object.getOwnPropertyNames(proto).forEach(function (name) {
if (name !== "now") {
clock.performance[name] =
name.indexOf("getEntries") === 0
? NOOP_ARRAY
: NOOP;
}
});
} else if ((config.toFake || []).includes("performance")) {
// user explicitly tried to fake performance when not present
throw new ReferenceError(
"non-existent performance object cannot be faked"
);
}
}
if (_global === globalObject && timersModule) {
clock.timersModuleMethods = [];
}
for (i = 0, l = clock.methods.length; i < l; i++) {
const nameOfMethodToReplace = clock.methods[i];
if (nameOfMethodToReplace === "hrtime") {
if (
_global.process &&
typeof _global.process.hrtime === "function"
) {
hijackMethod(_global.process, nameOfMethodToReplace, clock);
}
} else if (nameOfMethodToReplace === "nextTick") {
if (
_global.process &&
typeof _global.process.nextTick === "function"
) {
hijackMethod(_global.process, nameOfMethodToReplace, clock);
}
} else {
hijackMethod(_global, nameOfMethodToReplace, clock);
}
if (
clock.timersModuleMethods !== undefined &&
timersModule[nameOfMethodToReplace]
) {
const original = timersModule[nameOfMethodToReplace];
clock.timersModuleMethods.push({
methodName: nameOfMethodToReplace,
original: original,
});
timersModule[nameOfMethodToReplace] =
_global[nameOfMethodToReplace];
}
}
return clock;
}
/* eslint-enable complexity */
return {
timers: timers,
createClock: createClock,
install: install,
withGlobal: withGlobal,
};
}
/**
* @typedef {object} FakeTimers
* @property {Timers} timers
* @property {createClock} createClock
* @property {Function} install
* @property {withGlobal} withGlobal
*/
/* eslint-enable complexity */
/** @type {FakeTimers} */
const defaultImplementation = withGlobal(globalObject);
defaultImplementation.timers;
defaultImplementation.createClock;
defaultImplementation.install;
var withGlobal_1 = withGlobal;
class FakeTimers {
_global;
_clock;
_fakingTime;
_fakingDate;
_fakeTimers;
_userConfig;
_now = RealDate.now;
constructor({
global,
config
}) {
this._userConfig = config;
this._fakingDate = false;
this._fakingTime = false;
this._fakeTimers = withGlobal_1(global);
this._global = global;
}
clearAllTimers() {
if (this._fakingTime)
this._clock.reset();
}
dispose() {
this.useRealTimers();
}
runAllTimers() {
if (this._checkFakeTimers())
this._clock.runAll();
}
async runAllTimersAsync() {
if (this._checkFakeTimers())
await this._clock.runAllAsync();
}
runOnlyPendingTimers() {
if (this._checkFakeTimers())
this._clock.runToLast();
}
async runOnlyPendingTimersAsync() {
if (this._checkFakeTimers())
await this._clock.runToLastAsync();
}
advanceTimersToNextTimer(steps = 1) {
if (this._checkFakeTimers()) {
for (let i = steps; i > 0; i--) {
this._clock.next();
this._clock.tick(0);
if (this._clock.countTimers() === 0)
break;
}
}
}
async advanceTimersToNextTimerAsync(steps = 1) {
if (this._checkFakeTimers()) {
for (let i = steps; i > 0; i--) {
await this._clock.nextAsync();
this._clock.tick(0);
if (this._clock.countTimers() === 0)
break;
}
}
}
advanceTimersByTime(msToRun) {
if (this._checkFakeTimers())
this._clock.tick(msToRun);
}
async advanceTimersByTimeAsync(msToRun) {
if (this._checkFakeTimers())
await this._clock.tickAsync(msToRun);
}
runAllTicks() {
if (this._checkFakeTimers()) {
this._clock.runMicrotasks();
}
}
useRealTimers() {
if (this._fakingDate) {
resetDate();
this._fakingDate = false;
}
if (this._fakingTime) {
this._clock.uninstall();
this._fakingTime = false;
}
}
useFakeTimers() {
var _a, _b, _c;
if (this._fakingDate) {
throw new Error(
'"setSystemTime" was called already and date was mocked. Reset timers using `vi.useRealTimers()` if you want to use fake timers again.'
);
}
if (!this._fakingTime) {
const toFake = Object.keys(this._fakeTimers.timers).filter((timer) => timer !== "nextTick");
if (((_b = (_a = this._userConfig) == null ? void 0 : _a.toFake) == null ? void 0 : _b.includes("nextTick")) && isChildProcess())
throw new Error("process.nextTick cannot be mocked inside child_process");
const existingFakedMethods = (((_c = this._userConfig) == null ? void 0 : _c.toFake) || toFake).filter((method) => {
switch (method) {
case "setImmediate":
case "clearImmediate":
return method in this._global && this._global[method];
default:
return true;
}
});
this._clock = this._fakeTimers.install({
now: Date.now(),
...this._userConfig,
toFake: existingFakedMethods
});
this._fakingTime = true;
}
}
reset() {
if (this._checkFakeTimers()) {
const { now } = this._clock;
this._clock.reset();
this._clock.setSystemTime(now);
}
}
setSystemTime(now) {
if (this._fakingTime) {
this._clock.setSystemTime(now);
} else {
mockDate(now ?? this.getRealSystemTime());
this._fakingDate = true;
}
}
getRealSystemTime() {
return this._now();
}
getTimerCount() {
if (this._checkFakeTimers())
return this._clock.countTimers();
return 0;
}
configure(config) {
this._userConfig = config;
}
isFakeTimers() {
return this._fakingTime;
}
_checkFakeTimers() {
if (!this._fakingTime) {
throw new Error(
'Timers are not mocked. Try calling "vi.useFakeTimers()" first.'
);
}
return this._fakingTime;
}
}
function copyStackTrace(target, source) {
if (source.stack !== void 0)
target.stack = source.stack.replace(source.message, target.message);
return target;
}
function waitFor(callback, options = {}) {
const { setTimeout, setInterval, clearTimeout, clearInterval } = getSafeTimers();
const { interval = 50, timeout = 1e3 } = typeof options === "number" ? { timeout: options } : options;
const STACK_TRACE_ERROR = new Error("STACK_TRACE_ERROR");
return new Promise((resolve, reject) => {
let lastError;
let promiseStatus = "idle";
let timeoutId;
let intervalId;
const onResolve = (result) => {
if (timeoutId)
clearTimeout(timeoutId);
if (intervalId)
clearInterval(intervalId);
resolve(result);
};
const handleTimeout = () => {
let error = lastError;
if (!error)
error = copyStackTrace(new Error("Timed out in waitFor!"), STACK_TRACE_ERROR);
reject(error);
};
const checkCallback = () => {
if (vi.isFakeTimers())
vi.advanceTimersByTime(interval);
if (promiseStatus === "pending")
return;
try {
const result = callback();
if (result !== null && typeof result === "object" && typeof result.then === "function") {
const thenable = result;
promiseStatus = "pending";
thenable.then(
(resolvedValue) => {
promiseStatus = "resolved";
onResolve(resolvedValue);
},
(rejectedValue) => {
promiseStatus = "rejected";
lastError = rejectedValue;
}
);
} else {
onResolve(result);
return true;
}
} catch (error) {
lastError = error;
}
};
if (checkCallback() === true)
return;
timeoutId = setTimeout(handleTimeout, timeout);
intervalId = setInterval(checkCallback, interval);
});
}
function waitUntil(callback, options = {}) {
const { setTimeout, setInterval, clearTimeout, clearInterval } = getSafeTimers();
const { interval = 50, timeout = 1e3 } = typeof options === "number" ? { timeout: options } : options;
const STACK_TRACE_ERROR = new Error("STACK_TRACE_ERROR");
return new Promise((resolve, reject) => {
let promiseStatus = "idle";
let timeoutId;
let intervalId;
const onReject = (error) => {
if (!error)
error = copyStackTrace(new Error("Timed out in waitUntil!"), STACK_TRACE_ERROR);
reject(error);
};
const onResolve = (result) => {
if (!result)
return;
if (timeoutId)
clearTimeout(timeoutId);
if (intervalId)
clearInterval(intervalId);
resolve(result);
return true;
};
const checkCallback = () => {
if (vi.isFakeTimers())
vi.advanceTimersByTime(interval);
if (promiseStatus === "pending")
return;
try {
const result = callback();
if (result !== null && typeof result === "object" && typeof result.then === "function") {
const thenable = result;
promiseStatus = "pending";
thenable.then(
(resolvedValue) => {
promiseStatus = "resolved";
onResolve(resolvedValue);
},
(rejectedValue) => {
promiseStatus = "rejected";
onReject(rejectedValue);
}
);
} else {
return onResolve(result);
}
} catch (error) {
onReject(error);
}
};
if (checkCallback() === true)
return;
timeoutId = setTimeout(onReject, timeout);
intervalId = setInterval(checkCallback, interval);
});
}
function createVitest() {
const _mocker = typeof __vitest_mocker__ !== "undefined" ? __vitest_mocker__ : new Proxy({}, {
get(_, name) {
throw new Error(
`Vitest mocker was not initialized in this environment. vi.${String(name)}() is forbidden.`
);
}
});
let _mockedDate = null;
let _config = null;
const workerState = getWorkerState();
let _timers;
const timers = () => _timers || (_timers = new FakeTimers({
global: globalThis,
config: workerState.config.fakeTimers
}));
const _stubsGlobal = /* @__PURE__ */ new Map();
const _stubsEnv = /* @__PURE__ */ new Map();
const _envBooleans = ["PROD", "DEV", "SSR"];
const getImporter = () => {
const stackTrace = createSimpleStackTrace({ stackTraceLimit: 4 });
const importerStack = stackTrace.split("\n")[4];
const stack = parseSingleStack(importerStack);
return (stack == null ? void 0 : stack.file) || "";
};
const utils = {
useFakeTimers(config) {
var _a, _b, _c, _d;
if (isChildProcess()) {
if (((_a = config == null ? void 0 : config.toFake) == null ? void 0 : _a.includes("nextTick")) || ((_d = (_c = (_b = workerState.config) == null ? void 0 : _b.fakeTimers) == null ? void 0 : _c.toFake) == null ? void 0 : _d.includes("nextTick"))) {
throw new Error(
'vi.useFakeTimers({ toFake: ["nextTick"] }) is not supported in node:child_process. Use --pool=threads if mocking nextTick is required.'
);
}
}
if (config)
timers().configure({ ...workerState.config.fakeTimers, ...config });
else
timers().configure(workerState.config.fakeTimers);
timers().useFakeTimers();
return utils;
},
isFakeTimers() {
return timers().isFakeTimers();
},
useRealTimers() {
timers().useRealTimers();
_mockedDate = null;
return utils;
},
runOnlyPendingTimers() {
timers().runOnlyPendingTimers();
return utils;
},
async runOnlyPendingTimersAsync() {
await timers().runOnlyPendingTimersAsync();
return utils;
},
runAllTimers() {
timers().runAllTimers();
return utils;
},
async runAllTimersAsync() {
await timers().runAllTimersAsync();
return utils;
},
runAllTicks() {
timers().runAllTicks();
return utils;
},
advanceTimersByTime(ms) {
timers().advanceTimersByTime(ms);
return utils;
},
async advanceTimersByTimeAsync(ms) {
await timers().advanceTimersByTimeAsync(ms);
return utils;
},
advanceTimersToNextTimer() {
timers().advanceTimersToNextTimer();
return utils;
},
async advanceTimersToNextTimerAsync() {
await timers().advanceTimersToNextTimerAsync();
return utils;
},
getTimerCount() {
return timers().getTimerCount();
},
setSystemTime(time) {
const date = time instanceof Date ? time : new Date(time);
_mockedDate = date;
timers().setSystemTime(date);
return utils;
},
getMockedSystemTime() {
return _mockedDate;
},
getRealSystemTime() {
return timers().getRealSystemTime();
},
clearAllTimers() {
timers().clearAllTimers();
return utils;
},
// mocks
spyOn,
fn,
waitFor,
waitUntil,
hoisted(factory) {
assertTypes(factory, '"vi.hoisted" factory', ["function"]);
return factory();
},
mock(path, factory) {
const importer = getImporter();
_mocker.queueMock(
path,
importer,
factory ? () => factory(() => _mocker.importActual(path, importer, _mocker.getMockContext().callstack)) : void 0,
true
);
},
unmock(path) {
_mocker.queueUnmock(path, getImporter());
},
doMock(path, factory) {
const importer = getImporter();
_mocker.queueMock(
path,
importer,
factory ? () => factory(() => _mocker.importActual(path, importer, _mocker.getMockContext().callstack)) : void 0,
false
);
},
doUnmock(path) {
_mocker.queueUnmock(path, getImporter());
},
async importActual(path) {
return _mocker.importActual(
path,
getImporter(),
_mocker.getMockContext().callstack
);
},
async importMock(path) {
return _mocker.importMock(path, getImporter());
},
// this is typed in the interface so it's not necessary to type it here
mocked(item, _options = {}) {
return item;
},
isMockFunction(fn2) {
return isMockFunction(fn2);
},
clearAllMocks() {
mocks.forEach((spy) => spy.mockClear());
return utils;
},
resetAllMocks() {
mocks.forEach((spy) => spy.mockReset());
return utils;
},
restoreAllMocks() {
mocks.forEach((spy) => spy.mockRestore());
return utils;
},
stubGlobal(name, value) {
if (!_stubsGlobal.has(name))
_stubsGlobal.set(name, Object.getOwnPropertyDescriptor(globalThis, name));
Object.defineProperty(globalThis, name, {
value,
writable: true,
configurable: true,
enumerable: true
});
return utils;
},
stubEnv(name, value) {
if (!_stubsEnv.has(name))
_stubsEnv.set(name, process.env[name]);
if (_envBooleans.includes(name))
process.env[name] = value ? "1" : "";
else
process.env[name] = String(value);
return utils;
},
unstubAllGlobals() {
_stubsGlobal.forEach((original, name) => {
if (!original)
Reflect.deleteProperty(globalThis, name);
else
Object.defineProperty(globalThis, name, original);
});
_stubsGlobal.clear();
return utils;
},
unstubAllEnvs() {
_stubsEnv.forEach((original, name) => {
if (original === void 0)
delete process.env[name];
else
process.env[name] = original;
});
_stubsEnv.clear();
return utils;
},
resetModules() {
resetModules(workerState.moduleCache);
return utils;
},
async dynamicImportSettled() {
return waitForImportsToResolve();
},
setConfig(config) {
if (!_config)
_config = { ...workerState.config };
Object.assign(workerState.config, config);
},
resetConfig() {
if (_config)
Object.assign(workerState.config, _config);
}
};
return utils;
}
const vitest = createVitest();
const vi = vitest;
export { globalExpect as a, vitest as b, createExpect as c, getSnapshotClient as g, resetModules as r, vi as v };
+815
View File
@@ -0,0 +1,815 @@
import vm, { isContext } from 'node:vm';
import { fileURLToPath, pathToFileURL } from 'node:url';
import { dirname, basename, extname, normalize, join, resolve } from 'pathe';
import { createCustomConsole } from '../chunks/runtime-console.EO5ha7qv.js';
import { g as getDefaultRequestStubs, s as startVitestExecutor } from './execute.fL3szUAI.js';
import { distDir } from '../path.js';
import { dirname as dirname$1 } from 'node:path';
import { statSync, existsSync, readFileSync } from 'node:fs';
import { isNodeBuiltin, isPrimitive, toArray, getCachedData, setCacheData } from 'vite-node/utils';
import { createRequire, Module } from 'node:module';
import { CSS_LANGS_RE, KNOWN_ASSET_RE } from 'vite-node/constants';
import '@vitest/runner/utils';
import '@vitest/utils';
import { p as provideWorkerState } from './global.CkGT_TMy.js';
import './env.AtSIuHFg.js';
const _require = createRequire(import.meta.url);
const requiresCache = /* @__PURE__ */ new WeakMap();
class CommonjsExecutor {
context;
requireCache = /* @__PURE__ */ new Map();
publicRequireCache = this.createProxyCache();
moduleCache = /* @__PURE__ */ new Map();
builtinCache = /* @__PURE__ */ Object.create(null);
extensions = /* @__PURE__ */ Object.create(null);
fs;
Module;
constructor(options) {
this.context = options.context;
this.fs = options.fileMap;
const primitives = vm.runInContext("({ Object, Array, Error })", this.context);
const executor = this;
this.Module = class Module$1 {
exports;
isPreloading = false;
id;
filename;
loaded;
parent;
children = [];
path;
paths = [];
constructor(id = "", parent) {
this.exports = primitives.Object.create(Object.prototype);
this.path = dirname(id);
this.id = id;
this.filename = id;
this.loaded = false;
this.parent = parent;
}
get require() {
const require = requiresCache.get(this);
if (require)
return require;
const _require2 = Module$1.createRequire(this.id);
requiresCache.set(this, _require2);
return _require2;
}
static register = () => {
throw new Error(`[vitest] "register" is not available when running in Vitest.`);
};
_compile(code, filename) {
const cjsModule = Module$1.wrap(code);
const script = new vm.Script(cjsModule, {
filename,
importModuleDynamically: options.importModuleDynamically
});
script.identifier = filename;
const fn = script.runInContext(executor.context);
const __dirname = dirname(filename);
executor.requireCache.set(filename, this);
try {
fn(this.exports, this.require, this, filename, __dirname);
return this.exports;
} finally {
this.loaded = true;
}
}
// exposed for external use, Node.js does the opposite
static _load = (request, parent, _isMain) => {
const require = Module$1.createRequire((parent == null ? void 0 : parent.filename) ?? request);
return require(request);
};
static wrap = (script) => {
return Module$1.wrapper[0] + script + Module$1.wrapper[1];
};
static wrapper = new primitives.Array(
"(function (exports, require, module, __filename, __dirname) { ",
"\n});"
);
static builtinModules = Module.builtinModules;
static findSourceMap = Module.findSourceMap;
static SourceMap = Module.SourceMap;
static syncBuiltinESMExports = Module.syncBuiltinESMExports;
static _cache = executor.moduleCache;
static _extensions = executor.extensions;
static createRequire = (filename) => {
return executor.createRequire(filename);
};
static runMain = () => {
throw new primitives.Error('[vitest] "runMain" is not implemented.');
};
// @ts-expect-error not typed
static _resolveFilename = Module._resolveFilename;
// @ts-expect-error not typed
static _findPath = Module._findPath;
// @ts-expect-error not typed
static _initPaths = Module._initPaths;
// @ts-expect-error not typed
static _preloadModules = Module._preloadModules;
// @ts-expect-error not typed
static _resolveLookupPaths = Module._resolveLookupPaths;
// @ts-expect-error not typed
static globalPaths = Module.globalPaths;
static isBuiltin = Module.isBuiltin;
static Module = Module$1;
};
this.extensions[".js"] = this.requireJs;
this.extensions[".json"] = this.requireJson;
}
requireJs = (m, filename) => {
const content = this.fs.readFile(filename);
m._compile(content, filename);
};
requireJson = (m, filename) => {
const code = this.fs.readFile(filename);
m.exports = JSON.parse(code);
};
createRequire = (filename) => {
const _require2 = createRequire(filename);
const require = (id) => {
const resolved = _require2.resolve(id);
const ext = extname(resolved);
if (ext === ".node" || isNodeBuiltin(resolved))
return this.requireCoreModule(resolved);
const module = new this.Module(resolved);
return this.loadCommonJSModule(module, resolved);
};
require.resolve = _require2.resolve;
Object.defineProperty(require, "extensions", {
get: () => this.extensions,
set: () => {
},
configurable: true
});
require.main = void 0;
require.cache = this.publicRequireCache;
return require;
};
createProxyCache() {
return new Proxy(/* @__PURE__ */ Object.create(null), {
defineProperty: () => true,
deleteProperty: () => true,
set: () => true,
get: (_, key) => this.requireCache.get(key),
has: (_, key) => this.requireCache.has(key),
ownKeys: () => Array.from(this.requireCache.keys()),
getOwnPropertyDescriptor() {
return {
configurable: true,
enumerable: true
};
}
});
}
// very naive implementation for Node.js require
loadCommonJSModule(module, filename) {
const cached = this.requireCache.get(filename);
if (cached)
return cached.exports;
const extension = this.findLongestRegisteredExtension(filename);
const loader = this.extensions[extension] || this.extensions[".js"];
loader(module, filename);
return module.exports;
}
findLongestRegisteredExtension(filename) {
const name = basename(filename);
let currentExtension;
let index;
let startIndex = 0;
while ((index = name.indexOf(".", startIndex)) !== -1) {
startIndex = index + 1;
if (index === 0)
continue;
currentExtension = name.slice(index);
if (this.extensions[currentExtension])
return currentExtension;
}
return ".js";
}
require(identifier) {
const ext = extname(identifier);
if (ext === ".node" || isNodeBuiltin(identifier))
return this.requireCoreModule(identifier);
const module = new this.Module(identifier);
return this.loadCommonJSModule(module, identifier);
}
requireCoreModule(identifier) {
const normalized = identifier.replace(/^node:/, "");
if (this.builtinCache[normalized])
return this.builtinCache[normalized].exports;
const moduleExports = _require(identifier);
if (identifier === "node:module" || identifier === "module") {
const module = new this.Module("/module.js");
module.exports = this.Module;
this.builtinCache[normalized] = module;
return module.exports;
}
this.builtinCache[normalized] = _require.cache[normalized];
return moduleExports;
}
}
function interopCommonJsModule(interopDefault, mod) {
if (isPrimitive(mod) || Array.isArray(mod) || mod instanceof Promise) {
return {
keys: [],
moduleExports: {},
defaultExport: mod
};
}
if (interopDefault !== false && "__esModule" in mod && !isPrimitive(mod.default)) {
const defaultKets = Object.keys(mod.default);
const moduleKeys = Object.keys(mod);
const allKeys = /* @__PURE__ */ new Set([...defaultKets, ...moduleKeys]);
allKeys.delete("default");
return {
keys: Array.from(allKeys),
moduleExports: new Proxy(mod, {
get(mod2, prop) {
var _a;
return mod2[prop] ?? ((_a = mod2.default) == null ? void 0 : _a[prop]);
}
}),
defaultExport: mod
};
}
return {
keys: Object.keys(mod).filter((key) => key !== "default"),
moduleExports: mod,
defaultExport: mod
};
}
const SyntheticModule$1 = vm.SyntheticModule;
const SourceTextModule = vm.SourceTextModule;
var __defProp$1 = Object.defineProperty;
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField$1 = (obj, key, value) => {
__defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
var __accessCheck$1 = (obj, member, msg) => {
if (!member.has(obj))
throw TypeError("Cannot " + msg);
};
var __privateGet$1 = (obj, member, getter) => {
__accessCheck$1(obj, member, "read from private field");
return getter ? getter.call(obj) : member.get(obj);
};
var __privateAdd$1 = (obj, member, value) => {
if (member.has(obj))
throw TypeError("Cannot add the same private member more than once");
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
};
var _httpIp;
const dataURIRegex = /^data:(?<mime>text\/javascript|application\/json|application\/wasm)(?:;(?<encoding>charset=utf-8|base64))?,(?<code>.*)$/;
class EsmExecutor {
constructor(executor, options) {
this.executor = executor;
__publicField$1(this, "moduleCache", /* @__PURE__ */ new Map());
__publicField$1(this, "esmLinkMap", /* @__PURE__ */ new WeakMap());
__publicField$1(this, "context");
__privateAdd$1(this, _httpIp, IPnumber("127.0.0.0"));
this.context = options.context;
}
async evaluateModule(m) {
if (m.status === "unlinked") {
this.esmLinkMap.set(
m,
m.link((identifier, referencer) => this.executor.resolveModule(identifier, referencer.identifier))
);
}
await this.esmLinkMap.get(m);
if (m.status === "linked")
await m.evaluate();
return m;
}
async createEsModule(fileUrl, getCode) {
const cached = this.moduleCache.get(fileUrl);
if (cached)
return cached;
const code = await getCode();
if (fileUrl.endsWith(".json")) {
const m2 = new SyntheticModule$1(
["default"],
() => {
const result = JSON.parse(code);
m2.setExport("default", result);
}
);
this.moduleCache.set(fileUrl, m2);
return m2;
}
const m = new SourceTextModule(
code,
{
identifier: fileUrl,
context: this.context,
importModuleDynamically: this.executor.importModuleDynamically,
initializeImportMeta: (meta, mod) => {
meta.url = mod.identifier;
if (mod.identifier.startsWith("file:")) {
const filename = fileURLToPath(mod.identifier);
meta.filename = filename;
meta.dirname = dirname$1(filename);
}
meta.resolve = (specifier, importer) => {
return this.executor.resolve(specifier, importer != null ? importer.toString() : mod.identifier);
};
}
}
);
this.moduleCache.set(fileUrl, m);
return m;
}
async createWebAssemblyModule(fileUrl, getCode) {
const cached = this.moduleCache.get(fileUrl);
if (cached)
return cached;
const m = this.loadWebAssemblyModule(getCode(), fileUrl);
this.moduleCache.set(fileUrl, m);
return m;
}
async createNetworkModule(fileUrl) {
if (fileUrl.startsWith("http:")) {
const url = new URL(fileUrl);
if (url.hostname !== "localhost" && url.hostname !== "::1" && (IPnumber(url.hostname) & IPmask(8)) !== __privateGet$1(this, _httpIp)) {
throw new Error(
// we don't know the importer, so it's undefined (the same happens in --pool=threads)
`import of '${fileUrl}' by undefined is not supported: http can only be used to load local resources (use https instead).`
);
}
}
return this.createEsModule(fileUrl, () => fetch(fileUrl).then((r) => r.text()));
}
async loadWebAssemblyModule(source, identifier) {
const cached = this.moduleCache.get(identifier);
if (cached)
return cached;
const wasmModule = await WebAssembly.compile(source);
const exports = WebAssembly.Module.exports(wasmModule);
const imports = WebAssembly.Module.imports(wasmModule);
const moduleLookup = {};
for (const { module } of imports) {
if (moduleLookup[module] === void 0) {
moduleLookup[module] = await this.executor.resolveModule(
module,
identifier
);
}
}
const syntheticModule = new SyntheticModule$1(
exports.map(({ name }) => name),
async () => {
const importsObject = {};
for (const { module, name } of imports) {
if (!importsObject[module])
importsObject[module] = {};
await this.evaluateModule(moduleLookup[module]);
importsObject[module][name] = moduleLookup[module].namespace[name];
}
const wasmInstance = new WebAssembly.Instance(
wasmModule,
importsObject
);
for (const { name } of exports)
syntheticModule.setExport(name, wasmInstance.exports[name]);
},
{ context: this.context, identifier }
);
return syntheticModule;
}
cacheModule(identifier, module) {
this.moduleCache.set(identifier, module);
}
resolveCachedModule(identifier) {
return this.moduleCache.get(identifier);
}
async createDataModule(identifier) {
const cached = this.moduleCache.get(identifier);
if (cached)
return cached;
const match = identifier.match(dataURIRegex);
if (!match || !match.groups)
throw new Error("Invalid data URI");
const mime = match.groups.mime;
const encoding = match.groups.encoding;
if (mime === "application/wasm") {
if (!encoding)
throw new Error("Missing data URI encoding");
if (encoding !== "base64")
throw new Error(`Invalid data URI encoding: ${encoding}`);
const module = this.loadWebAssemblyModule(
Buffer.from(match.groups.code, "base64"),
identifier
);
this.moduleCache.set(identifier, module);
return module;
}
let code = match.groups.code;
if (!encoding || encoding === "charset=utf-8")
code = decodeURIComponent(code);
else if (encoding === "base64")
code = Buffer.from(code, "base64").toString();
else
throw new Error(`Invalid data URI encoding: ${encoding}`);
if (mime === "application/json") {
const module = new SyntheticModule$1(
["default"],
() => {
const obj = JSON.parse(code);
module.setExport("default", obj);
},
{ context: this.context, identifier }
);
this.moduleCache.set(identifier, module);
return module;
}
return this.createEsModule(identifier, () => code);
}
}
_httpIp = new WeakMap();
function IPnumber(address) {
const ip = address.match(/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/);
if (ip)
return (+ip[1] << 24) + (+ip[2] << 16) + (+ip[3] << 8) + +ip[4];
throw new Error(`Expected IP address, received ${address}`);
}
function IPmask(maskSize) {
return -1 << 32 - maskSize;
}
const CLIENT_ID = "/@vite/client";
const CLIENT_FILE = pathToFileURL(CLIENT_ID).href;
class ViteExecutor {
constructor(options) {
this.options = options;
this.esm = options.esmExecutor;
}
esm;
resolve = (identifier, parent) => {
if (identifier === CLIENT_ID) {
if (this.workerState.environment.transformMode === "web")
return identifier;
const packageName = this.getPackageName(parent);
throw new Error(
`[vitest] Vitest cannot handle ${CLIENT_ID} imported in ${parent} when running in SSR environment. Add "${packageName}" to "ssr.noExternal" if you are using Vite SSR, or to "server.deps.inline" if you are using Vite Node.`
);
}
};
get workerState() {
return this.options.context.__vitest_worker__;
}
getPackageName(modulePath) {
const path = normalize(modulePath);
let name = path.split("/node_modules/").pop() || "";
if (name == null ? void 0 : name.startsWith("@"))
name = name.split("/").slice(0, 2).join("/");
else
name = name.split("/")[0];
return name;
}
async createViteModule(fileUrl) {
if (fileUrl === CLIENT_FILE)
return this.createViteClientModule();
const cached = this.esm.resolveCachedModule(fileUrl);
if (cached)
return cached;
return this.esm.createEsModule(fileUrl, async () => {
const result = await this.options.transform(fileUrl, "web");
if (!result.code)
throw new Error(`[vitest] Failed to transform ${fileUrl}. Does the file exist?`);
return result.code;
});
}
createViteClientModule() {
const identifier = CLIENT_ID;
const cached = this.esm.resolveCachedModule(identifier);
if (cached)
return cached;
const stub = this.options.viteClientModule;
const moduleKeys = Object.keys(stub);
const module = new SyntheticModule$1(
moduleKeys,
() => {
moduleKeys.forEach((key) => {
module.setExport(key, stub[key]);
});
},
{ context: this.options.context, identifier }
);
this.esm.cacheModule(identifier, module);
return module;
}
canResolve = (fileUrl) => {
var _a;
const transformMode = this.workerState.environment.transformMode;
if (transformMode !== "web")
return false;
if (fileUrl === CLIENT_FILE)
return true;
const config = ((_a = this.workerState.config.deps) == null ? void 0 : _a.web) || {};
const [modulePath] = fileUrl.split("?");
if (config.transformCss && CSS_LANGS_RE.test(modulePath))
return true;
if (config.transformAssets && KNOWN_ASSET_RE.test(modulePath))
return true;
if (toArray(config.transformGlobPattern).some((pattern) => pattern.test(modulePath)))
return true;
return false;
};
}
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
var __accessCheck = (obj, member, msg) => {
if (!member.has(obj))
throw TypeError("Cannot " + msg);
};
var __privateGet = (obj, member, getter) => {
__accessCheck(obj, member, "read from private field");
return getter ? getter.call(obj) : member.get(obj);
};
var __privateAdd = (obj, member, value) => {
if (member.has(obj))
throw TypeError("Cannot add the same private member more than once");
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
};
var __privateSet = (obj, member, value, setter) => {
__accessCheck(obj, member, "write to private field");
setter ? setter.call(obj, value) : member.set(obj, value);
return value;
};
var _networkSupported;
const SyntheticModule = vm.SyntheticModule;
const nativeResolve = import.meta.resolve;
class ExternalModulesExecutor {
constructor(options) {
this.options = options;
__publicField(this, "cjs");
__publicField(this, "esm");
__publicField(this, "vite");
__publicField(this, "context");
__publicField(this, "fs");
__publicField(this, "resolvers", []);
__privateAdd(this, _networkSupported, null);
// dynamic import can be used in both ESM and CJS, so we have it in the executor
__publicField(this, "importModuleDynamically", async (specifier, referencer) => {
const module = await this.resolveModule(specifier, referencer.identifier);
return this.esm.evaluateModule(module);
});
__publicField(this, "resolveModule", async (specifier, referencer) => {
let identifier = this.resolve(specifier, referencer);
if (identifier instanceof Promise)
identifier = await identifier;
return await this.createModule(identifier);
});
this.context = options.context;
this.fs = options.fileMap;
this.esm = new EsmExecutor(this, {
context: this.context
});
this.cjs = new CommonjsExecutor({
context: this.context,
importModuleDynamically: this.importModuleDynamically,
fileMap: options.fileMap
});
this.vite = new ViteExecutor({
esmExecutor: this.esm,
context: this.context,
transform: options.transform,
viteClientModule: options.viteClientModule
});
this.resolvers = [this.vite.resolve];
}
async import(identifier) {
const module = await this.createModule(identifier);
await this.esm.evaluateModule(module);
return module.namespace;
}
require(identifier) {
return this.cjs.require(identifier);
}
createRequire(identifier) {
return this.cjs.createRequire(identifier);
}
resolve(specifier, parent) {
for (const resolver of this.resolvers) {
const id = resolver(specifier, parent);
if (id)
return id;
}
return nativeResolve(specifier, parent);
}
findNearestPackageData(basedir) {
var _a;
const originalBasedir = basedir;
const packageCache = this.options.packageCache;
while (basedir) {
const cached = getCachedData(packageCache, basedir, originalBasedir);
if (cached)
return cached;
const pkgPath = join(basedir, "package.json");
try {
if ((_a = statSync(pkgPath, { throwIfNoEntry: false })) == null ? void 0 : _a.isFile()) {
const pkgData = JSON.parse(this.fs.readFile(pkgPath));
if (packageCache)
setCacheData(packageCache, pkgData, basedir, originalBasedir);
return pkgData;
}
} catch {
}
const nextBasedir = dirname$1(basedir);
if (nextBasedir === basedir)
break;
basedir = nextBasedir;
}
return {};
}
wrapCoreSynteticModule(identifier, exports) {
const moduleKeys = Object.keys(exports);
const m = new SyntheticModule(
[...moduleKeys, "default"],
() => {
for (const key of moduleKeys)
m.setExport(key, exports[key]);
m.setExport("default", exports);
},
{
context: this.context,
identifier
}
);
return m;
}
wrapCommonJsSynteticModule(identifier, exports) {
const { keys, moduleExports, defaultExport } = interopCommonJsModule(this.options.interopDefault, exports);
const m = new SyntheticModule(
[...keys, "default"],
() => {
for (const key of keys)
m.setExport(key, moduleExports[key]);
m.setExport("default", defaultExport);
},
{
context: this.context,
identifier
}
);
return m;
}
getModuleInformation(identifier) {
if (identifier.startsWith("data:"))
return { type: "data", url: identifier, path: identifier };
const extension = extname(identifier);
if (extension === ".node" || isNodeBuiltin(identifier))
return { type: "builtin", url: identifier, path: identifier };
if (this.isNetworkSupported && (identifier.startsWith("http:") || identifier.startsWith("https:")))
return { type: "network", url: identifier, path: identifier };
const isFileUrl = identifier.startsWith("file://");
const pathUrl = isFileUrl ? fileURLToPath(identifier.split("?")[0]) : identifier;
const fileUrl = isFileUrl ? identifier : pathToFileURL(pathUrl).toString();
let type;
if (this.vite.canResolve(fileUrl)) {
type = "vite";
} else if (extension === ".mjs") {
type = "module";
} else if (extension === ".cjs") {
type = "commonjs";
} else if (extension === ".wasm") {
type = "wasm";
} else {
const pkgData = this.findNearestPackageData(normalize(pathUrl));
type = pkgData.type === "module" ? "module" : "commonjs";
}
return { type, path: pathUrl, url: fileUrl };
}
async createModule(identifier) {
const { type, url, path } = this.getModuleInformation(identifier);
if ((type === "module" || type === "commonjs" || type === "wasm") && !existsSync(path)) {
const error = new Error(`Cannot find module '${path}'`);
error.code = "ERR_MODULE_NOT_FOUND";
throw error;
}
switch (type) {
case "data":
return this.esm.createDataModule(identifier);
case "builtin": {
const exports = this.require(identifier);
return this.wrapCoreSynteticModule(identifier, exports);
}
case "vite":
return await this.vite.createViteModule(url);
case "wasm":
return await this.esm.createWebAssemblyModule(url, () => this.fs.readBuffer(path));
case "module":
return await this.esm.createEsModule(url, () => this.fs.readFile(path));
case "commonjs": {
const exports = this.require(path);
return this.wrapCommonJsSynteticModule(identifier, exports);
}
case "network": {
return this.esm.createNetworkModule(url);
}
default: {
const _deadend = type;
return _deadend;
}
}
}
get isNetworkSupported() {
var _a;
if (__privateGet(this, _networkSupported) == null) {
if (process.execArgv.includes("--experimental-network-imports"))
__privateSet(this, _networkSupported, true);
else if ((_a = process.env.NODE_OPTIONS) == null ? void 0 : _a.includes("--experimental-network-imports"))
__privateSet(this, _networkSupported, true);
else
__privateSet(this, _networkSupported, false);
}
return __privateGet(this, _networkSupported);
}
}
_networkSupported = new WeakMap();
class FileMap {
fsCache = /* @__PURE__ */ new Map();
fsBufferCache = /* @__PURE__ */ new Map();
readFile(path) {
const cached = this.fsCache.get(path);
if (cached)
return cached;
const source = readFileSync(path, "utf-8");
this.fsCache.set(path, source);
return source;
}
readBuffer(path) {
const cached = this.fsBufferCache.get(path);
if (cached)
return cached;
const buffer = readFileSync(path);
this.fsBufferCache.set(path, buffer);
return buffer;
}
}
const entryFile = pathToFileURL(resolve(distDir, "workers/runVmTests.js")).href;
const fileMap = new FileMap();
const packageCache = /* @__PURE__ */ new Map();
async function runVmTests(state) {
var _a;
const { environment, ctx, rpc } = state;
if (!environment.setupVM) {
const envName = ctx.environment.name;
const packageId = envName[0] === "." ? envName : `vitest-environment-${envName}`;
throw new TypeError(
`Environment "${ctx.environment.name}" is not a valid environment. Path "${packageId}" doesn't support vm environment because it doesn't provide "setupVM" method.`
);
}
const vm = await environment.setupVM(ctx.environment.options || ctx.config.environmentOptions || {});
state.durations.environment = performance.now() - state.durations.environment;
process.env.VITEST_VM_POOL = "1";
if (!vm.getVmContext)
throw new TypeError(`Environment ${environment.name} doesn't provide "getVmContext" method. It should return a context created by "vm.createContext" method.`);
const context = vm.getVmContext();
if (!isContext(context))
throw new TypeError(`Environment ${environment.name} doesn't provide a valid context. It should be created by "vm.createContext" method.`);
provideWorkerState(context, state);
context.process = process;
context.global = context;
context.console = state.config.disableConsoleIntercept ? console : createCustomConsole();
context.setImmediate = setImmediate;
context.clearImmediate = clearImmediate;
const stubs = getDefaultRequestStubs(context);
const externalModulesExecutor = new ExternalModulesExecutor({
context,
fileMap,
packageCache,
transform: rpc.transform,
viteClientModule: stubs["/@vite/client"]
});
const executor = await startVitestExecutor({
context,
moduleCache: state.moduleCache,
mockMap: state.mockMap,
state,
externalModulesExecutor,
requestStubs: stubs
});
context.__vitest_mocker__ = executor.mocker;
const { run } = await executor.importExternalModule(entryFile);
try {
await run(ctx.files, ctx.config, executor);
} finally {
await ((_a = vm.teardown) == null ? void 0 : _a.call(vm));
state.environmentTeardownRun = true;
}
}
export { runVmTests as r };
+107
View File
@@ -0,0 +1,107 @@
import { pathToFileURL } from 'node:url';
import { workerId } from 'tinypool';
import { ViteNodeRunner, ModuleCacheMap } from 'vite-node/client';
import { readFileSync } from 'node:fs';
import { resolve, normalize } from 'pathe';
import { e as environments } from './vendor/index.GVFv9dZ0.js';
import { i as isChildProcess, s as setProcessTitle } from './vendor/base.5NT-gWu5.js';
import { s as setupInspect } from './vendor/inspector.IgLX3ur5.js';
import { c as createRuntimeRpc, a as rpcDone } from './vendor/rpc.joBhAkyK.js';
import 'node:console';
import '@vitest/utils';
import 'node:module';
import './vendor/index.8bPxjt7g.js';
import './vendor/global.CkGT_TMy.js';
function isBuiltinEnvironment(env) {
return env in environments;
}
const _loaders = /* @__PURE__ */ new Map();
async function createEnvironmentLoader(options) {
if (!_loaders.has(options.root)) {
const loader = new ViteNodeRunner(options);
await loader.executeId("/@vite/env");
_loaders.set(options.root, loader);
}
return _loaders.get(options.root);
}
async function loadEnvironment(ctx, rpc) {
var _a;
const name = ctx.environment.name;
if (isBuiltinEnvironment(name))
return environments[name];
const loader = await createEnvironmentLoader({
root: ctx.config.root,
fetchModule: async (id) => {
const result = await rpc.fetch(id, "ssr");
if (result.id)
return { code: readFileSync(result.id, "utf-8") };
return result;
},
resolveId: (id, importer) => rpc.resolveId(id, importer, "ssr")
});
const root = loader.root;
const packageId = name[0] === "." || name[0] === "/" ? resolve(root, name) : ((_a = await rpc.resolveId(`vitest-environment-${name}`, void 0, "ssr")) == null ? void 0 : _a.id) ?? resolve(root, name);
const pkg = await loader.executeId(normalize(packageId));
if (!pkg || !pkg.default || typeof pkg.default !== "object") {
throw new TypeError(
`Environment "${name}" is not a valid environment. Path "${packageId}" should export default object with a "setup" or/and "setupVM" method.`
);
}
const environment = pkg.default;
if (environment.transformMode !== "web" && environment.transformMode !== "ssr") {
throw new TypeError(
`Environment "${name}" is not a valid environment. Path "${packageId}" should export default object with a "transformMode" method equal to "ssr" or "web".`
);
}
return environment;
}
if (isChildProcess())
setProcessTitle(`vitest ${workerId}`);
async function run(ctx) {
const prepareStart = performance.now();
const inspectorCleanup = setupInspect(ctx);
process.env.VITEST_WORKER_ID = String(ctx.workerId);
process.env.VITEST_POOL_ID = String(workerId);
try {
if (ctx.worker[0] === ".")
throw new Error(`Path to the test runner cannot be relative, received "${ctx.worker}"`);
const file = ctx.worker.startsWith("file:") ? ctx.worker : pathToFileURL(ctx.worker).toString();
const testRunnerModule = await import(file);
if (!testRunnerModule.default || typeof testRunnerModule.default !== "object")
throw new TypeError(`Test worker object should be exposed as a default export. Received "${typeof testRunnerModule.default}"`);
const worker = testRunnerModule.default;
if (!worker.getRpcOptions || typeof worker.getRpcOptions !== "function")
throw new TypeError(`Test worker should expose "getRpcOptions" method. Received "${typeof worker.getRpcOptions}".`);
const { rpc, onCancel } = createRuntimeRpc(worker.getRpcOptions(ctx));
const beforeEnvironmentTime = performance.now();
const environment = await loadEnvironment(ctx, rpc);
if (ctx.environment.transformMode)
environment.transformMode = ctx.environment.transformMode;
const state = {
ctx,
// here we create a new one, workers can reassign this if they need to keep it non-isolated
moduleCache: new ModuleCacheMap(),
mockMap: /* @__PURE__ */ new Map(),
config: ctx.config,
onCancel,
environment,
durations: {
environment: beforeEnvironmentTime,
prepare: prepareStart
},
rpc,
providedContext: ctx.providedContext
};
if (!worker.runTests || typeof worker.runTests !== "function")
throw new TypeError(`Test worker should expose "runTests" method. Received "${typeof worker.runTests}".`);
await worker.runTests(state);
} finally {
await rpcDone().catch(() => {
});
inspectorCleanup();
}
}
export { run };
+40
View File
@@ -0,0 +1,40 @@
import * as v8 from 'v8';
import { d as BirpcOptions, e as RuntimeRPC, f as ContextRPC, W as WorkerGlobalState, g as WorkerContext, R as ResolvedConfig } from './reporters-w_64AS5f.js';
import { Awaitable } from '@vitest/utils';
import 'vite';
import '@vitest/runner';
import 'vite-node';
import '@vitest/snapshot';
import '@vitest/expect';
import '@vitest/runner/utils';
import 'tinybench';
import 'node:stream';
import 'vite-node/client';
import '@vitest/snapshot/manager';
import 'vite-node/server';
import 'node:worker_threads';
import 'node:fs';
import 'chai';
type WorkerRpcOptions = Pick<BirpcOptions<RuntimeRPC>, 'on' | 'post' | 'serialize' | 'deserialize'>;
interface VitestWorker {
getRpcOptions: (ctx: ContextRPC) => WorkerRpcOptions;
runTests: (state: WorkerGlobalState) => Awaitable<unknown>;
}
declare function createThreadsRpcOptions({ port }: WorkerContext): WorkerRpcOptions;
declare function createForksRpcOptions(nodeV8: typeof v8): WorkerRpcOptions;
/**
* Reverts the wrapping done by `utils/config-helpers.ts`'s `wrapSerializableConfig`
*/
declare function unwrapSerializableConfig(config: ResolvedConfig): ResolvedConfig;
declare function provideWorkerState(context: any, state: WorkerGlobalState): WorkerGlobalState;
declare function run(ctx: ContextRPC): Promise<void>;
declare function runVmTests(state: WorkerGlobalState): Promise<void>;
declare function runBaseTests(state: WorkerGlobalState): Promise<void>;
export { type VitestWorker, type WorkerRpcOptions, createForksRpcOptions, createThreadsRpcOptions, provideWorkerState, runBaseTests, run as runVitestWorker, runVmTests, unwrapSerializableConfig };
+31
View File
@@ -0,0 +1,31 @@
export { c as createForksRpcOptions, a as createThreadsRpcOptions, u as unwrapSerializableConfig } from './vendor/utils.0uYuCbzo.js';
export { p as provideWorkerState } from './vendor/global.CkGT_TMy.js';
export { run as runVitestWorker } from './worker.js';
export { r as runVmTests } from './vendor/vm.QEE48c0T.js';
export { r as runBaseTests } from './vendor/base.Ybri3C14.js';
import '@vitest/utils';
import 'node:url';
import 'tinypool';
import 'vite-node/client';
import 'node:fs';
import 'pathe';
import './vendor/index.GVFv9dZ0.js';
import 'node:console';
import './vendor/base.5NT-gWu5.js';
import './vendor/inspector.IgLX3ur5.js';
import 'node:module';
import './vendor/rpc.joBhAkyK.js';
import './vendor/index.8bPxjt7g.js';
import 'node:vm';
import './chunks/runtime-console.EO5ha7qv.js';
import 'node:stream';
import 'node:path';
import './vendor/date.Ns1pGd_X.js';
import '@vitest/runner/utils';
import './vendor/env.AtSIuHFg.js';
import 'std-env';
import './vendor/execute.fL3szUAI.js';
import 'vite-node/utils';
import '@vitest/utils/error';
import './path.js';
import 'vite-node/constants';
+33
View File
@@ -0,0 +1,33 @@
import v8 from 'node:v8';
import { c as createForksRpcOptions, u as unwrapSerializableConfig } from '../vendor/utils.0uYuCbzo.js';
import { r as runBaseTests } from '../vendor/base.Ybri3C14.js';
import '@vitest/utils';
import 'vite-node/client';
import '../vendor/global.CkGT_TMy.js';
import '../vendor/execute.fL3szUAI.js';
import 'node:vm';
import 'node:url';
import 'node:fs';
import 'vite-node/utils';
import 'pathe';
import '@vitest/utils/error';
import '../path.js';
import '../vendor/base.5NT-gWu5.js';
class ForksBaseWorker {
getRpcOptions() {
return createForksRpcOptions(v8);
}
async runTests(state) {
const exit = process.exit;
state.ctx.config = unwrapSerializableConfig(state.ctx.config);
try {
await runBaseTests(state);
} finally {
process.exit = exit;
}
}
}
var forks = new ForksBaseWorker();
export { forks as default };
+84
View File
@@ -0,0 +1,84 @@
import { isatty } from 'node:tty';
import { createRequire } from 'node:module';
import util from 'node:util';
import timers from 'node:timers';
import { performance } from 'node:perf_hooks';
import { startTests } from '@vitest/runner';
import { setupColors, createColors } from '@vitest/utils';
import { installSourcemapsSupport } from 'vite-node/source-map';
import { s as setupChaiConfig, r as resolveTestRunner, a as resolveSnapshotEnvironment } from '../vendor/index.DpVgvm2P.js';
import { a as startCoverageInsideWorker, s as stopCoverageInsideWorker } from '../vendor/coverage.E7sG1b3r.js';
import { g as getWorkerState } from '../vendor/global.CkGT_TMy.js';
import { V as VitestIndex } from '../vendor/index.dI9lHwVn.js';
import { s as setupCommonEnv } from '../vendor/setup-common.8nJLd4ay.js';
import { c as closeInspector } from '../vendor/inspector.IgLX3ur5.js';
import 'chai';
import 'pathe';
import '../path.js';
import 'node:url';
import '../vendor/rpc.joBhAkyK.js';
import '../vendor/index.8bPxjt7g.js';
import '../vendor/benchmark.yGkUTKnC.js';
import '@vitest/runner/utils';
import '../vendor/index.SMVOaj7F.js';
import '../vendor/env.AtSIuHFg.js';
import 'std-env';
import '../vendor/run-once.Olz_Zkd8.js';
import '../vendor/vi.YFlodzP_.js';
import '../vendor/_commonjsHelpers.jjO7Zipk.js';
import '@vitest/expect';
import '@vitest/snapshot';
import '@vitest/utils/error';
import '../vendor/tasks.IknbGB2n.js';
import '@vitest/utils/source-map';
import '../vendor/base.5NT-gWu5.js';
import '../vendor/date.Ns1pGd_X.js';
import '@vitest/spy';
async function run(files, config, executor) {
const workerState = getWorkerState();
await setupCommonEnv(config);
Object.defineProperty(globalThis, "__vitest_index__", {
value: VitestIndex,
enumerable: false
});
setupColors(createColors(isatty(1)));
if (workerState.environment.transformMode === "web") {
const _require = createRequire(import.meta.url);
_require.extensions[".css"] = () => ({});
_require.extensions[".scss"] = () => ({});
_require.extensions[".sass"] = () => ({});
_require.extensions[".less"] = () => ({});
}
globalThis.__vitest_required__ = {
util,
timers
};
installSourcemapsSupport({
getSourceMap: (source) => workerState.moduleCache.getSourceMap(source)
});
await startCoverageInsideWorker(config.coverage, executor);
if (config.chaiConfig)
setupChaiConfig(config.chaiConfig);
const [runner, snapshotEnvironment] = await Promise.all([
resolveTestRunner(config, executor),
resolveSnapshotEnvironment(config, executor)
]);
config.snapshotOptions.snapshotEnvironment = snapshotEnvironment;
workerState.onCancel.then((reason) => {
var _a;
closeInspector(config);
(_a = runner.onCancel) == null ? void 0 : _a.call(runner, reason);
});
workerState.durations.prepare = performance.now() - workerState.durations.prepare;
const { vi } = VitestIndex;
for (const file of files) {
workerState.filepath = file;
await startTests([file], runner);
vi.resetConfig();
vi.restoreAllMocks();
}
await stopCoverageInsideWorker(config.coverage, executor);
}
export { run };
+26
View File
@@ -0,0 +1,26 @@
import { r as runBaseTests } from '../vendor/base.Ybri3C14.js';
import { a as createThreadsRpcOptions } from '../vendor/utils.0uYuCbzo.js';
import 'vite-node/client';
import '../vendor/global.CkGT_TMy.js';
import '../vendor/execute.fL3szUAI.js';
import 'node:vm';
import 'node:url';
import 'node:fs';
import 'vite-node/utils';
import 'pathe';
import '@vitest/utils/error';
import '../path.js';
import '@vitest/utils';
import '../vendor/base.5NT-gWu5.js';
class ThreadsBaseWorker {
getRpcOptions(ctx) {
return createThreadsRpcOptions(ctx);
}
runTests(state) {
return runBaseTests(state);
}
}
var threads = new ThreadsBaseWorker();
export { threads as default };
+43
View File
@@ -0,0 +1,43 @@
import v8 from 'node:v8';
import { c as createForksRpcOptions, u as unwrapSerializableConfig } from '../vendor/utils.0uYuCbzo.js';
import { r as runVmTests } from '../vendor/vm.QEE48c0T.js';
import '@vitest/utils';
import 'node:vm';
import 'node:url';
import 'pathe';
import '../chunks/runtime-console.EO5ha7qv.js';
import 'node:stream';
import 'node:console';
import 'node:path';
import '../vendor/date.Ns1pGd_X.js';
import '@vitest/runner/utils';
import '../vendor/global.CkGT_TMy.js';
import '../vendor/env.AtSIuHFg.js';
import 'std-env';
import '../vendor/execute.fL3szUAI.js';
import 'node:fs';
import 'vite-node/client';
import 'vite-node/utils';
import '@vitest/utils/error';
import '../path.js';
import '../vendor/base.5NT-gWu5.js';
import 'node:module';
import 'vite-node/constants';
class ForksVmWorker {
getRpcOptions() {
return createForksRpcOptions(v8);
}
async runTests(state) {
const exit = process.exit;
state.ctx.config = unwrapSerializableConfig(state.ctx.config);
try {
await runVmTests(state);
} finally {
process.exit = exit;
}
}
}
var vmForks = new ForksVmWorker();
export { vmForks as default };
+36
View File
@@ -0,0 +1,36 @@
import { a as createThreadsRpcOptions } from '../vendor/utils.0uYuCbzo.js';
import { r as runVmTests } from '../vendor/vm.QEE48c0T.js';
import '@vitest/utils';
import 'node:vm';
import 'node:url';
import 'pathe';
import '../chunks/runtime-console.EO5ha7qv.js';
import 'node:stream';
import 'node:console';
import 'node:path';
import '../vendor/date.Ns1pGd_X.js';
import '@vitest/runner/utils';
import '../vendor/global.CkGT_TMy.js';
import '../vendor/env.AtSIuHFg.js';
import 'std-env';
import '../vendor/execute.fL3szUAI.js';
import 'node:fs';
import 'vite-node/client';
import 'vite-node/utils';
import '@vitest/utils/error';
import '../path.js';
import '../vendor/base.5NT-gWu5.js';
import 'node:module';
import 'vite-node/constants';
class ThreadsVmWorker {
getRpcOptions(ctx) {
return createThreadsRpcOptions(ctx);
}
runTests(state) {
return runVmTests(state);
}
}
var vmThreads = new ThreadsVmWorker();
export { vmThreads as default };
+1
View File
@@ -0,0 +1 @@
export * from './dist/environments'
+1
View File
@@ -0,0 +1 @@
export * from './dist/execute.js'
+19
View File
@@ -0,0 +1,19 @@
declare global {
const suite: typeof import('vitest')['suite']
const test: typeof import('vitest')['test']
const describe: typeof import('vitest')['describe']
const it: typeof import('vitest')['it']
const expectTypeOf: typeof import('vitest')['expectTypeOf']
const assertType: typeof import('vitest')['assertType']
const expect: typeof import('vitest')['expect']
const assert: typeof import('vitest')['assert']
const vitest: typeof import('vitest')['vitest']
const vi: typeof import('vitest')['vitest']
const beforeAll: typeof import('vitest')['beforeAll']
const afterAll: typeof import('vitest')['afterAll']
const beforeEach: typeof import('vitest')['beforeEach']
const afterEach: typeof import('vitest')['afterEach']
const onTestFailed: typeof import('vitest')['onTestFailed']
const onTestFinished: typeof import('vitest')['onTestFinished']
}
export {}
+5
View File
@@ -0,0 +1,5 @@
/// <reference path="./importMeta.d.ts" />
// https://github.com/microsoft/TypeScript/issues/45096
// TypeScript has a bug that makes <reference types="vite/types/importMeta" />
// not possible in userland. This file provides a workaround for now.
+4
View File
@@ -0,0 +1,4 @@
interface ImportMeta {
url: string
readonly vitest?: typeof import('vitest')
}
+5
View File
@@ -0,0 +1,5 @@
throw new Error(
'Vitest cannot be imported in a CommonJS module using require(). Please use "import" instead.'
+ '\n\nIf you are using "import" in your source code, then it\'s possible it was bundled into require() automatically by your bundler. '
+ 'In that case, do not bundle CommonJS output since it will never work with Vitest, or use dynamic import() which is available in all CommonJS modules.',
)
+1
View File
@@ -0,0 +1 @@
export * from './dist/index.js'
+6
View File
@@ -0,0 +1,6 @@
import type { JSDOM } from 'jsdom'
declare global {
const jsdom: JSDOM
}
export {}
+1
View File
@@ -0,0 +1 @@
export * from './dist/node.js'
+203
View File
@@ -0,0 +1,203 @@
{
"name": "vitest",
"type": "module",
"version": "1.6.1",
"description": "Next generation testing framework powered by Vite",
"author": "Anthony Fu <anthonyfu117@hotmail.com>",
"license": "MIT",
"funding": "https://opencollective.com/vitest",
"homepage": "https://github.com/vitest-dev/vitest#readme",
"repository": {
"type": "git",
"url": "git+https://github.com/vitest-dev/vitest.git",
"directory": "packages/vitest"
},
"bugs": {
"url": "https://github.com/vitest-dev/vitest/issues"
},
"keywords": [
"vite",
"vite-node",
"vitest",
"test",
"jest"
],
"sideEffects": false,
"exports": {
".": {
"import": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
},
"require": {
"types": "./index.d.cts",
"default": "./index.cjs"
}
},
"./*": "./*",
"./globals": {
"types": "./globals.d.ts"
},
"./jsdom": {
"types": "./jsdom.d.ts"
},
"./importMeta": {
"types": "./importMeta.d.ts"
},
"./import-meta": {
"types": "./import-meta.d.ts"
},
"./node": {
"types": "./dist/node.d.ts",
"default": "./dist/node.js"
},
"./execute": {
"types": "./dist/execute.d.ts",
"default": "./dist/execute.js"
},
"./workers": {
"types": "./dist/workers.d.ts",
"import": "./dist/workers.js"
},
"./browser": {
"types": "./dist/browser.d.ts",
"default": "./dist/browser.js"
},
"./runners": {
"types": "./dist/runners.d.ts",
"default": "./dist/runners.js"
},
"./suite": {
"types": "./dist/suite.d.ts",
"default": "./dist/suite.js"
},
"./environments": {
"types": "./dist/environments.d.ts",
"default": "./dist/environments.js"
},
"./utils": {
"types": "./dist/utils.d.ts",
"default": "./dist/utils.js"
},
"./config": {
"types": "./config.d.ts",
"require": "./dist/config.cjs",
"default": "./dist/config.js"
},
"./coverage": {
"types": "./coverage.d.ts",
"default": "./dist/coverage.js"
},
"./reporters": {
"types": "./dist/reporters.d.ts",
"default": "./dist/reporters.js"
},
"./snapshot": {
"types": "./dist/snapshot.d.ts",
"default": "./dist/snapshot.js"
}
},
"main": "./dist/index.js",
"module": "./dist/index.js",
"types": "./dist/index.d.ts",
"bin": {
"vitest": "./vitest.mjs"
},
"files": [
"*.cjs",
"*.d.cts",
"*.d.ts",
"*.mjs",
"bin",
"dist"
],
"engines": {
"node": "^18.0.0 || >=20.0.0"
},
"peerDependencies": {
"@edge-runtime/vm": "*",
"@types/node": "^18.0.0 || >=20.0.0",
"happy-dom": "*",
"jsdom": "*",
"@vitest/ui": "1.6.1",
"@vitest/browser": "1.6.1"
},
"peerDependenciesMeta": {
"@edge-runtime/vm": {
"optional": true
},
"@types/node": {
"optional": true
},
"@vitest/browser": {
"optional": true
},
"@vitest/ui": {
"optional": true
},
"happy-dom": {
"optional": true
},
"jsdom": {
"optional": true
}
},
"dependencies": {
"acorn-walk": "^8.3.2",
"chai": "^4.3.10",
"debug": "^4.3.4",
"execa": "^8.0.1",
"local-pkg": "^0.5.0",
"magic-string": "^0.30.5",
"pathe": "^1.1.1",
"picocolors": "^1.0.0",
"std-env": "^3.5.0",
"strip-literal": "^2.0.0",
"tinybench": "^2.5.1",
"tinypool": "^0.8.3",
"vite": "^5.0.0",
"why-is-node-running": "^2.2.2",
"@vitest/runner": "1.6.1",
"@vitest/expect": "1.6.1",
"@vitest/spy": "1.6.1",
"@vitest/utils": "1.6.1",
"vite-node": "1.6.1",
"@vitest/snapshot": "1.6.1"
},
"devDependencies": {
"@ampproject/remapping": "^2.2.1",
"@antfu/install-pkg": "^0.3.1",
"@edge-runtime/vm": "^3.1.8",
"@sinonjs/fake-timers": "11.1.0",
"@types/estree": "^1.0.5",
"@types/istanbul-lib-coverage": "^2.0.6",
"@types/istanbul-reports": "^3.0.4",
"@types/jsdom": "^21.1.6",
"@types/micromatch": "^4.0.6",
"@types/node": "^20.11.5",
"@types/prompts": "^2.4.9",
"@types/sinonjs__fake-timers": "^8.1.5",
"birpc": "0.2.15",
"cac": "^6.7.14",
"chai-subset": "^1.6.0",
"cli-truncate": "^4.0.0",
"expect-type": "^0.17.3",
"fast-glob": "^3.3.2",
"find-up": "^6.3.0",
"flatted": "^3.2.9",
"get-tsconfig": "^4.7.3",
"happy-dom": "^14.3.10",
"jsdom": "^24.0.0",
"log-update": "^5.0.1",
"micromatch": "^4.0.5",
"p-limit": "^5.0.0",
"pretty-format": "^29.7.0",
"prompts": "^2.4.2",
"strip-ansi": "^7.1.0",
"ws": "^8.14.2"
},
"scripts": {
"build": "rimraf dist && rollup -c",
"dev": "NODE_OPTIONS=\"--max-old-space-size=8192\" rollup -c --watch -m inline"
}
}
+1
View File
@@ -0,0 +1 @@
export * from './dist/reporters.js'
+1
View File
@@ -0,0 +1 @@
export * from './dist/runners.js'
+1
View File
@@ -0,0 +1 @@
export * from './dist/snapshot.js'
+1
View File
@@ -0,0 +1 @@
export * from './dist/suite.js'
+23
View File
@@ -0,0 +1,23 @@
// borrowed from tsx implementation:
// https://github.com/esbuild-kit/tsx
const ignoreWarnings = new Set([
'--experimental-loader is an experimental feature. This feature could change at any time',
'Custom ESM Loaders is an experimental feature. This feature could change at any time',
'Custom ESM Loaders is an experimental feature and might change at any time',
'VM Modules is an experimental feature and might change at any time',
'VM Modules is an experimental feature. This feature could change at any time',
])
const { emit } = process
process.emit = function (event, warning) {
if (
event === 'warning'
&& ignoreWarnings.has(warning.message)
)
return
// eslint-disable-next-line prefer-rest-params
return Reflect.apply(emit, this, arguments)
}
+1
View File
@@ -0,0 +1 @@
export * from './dist/utils.js'
+2
View File
@@ -0,0 +1,2 @@
#!/usr/bin/env node
import './dist/cli-wrapper.js'
+1
View File
@@ -0,0 +1 @@
export * from './dist/workers.js'