diff --git a/.github/MARKETPLACE_PUBLISHING.md b/.github/MARKETPLACE_PUBLISHING.md
index b612b8f..9f60771 100644
--- a/.github/MARKETPLACE_PUBLISHING.md
+++ b/.github/MARKETPLACE_PUBLISHING.md
@@ -262,7 +262,7 @@ Add relevant badges to increase trust:
[](...)
[](...)
[](...)
-[](LICENSE)
+[](https://www.gnu.org/licenses/agpl-3.0)
[](...)
```
diff --git a/ACTION_README.md b/ACTION_README.md
index e0c9c1c..f6ec066 100644
--- a/ACTION_README.md
+++ b/ACTION_README.md
@@ -2,7 +2,7 @@
[](https://github.com/marketplace/actions/gosqlx-sql-validator)
[](https://github.com/ajitpratap0/GoSQLX/releases)
-[](LICENSE)
+[](https://www.gnu.org/licenses/agpl-3.0)
Ultra-fast SQL validation, linting, and formatting for your CI/CD pipelines. **100-1000x faster** than traditional SQL linters like SQLFluff.
@@ -435,7 +435,7 @@ We welcome contributions! Please see:
## License
-MIT License - see [LICENSE](LICENSE) file for details.
+GNU Affero General Public License v3.0 (AGPL-3.0) - see [LICENSE](LICENSE) file for details.
## Support
diff --git a/LICENSE b/LICENSE
index 867ed14..be3f7b2 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,21 +1,661 @@
-MIT License
-
-Copyright (c) 2025 GoSQLX
-
-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.
+ GNU AFFERO GENERAL PUBLIC LICENSE
+ Version 3, 19 November 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU Affero General Public License is a free, copyleft license for
+software and other kinds of works, specifically designed to ensure
+cooperation with the community in the case of network server software.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+our General Public Licenses are intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ Developers that use our General Public Licenses protect your rights
+with two steps: (1) assert copyright on the software, and (2) offer
+you this License which gives you legal permission to copy, distribute
+and/or modify the software.
+
+ A secondary benefit of defending all users' freedom is that
+improvements made in alternate versions of the program, if they
+receive widespread use, become available for other developers to
+incorporate. Many developers of free software are heartened and
+encouraged by the resulting cooperation. However, in the case of
+software used on network servers, this result may fail to come about.
+The GNU General Public License permits making a modified version and
+letting the public access it on a server without ever releasing its
+source code to the public.
+
+ The GNU Affero General Public License is designed specifically to
+ensure that, in such cases, the modified source code becomes available
+to the community. It requires the operator of a network server to
+provide the source code of the modified version running there to the
+users of that server. Therefore, public use of a modified version, on
+a publicly accessible server, gives the public access to the source
+code of the modified version.
+
+ An older license, called the Affero General Public License and
+published by Affero, was designed to accomplish similar goals. This is
+a different license, not a version of the Affero GPL, but Affero has
+released a new version of the Affero GPL which permits relicensing under
+this license.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU Affero General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Remote Network Interaction; Use with the GNU General Public License.
+
+ Notwithstanding any other provision of this License, if you modify the
+Program, your modified version must prominently offer all users
+interacting with it remotely through a computer network (if your version
+supports such interaction) an opportunity to receive the Corresponding
+Source of your version by providing access to the Corresponding Source
+from a network server at no charge, through some standard or customary
+means of facilitating copying of software. This Corresponding Source
+shall include the Corresponding Source for any work covered by version 3
+of the GNU General Public License that is incorporated pursuant to the
+following paragraph.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the work with which it is combined will remain governed by version
+3 of the GNU General Public License.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU Affero General Public License from time to time. Such new versions
+will be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU Affero General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU Affero General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU Affero General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If your software can interact with users remotely through a computer
+network, you should also make sure that it provides a way for users to
+get its source. For example, if your program is a web application, its
+interface could display a "Source" link that leads users to an archive
+of the code. There are many ways you could offer source, and different
+solutions will be better for different programs; see section 13 for the
+specific requirements.
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU AGPL, see
+.
diff --git a/README.md b/README.md
index 163895f..ec2296f 100644
--- a/README.md
+++ b/README.md
@@ -8,7 +8,7 @@
[](https://go.dev)
[](https://github.com/ajitpratap0/GoSQLX/releases)
-[](https://opensource.org/licenses/MIT)
+[](https://www.gnu.org/licenses/agpl-3.0)
[](http://makeapullrequest.com)
[](https://github.com/ajitpratap0/GoSQLX/actions)
@@ -771,7 +771,7 @@ We welcome contributions! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guid
## 📄 License
-This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
+This project is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0) - see the [LICENSE](LICENSE) file for details.
## 🚀 Roadmap
@@ -940,7 +940,7 @@ If GoSQLX helps your project, please consider:
-This project is licensed under the **MIT License** - see the [LICENSE](LICENSE) file for details.
+This project is licensed under the **GNU Affero General Public License v3.0 (AGPL-3.0)** - see the [LICENSE](LICENSE) file for details.
diff --git a/RELEASE_NOTES_v1.5.0.md b/RELEASE_NOTES_v1.5.0.md
index f0533f0..d019a14 100644
--- a/RELEASE_NOTES_v1.5.0.md
+++ b/RELEASE_NOTES_v1.5.0.md
@@ -426,7 +426,7 @@ Special thanks to all contributors who made this release possible!
## 📄 License
-MIT License - see [LICENSE](LICENSE) file for details
+GNU Affero General Public License v3.0 (AGPL-3.0) - see [LICENSE](LICENSE) file for details
---
diff --git a/cmd/gosqlx/internal/config/README.md b/cmd/gosqlx/internal/config/README.md
index fcd8c4c..d9c5a65 100644
--- a/cmd/gosqlx/internal/config/README.md
+++ b/cmd/gosqlx/internal/config/README.md
@@ -437,4 +437,4 @@ When adding new configuration options:
## License
-This package is part of GoSQLX and is licensed under the MIT License.
+This package is part of GoSQLX and is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0).
diff --git a/docs/CLI_GUIDE.md b/docs/CLI_GUIDE.md
index ebe18ee..b632c76 100644
--- a/docs/CLI_GUIDE.md
+++ b/docs/CLI_GUIDE.md
@@ -577,4 +577,4 @@ See [CONTRIBUTING.md](../CONTRIBUTING.md) for detailed guidelines.
## License
-GoSQLX CLI is licensed under the MIT License. See [LICENSE](../LICENSE) for details.
\ No newline at end of file
+GoSQLX CLI is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0). See [LICENSE](../LICENSE) for details.
\ No newline at end of file
diff --git a/docs/COMPARISON.md b/docs/COMPARISON.md
index ec4baa8..8f74a98 100644
--- a/docs/COMPARISON.md
+++ b/docs/COMPARISON.md
@@ -26,7 +26,7 @@ This guide helps you choose the right SQL parsing tool for your needs. We provid
| **IDE Integration** | ⚠️ Planned | ✅ VSCode | ❌ No | ⚠️ Limited | ❌ No |
| **Config Files** | ⚠️ Planned | ✅ .sqlfluff | ⚠️ Limited | ⚠️ Limited | ❌ No |
| **Active Development** | ✅ Yes | ✅ Yes | ⚠️ Slow | ✅ Yes | ✅ Yes |
-| **License** | MIT | MIT | MIT | Apache 2.0 | BSD |
+| **License** | AGPL-3.0 | MIT | MIT | Apache 2.0 | BSD |
*pg_query uses PostgreSQL's official parser, so PostgreSQL compliance is 100%
diff --git a/pkg/sql/parser/sustained_load_test.go b/pkg/sql/parser/sustained_load_test.go
index 0cac504..afccc9a 100644
--- a/pkg/sql/parser/sustained_load_test.go
+++ b/pkg/sql/parser/sustained_load_test.go
@@ -20,6 +20,10 @@ func TestSustainedLoad_Tokenization10Seconds(t *testing.T) {
if testing.Short() {
t.Skip("Skipping sustained load test in short mode")
}
+ // Skip when race detector is enabled - adds 3-5x overhead making performance measurements unreliable
+ if raceEnabled {
+ t.Skip("Skipping sustained load test with race detector (adds 3-5x overhead)")
+ }
const (
duration = 10 * time.Second
@@ -93,6 +97,10 @@ func TestSustainedLoad_Parsing10Seconds(t *testing.T) {
if testing.Short() {
t.Skip("Skipping sustained load test in short mode")
}
+ // Skip when race detector is enabled - adds 3-5x overhead making performance measurements unreliable
+ if raceEnabled {
+ t.Skip("Skipping sustained load test with race detector (adds 3-5x overhead)")
+ }
const duration = 10 * time.Second
// Scale workers to available CPUs to avoid contention on smaller CI runners
@@ -207,6 +215,10 @@ func TestSustainedLoad_EndToEnd10Seconds(t *testing.T) {
if testing.Short() {
t.Skip("Skipping sustained load test in short mode")
}
+ // Skip when race detector is enabled - adds 3-5x overhead making performance measurements unreliable
+ if raceEnabled {
+ t.Skip("Skipping sustained load test with race detector (adds 3-5x overhead)")
+ }
const duration = 10 * time.Second
// Scale workers to available CPUs to avoid contention on smaller CI runners
@@ -342,6 +354,10 @@ func TestSustainedLoad_MemoryStability(t *testing.T) {
if testing.Short() {
t.Skip("Skipping sustained load test in short mode")
}
+ // Skip when race detector is enabled - adds 3-5x overhead making performance measurements unreliable
+ if raceEnabled {
+ t.Skip("Skipping sustained load test with race detector (adds 3-5x overhead)")
+ }
const duration = 10 * time.Second
// Scale workers to available CPUs to avoid contention on smaller CI runners
@@ -460,6 +476,10 @@ func TestSustainedLoad_VaryingWorkers(t *testing.T) {
if testing.Short() {
t.Skip("Skipping sustained load test in short mode")
}
+ // Skip when race detector is enabled - adds 3-5x overhead making performance measurements unreliable
+ if raceEnabled {
+ t.Skip("Skipping sustained load test with race detector (adds 3-5x overhead)")
+ }
// Reduce duration and worker counts when race detection is enabled
// to prevent test timeouts (race detection adds significant overhead)
@@ -523,6 +543,10 @@ func TestSustainedLoad_ComplexQueries(t *testing.T) {
if testing.Short() {
t.Skip("Skipping sustained load test in short mode")
}
+ // Skip when race detector is enabled - adds 3-5x overhead making performance measurements unreliable
+ if raceEnabled {
+ t.Skip("Skipping sustained load test with race detector (adds 3-5x overhead)")
+ }
const duration = 10 * time.Second
// Scale workers to available CPUs to avoid contention on smaller CI runners
diff --git a/pkg/sql/tokenizer/context_test.go b/pkg/sql/tokenizer/context_test.go
index 0fa190a..e136471 100644
--- a/pkg/sql/tokenizer/context_test.go
+++ b/pkg/sql/tokenizer/context_test.go
@@ -215,6 +215,11 @@ func TestTokenizeContext_ErrorHandling(t *testing.T) {
// TestTokenizeContext_CancellationResponseTime verifies fast cancellation (< 100ms requirement)
func TestTokenizeContext_CancellationResponseTime(t *testing.T) {
+ // Skip when race detector is enabled - adds 3-5x overhead making timing measurements unreliable
+ if raceEnabled {
+ t.Skip("Skipping timing-sensitive test with race detector (adds 3-5x overhead)")
+ }
+
ctx, cancel := context.WithCancel(context.Background())
tkz := GetTokenizer()
defer PutTokenizer(tkz)
diff --git a/pkg/sql/tokenizer/norace.go b/pkg/sql/tokenizer/norace.go
new file mode 100644
index 0000000..03f8f58
--- /dev/null
+++ b/pkg/sql/tokenizer/norace.go
@@ -0,0 +1,9 @@
+//go:build !race
+// +build !race
+
+package tokenizer
+
+// raceEnabled is set to false when the race detector is not enabled
+//
+//nolint:unused // Used conditionally based on build tags
+const raceEnabled = false
diff --git a/pkg/sql/tokenizer/race.go b/pkg/sql/tokenizer/race.go
new file mode 100644
index 0000000..99b1ff7
--- /dev/null
+++ b/pkg/sql/tokenizer/race.go
@@ -0,0 +1,9 @@
+//go:build race
+// +build race
+
+package tokenizer
+
+// raceEnabled is set to true when the race detector is enabled
+//
+//nolint:unused // Used conditionally based on build tags
+const raceEnabled = true
diff --git a/vscode-extension/.eslintrc.json b/vscode-extension/.eslintrc.json
new file mode 100644
index 0000000..1f276fb
--- /dev/null
+++ b/vscode-extension/.eslintrc.json
@@ -0,0 +1,28 @@
+{
+ "root": true,
+ "parser": "@typescript-eslint/parser",
+ "parserOptions": {
+ "ecmaVersion": 2022,
+ "sourceType": "module"
+ },
+ "plugins": ["@typescript-eslint"],
+ "extends": [
+ "eslint:recommended",
+ "plugin:@typescript-eslint/recommended"
+ ],
+ "rules": {
+ "@typescript-eslint/naming-convention": [
+ "warn",
+ {
+ "selector": "import",
+ "format": ["camelCase", "PascalCase"]
+ }
+ ],
+ "@typescript-eslint/semi": "warn",
+ "curly": "warn",
+ "eqeqeq": "warn",
+ "no-throw-literal": "warn",
+ "semi": "off"
+ },
+ "ignorePatterns": ["out", "dist", "**/*.d.ts"]
+}
diff --git a/vscode-extension/.gitignore b/vscode-extension/.gitignore
new file mode 100644
index 0000000..c6fe243
--- /dev/null
+++ b/vscode-extension/.gitignore
@@ -0,0 +1,6 @@
+out/
+dist/
+node_modules/
+.vscode-test/
+*.vsix
+.DS_Store
diff --git a/vscode-extension/.vscodeignore b/vscode-extension/.vscodeignore
new file mode 100644
index 0000000..8b470c6
--- /dev/null
+++ b/vscode-extension/.vscodeignore
@@ -0,0 +1,12 @@
+.vscode/**
+.vscode-test/**
+src/**
+.gitignore
+.yarnrc
+vsc-extension-quickstart.md
+**/tsconfig.json
+**/.eslintrc.json
+**/*.map
+**/*.ts
+node_modules/**
+.github/**
diff --git a/vscode-extension/CHANGELOG.md b/vscode-extension/CHANGELOG.md
new file mode 100644
index 0000000..7990444
--- /dev/null
+++ b/vscode-extension/CHANGELOG.md
@@ -0,0 +1,34 @@
+# Change Log
+
+All notable changes to the "GoSQLX" extension will be documented in this file.
+
+## [0.1.0] - 2025-11-27
+
+### Added
+- Initial release of GoSQLX VS Code extension
+- Real-time SQL validation via GoSQLX Language Server
+- SQL syntax highlighting with comprehensive TextMate grammar
+- SQL formatting with customizable options
+ - Configurable indent size
+ - Uppercase/lowercase keywords option
+- Intelligent autocomplete for SQL keywords and functions
+- Hover documentation for SQL keywords
+- SQL analysis command for query complexity analysis
+- Multi-dialect support (PostgreSQL, MySQL, SQL Server, Oracle, SQLite)
+- Extension settings panel
+- Command palette integration
+- Context menu integration
+- Status bar indicator
+- Output channel for debugging
+
+### Technical
+- Language Server Protocol (LSP) client implementation
+- TextMate grammar with patterns for:
+ - Comments (line and block)
+ - Strings (single, double, dollar-quoted, backtick)
+ - Numbers (integer, float, hex)
+ - Operators (comparison, arithmetic, JSON)
+ - Keywords (DML, DDL, joins, window functions, CTEs)
+ - Functions (aggregate, window, string, datetime, math, JSON, array)
+ - Data types (PostgreSQL comprehensive list)
+ - Parameters (positional and named)
diff --git a/vscode-extension/LICENSE b/vscode-extension/LICENSE
new file mode 100644
index 0000000..be3f7b2
--- /dev/null
+++ b/vscode-extension/LICENSE
@@ -0,0 +1,661 @@
+ GNU AFFERO GENERAL PUBLIC LICENSE
+ Version 3, 19 November 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU Affero General Public License is a free, copyleft license for
+software and other kinds of works, specifically designed to ensure
+cooperation with the community in the case of network server software.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+our General Public Licenses are intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ Developers that use our General Public Licenses protect your rights
+with two steps: (1) assert copyright on the software, and (2) offer
+you this License which gives you legal permission to copy, distribute
+and/or modify the software.
+
+ A secondary benefit of defending all users' freedom is that
+improvements made in alternate versions of the program, if they
+receive widespread use, become available for other developers to
+incorporate. Many developers of free software are heartened and
+encouraged by the resulting cooperation. However, in the case of
+software used on network servers, this result may fail to come about.
+The GNU General Public License permits making a modified version and
+letting the public access it on a server without ever releasing its
+source code to the public.
+
+ The GNU Affero General Public License is designed specifically to
+ensure that, in such cases, the modified source code becomes available
+to the community. It requires the operator of a network server to
+provide the source code of the modified version running there to the
+users of that server. Therefore, public use of a modified version, on
+a publicly accessible server, gives the public access to the source
+code of the modified version.
+
+ An older license, called the Affero General Public License and
+published by Affero, was designed to accomplish similar goals. This is
+a different license, not a version of the Affero GPL, but Affero has
+released a new version of the Affero GPL which permits relicensing under
+this license.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU Affero General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Remote Network Interaction; Use with the GNU General Public License.
+
+ Notwithstanding any other provision of this License, if you modify the
+Program, your modified version must prominently offer all users
+interacting with it remotely through a computer network (if your version
+supports such interaction) an opportunity to receive the Corresponding
+Source of your version by providing access to the Corresponding Source
+from a network server at no charge, through some standard or customary
+means of facilitating copying of software. This Corresponding Source
+shall include the Corresponding Source for any work covered by version 3
+of the GNU General Public License that is incorporated pursuant to the
+following paragraph.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the work with which it is combined will remain governed by version
+3 of the GNU General Public License.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU Affero General Public License from time to time. Such new versions
+will be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU Affero General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU Affero General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU Affero General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If your software can interact with users remotely through a computer
+network, you should also make sure that it provides a way for users to
+get its source. For example, if your program is a web application, its
+interface could display a "Source" link that leads users to an archive
+of the code. There are many ways you could offer source, and different
+solutions will be better for different programs; see section 13 for the
+specific requirements.
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU AGPL, see
+.
diff --git a/vscode-extension/README.md b/vscode-extension/README.md
new file mode 100644
index 0000000..1799c0e
--- /dev/null
+++ b/vscode-extension/README.md
@@ -0,0 +1,360 @@
+# GoSQLX - SQL Parser & Linter for VS Code
+
+High-performance SQL parsing, validation, formatting, and analysis powered by [GoSQLX](https://github.com/ajitpratap0/GoSQLX).
+
+## Features
+
+### Real-time SQL Validation
+Get instant feedback on SQL syntax errors as you type. Errors are highlighted directly in the editor with detailed messages in the Problems panel.
+
+### SQL Formatting
+Format your SQL code with customizable indentation and keyword casing.
+
+- **Keyboard shortcut**: `Ctrl+Shift+F` (Windows/Linux) or `Cmd+Shift+F` (Mac)
+- **Command palette**: "GoSQLX: Format SQL"
+- **Right-click menu**: Format SQL
+
+### Intelligent Autocomplete
+Get context-aware suggestions for:
+- SQL keywords (100+ supported)
+- SQL functions with signatures
+- Common SQL snippets and patterns
+
+### Hover Documentation
+Hover over SQL keywords to see documentation and usage examples.
+
+### SQL Analysis
+Analyze query complexity, find potential issues, and get optimization suggestions.
+
+### Multi-Dialect Support
+Full support for database-specific syntax:
+- **PostgreSQL**: Dollar-quoted strings, JSONB operators, array operations, window functions
+- **MySQL**: Backtick identifiers, LIMIT/OFFSET syntax, GROUP_CONCAT, hash comments
+- **SQL Server**: Bracket identifiers, TOP clause, CROSS/OUTER APPLY, TRY/CATCH
+- **Oracle**: CONNECT BY hierarchical queries, ROWNUM, DECODE, MODEL clause
+- **SQLite**: Lightweight syntax, ATTACH/DETACH, FTS full-text search
+- **Generic SQL**: Standard SQL-99 compliance
+
+## Requirements
+
+You need to have the `gosqlx` CLI tool installed:
+
+```bash
+# Install via Go
+go install github.com/ajitpratap0/GoSQLX/cmd/gosqlx@latest
+
+# Verify installation
+gosqlx --version
+```
+
+Make sure `gosqlx` is in your system PATH.
+
+### Platform-Specific Installation
+
+**macOS/Linux:**
+```bash
+# Add Go bin to PATH (add to ~/.bashrc or ~/.zshrc)
+export PATH="$PATH:$(go env GOPATH)/bin"
+
+# Reload shell
+source ~/.bashrc # or source ~/.zshrc
+```
+
+**Windows:**
+```powershell
+# Add Go bin to PATH (run in PowerShell as Admin)
+$env:Path += ";$(go env GOPATH)\bin"
+
+# Or permanently via System Properties > Environment Variables
+# Add: %USERPROFILE%\go\bin
+```
+
+## Extension Settings
+
+This extension contributes the following settings:
+
+| Setting | Default | Scope | Description |
+|---------|---------|-------|-------------|
+| `gosqlx.enable` | `true` | Resource | Enable GoSQLX language server |
+| `gosqlx.executablePath` | `gosqlx` | Machine | Path to the gosqlx executable |
+| `gosqlx.trace.server` | `off` | Window | Traces communication with the language server |
+| `gosqlx.format.indentSize` | `2` | Resource | Number of spaces for indentation |
+| `gosqlx.format.uppercaseKeywords` | `true` | Resource | Convert keywords to uppercase |
+| `gosqlx.validation.enable` | `true` | Resource | Enable real-time SQL validation |
+| `gosqlx.dialect` | `generic` | Resource | SQL dialect for validation |
+| `gosqlx.timeouts.startup` | `10000` | Window | Language server startup timeout (ms) |
+| `gosqlx.timeouts.validation` | `5000` | Window | Executable validation timeout (ms) |
+| `gosqlx.timeouts.analysis` | `30000` | Window | SQL analysis timeout (ms) |
+| `gosqlx.telemetry.enable` | `false` | Global | Enable anonymous usage telemetry |
+| `gosqlx.performance.showStatusBar` | `false` | Window | Show performance metrics in status bar |
+| `gosqlx.performance.collectMetrics` | `true` | Window | Collect performance metrics |
+
+### Workspace Settings
+
+Settings with `Resource` scope can be configured per-workspace in `.vscode/settings.json`:
+
+```json
+{
+ "gosqlx.dialect": "postgresql",
+ "gosqlx.format.indentSize": 4,
+ "gosqlx.format.uppercaseKeywords": false
+}
+```
+
+## Commands
+
+| Command | Description |
+|---------|-------------|
+| `GoSQLX: Validate SQL` | Validate the current SQL file |
+| `GoSQLX: Format SQL` | Format the current SQL file |
+| `GoSQLX: Analyze SQL` | Analyze query complexity and structure |
+| `GoSQLX: Restart Language Server` | Restart the GoSQLX language server |
+| `GoSQLX: Show Output Channel` | Show the GoSQLX output channel |
+| `GoSQLX: Show Performance Metrics` | Display performance statistics |
+| `GoSQLX: Validate Configuration` | Check configuration for errors |
+
+## Performance
+
+GoSQLX delivers exceptional performance:
+
+| Operation | Speed |
+|-----------|-------|
+| Validation | 1.38M+ ops/sec |
+| Formatting | 2,600+ files/sec |
+| Parsing | 1.5M+ ops/sec |
+
+## Troubleshooting
+
+### Language server not starting
+
+**Symptom**: Status bar shows "GoSQLX: Executable not found"
+
+1. **Verify gosqlx is installed:**
+ ```bash
+ # macOS/Linux
+ which gosqlx
+ gosqlx --version
+
+ # Windows
+ where gosqlx
+ gosqlx --version
+ ```
+
+2. **Check PATH configuration:**
+ ```bash
+ # macOS/Linux - verify GOPATH/bin is in PATH
+ echo $PATH | grep -o "$(go env GOPATH)/bin"
+
+ # If not found, add to shell profile:
+ echo 'export PATH="$PATH:$(go env GOPATH)/bin"' >> ~/.bashrc
+ source ~/.bashrc
+ ```
+
+3. **Specify full path in settings:**
+ ```json
+ {
+ "gosqlx.executablePath": "/full/path/to/gosqlx"
+ }
+ ```
+
+4. **Check the output channel:**
+ - Open Command Palette (`Ctrl+Shift+P`)
+ - Run "GoSQLX: Show Output Channel"
+
+### Permission denied errors
+
+**Symptom**: "EACCES" or "permission denied" errors
+
+**macOS/Linux:**
+```bash
+# Check permissions
+ls -la $(which gosqlx)
+
+# Fix permissions
+chmod +x $(which gosqlx)
+```
+
+**Windows:**
+- Run VS Code as Administrator
+- Check Windows Defender/antivirus settings
+- Verify the executable is not blocked (Properties > Unblock)
+
+### Timeout errors
+
+**Symptom**: "Analysis timed out" or "startup timeout"
+
+1. **Increase timeout settings:**
+ ```json
+ {
+ "gosqlx.timeouts.startup": 30000,
+ "gosqlx.timeouts.analysis": 60000
+ }
+ ```
+
+2. **Check system resources:**
+ - Close resource-intensive applications
+ - Check CPU/memory usage
+
+3. **Try with simpler SQL:**
+ - Complex queries may take longer
+ - Break down large queries for analysis
+
+### Validation not working
+
+**Symptom**: No syntax errors shown for invalid SQL
+
+1. **Verify language detection:**
+ - Ensure the file has a `.sql` extension
+ - Check status bar shows "SQL" as language
+
+2. **Check validation is enabled:**
+ ```json
+ {
+ "gosqlx.validation.enable": true
+ }
+ ```
+
+3. **Restart the language server:**
+ - Run "GoSQLX: Restart Language Server"
+
+4. **Verify dialect setting:**
+ - Some syntax is dialect-specific
+ - Try `"gosqlx.dialect": "generic"`
+
+### Formatting issues
+
+**Symptom**: Format command does nothing or produces unexpected results
+
+1. **Check for syntax errors:**
+ - Files with syntax errors may not format correctly
+ - Fix errors first, then format
+
+2. **Verify language server is running:**
+ - Status bar should show "GoSQLX" (not error state)
+ - Try restarting the server
+
+3. **Check format settings:**
+ ```json
+ {
+ "gosqlx.format.indentSize": 2,
+ "gosqlx.format.uppercaseKeywords": true
+ }
+ ```
+
+### Remote development issues
+
+**Symptom**: Extension not working in Remote SSH/WSL/Container
+
+1. **Install gosqlx in remote environment:**
+ ```bash
+ # Run in remote terminal
+ go install github.com/ajitpratap0/GoSQLX/cmd/gosqlx@latest
+ ```
+
+2. **Configure remote PATH:**
+ - Add Go bin to PATH in remote shell profile
+ - Restart remote VS Code window
+
+3. **Use remote-specific settings:**
+ ```json
+ // Remote settings
+ {
+ "gosqlx.executablePath": "/home/user/go/bin/gosqlx"
+ }
+ ```
+
+### Connection reset errors
+
+**Symptom**: "ECONNRESET" or "connection reset"
+
+1. **Restart VS Code:**
+ - Close all VS Code windows
+ - Reopen the workspace
+
+2. **Check for zombie processes:**
+ ```bash
+ # macOS/Linux
+ ps aux | grep gosqlx
+ kill # if found
+
+ # Windows
+ tasklist | findstr gosqlx
+ taskkill /F /PID
+ ```
+
+3. **Check system sleep/resume:**
+ - Connections may break after sleep
+ - Restart language server after wake
+
+### Version mismatch errors
+
+**Symptom**: "JSON parse error" or unexpected responses
+
+1. **Update gosqlx:**
+ ```bash
+ go install github.com/ajitpratap0/GoSQLX/cmd/gosqlx@latest
+ ```
+
+2. **Verify version:**
+ ```bash
+ gosqlx --version
+ ```
+
+3. **Check extension version:**
+ - Update extension to latest version
+ - Restart VS Code
+
+### Debug logging
+
+For persistent issues, enable verbose logging:
+
+```json
+{
+ "gosqlx.trace.server": "verbose"
+}
+```
+
+Then check the output channel for detailed logs.
+
+## Telemetry
+
+GoSQLX can collect anonymous usage data to help improve the extension. This is **disabled by default**.
+
+When enabled:
+- **What we collect**: Command usage counts, operation durations, error codes
+- **What we NEVER collect**: SQL content, file paths, personal information
+
+To opt in:
+```json
+{
+ "gosqlx.telemetry.enable": true
+}
+```
+
+Telemetry also respects VS Code's global telemetry setting.
+
+## Contributing
+
+Contributions are welcome! Please see our [Contributing Guide](https://github.com/ajitpratap0/GoSQLX/blob/main/CONTRIBUTING.md).
+
+## License
+
+GNU Affero General Public License v3.0 (AGPL-3.0) - see [LICENSE](https://github.com/ajitpratap0/GoSQLX/blob/main/LICENSE)
+
+## Release Notes
+
+### 0.1.0
+
+Initial release:
+- Real-time SQL validation
+- SQL formatting with customizable options
+- Syntax highlighting for SQL with multi-dialect support
+- Intelligent autocomplete
+- Hover documentation
+- SQL analysis command
+- Multi-dialect support (PostgreSQL, MySQL, SQL Server, Oracle, SQLite)
+- Configurable timeouts
+- Performance metrics
+- Configuration validation
+- Enhanced error messaging with actionable suggestions
+- Workspace settings support
diff --git a/vscode-extension/images/icon.svg b/vscode-extension/images/icon.svg
new file mode 100644
index 0000000..dc6d60d
--- /dev/null
+++ b/vscode-extension/images/icon.svg
@@ -0,0 +1,26 @@
+
diff --git a/vscode-extension/language-configuration.json b/vscode-extension/language-configuration.json
new file mode 100644
index 0000000..6180c0e
--- /dev/null
+++ b/vscode-extension/language-configuration.json
@@ -0,0 +1,39 @@
+{
+ "comments": {
+ "lineComment": "--",
+ "blockComment": ["/*", "*/"]
+ },
+ "brackets": [
+ ["(", ")"],
+ ["[", "]"],
+ ["{", "}"]
+ ],
+ "autoClosingPairs": [
+ { "open": "(", "close": ")" },
+ { "open": "[", "close": "]" },
+ { "open": "{", "close": "}" },
+ { "open": "'", "close": "'", "notIn": ["string", "comment"] },
+ { "open": "\"", "close": "\"", "notIn": ["string", "comment"] },
+ { "open": "`", "close": "`", "notIn": ["string", "comment"] },
+ { "open": "/*", "close": "*/", "notIn": ["string"] }
+ ],
+ "surroundingPairs": [
+ ["(", ")"],
+ ["[", "]"],
+ ["{", "}"],
+ ["'", "'"],
+ ["\"", "\""],
+ ["`", "`"]
+ ],
+ "folding": {
+ "markers": {
+ "start": "(?i)^\\s*(BEGIN|CASE|IF|LOOP|WHILE|FOR|CREATE|WITH)\\b",
+ "end": "(?i)^\\s*(END|;)\\s*$"
+ }
+ },
+ "wordPattern": "[\\w$#@]+",
+ "indentationRules": {
+ "increaseIndentPattern": "(?i)^\\s*(SELECT|FROM|WHERE|AND|OR|JOIN|LEFT|RIGHT|INNER|OUTER|CROSS|GROUP|ORDER|HAVING|UNION|INTERSECT|EXCEPT|CASE|WHEN|ELSE|BEGIN|IF|LOOP|WHILE|FOR|WITH)\\b",
+ "decreaseIndentPattern": "(?i)^\\s*(END|;|\\)|\\])\\s*$"
+ }
+}
diff --git a/vscode-extension/package-lock.json b/vscode-extension/package-lock.json
new file mode 100644
index 0000000..f755e62
--- /dev/null
+++ b/vscode-extension/package-lock.json
@@ -0,0 +1,5660 @@
+{
+ "name": "gosqlx",
+ "version": "0.1.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "gosqlx",
+ "version": "0.1.0",
+ "license": "MIT",
+ "dependencies": {
+ "vscode-languageclient": "^9.0.1"
+ },
+ "devDependencies": {
+ "@types/glob": "^8.1.0",
+ "@types/mocha": "^10.0.6",
+ "@types/node": "^20.10.0",
+ "@types/vscode": "^1.85.0",
+ "@typescript-eslint/eslint-plugin": "^6.13.0",
+ "@typescript-eslint/parser": "^6.13.0",
+ "@vscode/test-electron": "^2.3.8",
+ "@vscode/vsce": "^2.22.0",
+ "eslint": "^8.54.0",
+ "glob": "^10.3.10",
+ "mocha": "^10.2.0",
+ "typescript": "^5.3.2"
+ },
+ "engines": {
+ "vscode": "^1.85.0"
+ }
+ },
+ "node_modules/@azure/abort-controller": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz",
+ "integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@azure/core-auth": {
+ "version": "1.10.1",
+ "resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.10.1.tgz",
+ "integrity": "sha512-ykRMW8PjVAn+RS6ww5cmK9U2CyH9p4Q88YJwvUslfuMmN98w/2rdGRLPqJYObapBCdzBVeDgYWdJnFPFb7qzpg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@azure/abort-controller": "^2.1.2",
+ "@azure/core-util": "^1.13.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@azure/core-client": {
+ "version": "1.10.1",
+ "resolved": "https://registry.npmjs.org/@azure/core-client/-/core-client-1.10.1.tgz",
+ "integrity": "sha512-Nh5PhEOeY6PrnxNPsEHRr9eimxLwgLlpmguQaHKBinFYA/RU9+kOYVOQqOrTsCL+KSxrLLl1gD8Dk5BFW/7l/w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@azure/abort-controller": "^2.1.2",
+ "@azure/core-auth": "^1.10.0",
+ "@azure/core-rest-pipeline": "^1.22.0",
+ "@azure/core-tracing": "^1.3.0",
+ "@azure/core-util": "^1.13.0",
+ "@azure/logger": "^1.3.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@azure/core-rest-pipeline": {
+ "version": "1.22.2",
+ "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.22.2.tgz",
+ "integrity": "sha512-MzHym+wOi8CLUlKCQu12de0nwcq9k9Kuv43j4Wa++CsCpJwps2eeBQwD2Bu8snkxTtDKDx4GwjuR9E8yC8LNrg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@azure/abort-controller": "^2.1.2",
+ "@azure/core-auth": "^1.10.0",
+ "@azure/core-tracing": "^1.3.0",
+ "@azure/core-util": "^1.13.0",
+ "@azure/logger": "^1.3.0",
+ "@typespec/ts-http-runtime": "^0.3.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@azure/core-tracing": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.3.1.tgz",
+ "integrity": "sha512-9MWKevR7Hz8kNzzPLfX4EAtGM2b8mr50HPDBvio96bURP/9C+HjdH3sBlLSNNrvRAr5/k/svoH457gB5IKpmwQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@azure/core-util": {
+ "version": "1.13.1",
+ "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.13.1.tgz",
+ "integrity": "sha512-XPArKLzsvl0Hf0CaGyKHUyVgF7oDnhKoP85Xv6M4StF/1AhfORhZudHtOyf2s+FcbuQ9dPRAjB8J2KvRRMUK2A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@azure/abort-controller": "^2.1.2",
+ "@typespec/ts-http-runtime": "^0.3.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@azure/identity": {
+ "version": "4.13.0",
+ "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-4.13.0.tgz",
+ "integrity": "sha512-uWC0fssc+hs1TGGVkkghiaFkkS7NkTxfnCH+Hdg+yTehTpMcehpok4PgUKKdyCH+9ldu6FhiHRv84Ntqj1vVcw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@azure/abort-controller": "^2.0.0",
+ "@azure/core-auth": "^1.9.0",
+ "@azure/core-client": "^1.9.2",
+ "@azure/core-rest-pipeline": "^1.17.0",
+ "@azure/core-tracing": "^1.0.0",
+ "@azure/core-util": "^1.11.0",
+ "@azure/logger": "^1.0.0",
+ "@azure/msal-browser": "^4.2.0",
+ "@azure/msal-node": "^3.5.0",
+ "open": "^10.1.0",
+ "tslib": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@azure/logger": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.3.0.tgz",
+ "integrity": "sha512-fCqPIfOcLE+CGqGPd66c8bZpwAji98tZ4JI9i/mlTNTlsIWslCfpg48s/ypyLxZTump5sypjrKn2/kY7q8oAbA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typespec/ts-http-runtime": "^0.3.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@azure/msal-browser": {
+ "version": "4.26.2",
+ "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-4.26.2.tgz",
+ "integrity": "sha512-F2U1mEAFsYGC5xzo1KuWc/Sy3CRglU9Ql46cDUx8x/Y3KnAIr1QAq96cIKCk/ZfnVxlvprXWRjNKoEpgLJXLhg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@azure/msal-common": "15.13.2"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/@azure/msal-common": {
+ "version": "15.13.2",
+ "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-15.13.2.tgz",
+ "integrity": "sha512-cNwUoCk3FF8VQ7Ln/MdcJVIv3sF73/OT86cRH81ECsydh7F4CNfIo2OAx6Cegtg8Yv75x4506wN4q+Emo6erOA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/@azure/msal-node": {
+ "version": "3.8.3",
+ "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-3.8.3.tgz",
+ "integrity": "sha512-Ul7A4gwmaHzYWj2Z5xBDly/W8JSC1vnKgJ898zPMZr0oSf1ah0tiL15sytjycU/PMhDZAlkWtEL1+MzNMU6uww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@azure/msal-common": "15.13.2",
+ "jsonwebtoken": "^9.0.0",
+ "uuid": "^8.3.0"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils": {
+ "version": "4.9.0",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz",
+ "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eslint-visitor-keys": "^3.4.3"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
+ }
+ },
+ "node_modules/@eslint-community/regexpp": {
+ "version": "4.12.2",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz",
+ "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@eslint/eslintrc": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz",
+ "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "^6.12.4",
+ "debug": "^4.3.2",
+ "espree": "^9.6.0",
+ "globals": "^13.19.0",
+ "ignore": "^5.2.0",
+ "import-fresh": "^3.2.1",
+ "js-yaml": "^4.1.0",
+ "minimatch": "^3.1.2",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/brace-expansion": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/@eslint/js": {
+ "version": "8.57.1",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz",
+ "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@humanwhocodes/config-array": {
+ "version": "0.13.0",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz",
+ "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==",
+ "deprecated": "Use @eslint/config-array instead",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@humanwhocodes/object-schema": "^2.0.3",
+ "debug": "^4.3.1",
+ "minimatch": "^3.0.5"
+ },
+ "engines": {
+ "node": ">=10.10.0"
+ }
+ },
+ "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/@humanwhocodes/config-array/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/@humanwhocodes/module-importer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+ "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=12.22"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@humanwhocodes/object-schema": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz",
+ "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
+ "deprecated": "Use @eslint/object-schema instead",
+ "dev": true,
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@isaacs/cliui": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
+ "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^5.1.2",
+ "string-width-cjs": "npm:string-width@^4.2.0",
+ "strip-ansi": "^7.0.1",
+ "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
+ "wrap-ansi": "^8.1.0",
+ "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@isaacs/cliui/node_modules/ansi-regex": {
+ "version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
+ "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/@isaacs/cliui/node_modules/emoji-regex": {
+ "version": "9.2.2",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
+ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@isaacs/cliui/node_modules/string-width": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
+ "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eastasianwidth": "^0.2.0",
+ "emoji-regex": "^9.2.2",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@isaacs/cliui/node_modules/strip-ansi": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz",
+ "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@pkgjs/parseargs": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
+ "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/@types/glob": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/@types/glob/-/glob-8.1.0.tgz",
+ "integrity": "sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/minimatch": "^5.1.2",
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/json-schema": {
+ "version": "7.0.15",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/minimatch": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz",
+ "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/mocha": {
+ "version": "10.0.10",
+ "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.10.tgz",
+ "integrity": "sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/node": {
+ "version": "20.19.25",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.25.tgz",
+ "integrity": "sha512-ZsJzA5thDQMSQO788d7IocwwQbI8B5OPzmqNvpf3NY/+MHDAS759Wo0gd2WQeXYt5AAAQjzcrTVC6SKCuYgoCQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~6.21.0"
+ }
+ },
+ "node_modules/@types/semver": {
+ "version": "7.7.1",
+ "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.7.1.tgz",
+ "integrity": "sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/vscode": {
+ "version": "1.106.1",
+ "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.106.1.tgz",
+ "integrity": "sha512-R/HV8u2h8CAddSbX8cjpdd7B8/GnE4UjgjpuGuHcbp1xV6yh4OeqU4L1pKjlwujCrSFS0MOpwJAIs/NexMB1fQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@typescript-eslint/eslint-plugin": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz",
+ "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/regexpp": "^4.5.1",
+ "@typescript-eslint/scope-manager": "6.21.0",
+ "@typescript-eslint/type-utils": "6.21.0",
+ "@typescript-eslint/utils": "6.21.0",
+ "@typescript-eslint/visitor-keys": "6.21.0",
+ "debug": "^4.3.4",
+ "graphemer": "^1.4.0",
+ "ignore": "^5.2.4",
+ "natural-compare": "^1.4.0",
+ "semver": "^7.5.4",
+ "ts-api-utils": "^1.0.1"
+ },
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha",
+ "eslint": "^7.0.0 || ^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/parser": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz",
+ "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "peer": true,
+ "dependencies": {
+ "@typescript-eslint/scope-manager": "6.21.0",
+ "@typescript-eslint/types": "6.21.0",
+ "@typescript-eslint/typescript-estree": "6.21.0",
+ "@typescript-eslint/visitor-keys": "6.21.0",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^7.0.0 || ^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/scope-manager": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz",
+ "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "6.21.0",
+ "@typescript-eslint/visitor-keys": "6.21.0"
+ },
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/type-utils": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz",
+ "integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/typescript-estree": "6.21.0",
+ "@typescript-eslint/utils": "6.21.0",
+ "debug": "^4.3.4",
+ "ts-api-utils": "^1.0.1"
+ },
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^7.0.0 || ^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/types": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz",
+ "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz",
+ "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "@typescript-eslint/types": "6.21.0",
+ "@typescript-eslint/visitor-keys": "6.21.0",
+ "debug": "^4.3.4",
+ "globby": "^11.1.0",
+ "is-glob": "^4.0.3",
+ "minimatch": "9.0.3",
+ "semver": "^7.5.4",
+ "ts-api-utils": "^1.0.1"
+ },
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/utils": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz",
+ "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.4.0",
+ "@types/json-schema": "^7.0.12",
+ "@types/semver": "^7.5.0",
+ "@typescript-eslint/scope-manager": "6.21.0",
+ "@typescript-eslint/types": "6.21.0",
+ "@typescript-eslint/typescript-estree": "6.21.0",
+ "semver": "^7.5.4"
+ },
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/visitor-keys": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz",
+ "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "6.21.0",
+ "eslint-visitor-keys": "^3.4.1"
+ },
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typespec/ts-http-runtime": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/@typespec/ts-http-runtime/-/ts-http-runtime-0.3.2.tgz",
+ "integrity": "sha512-IlqQ/Gv22xUC1r/WQm4StLkYQmaaTsXAhUVsNE0+xiyf0yRFiH5++q78U3bw6bLKDCTmh0uqKB9eG9+Bt75Dkg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "http-proxy-agent": "^7.0.0",
+ "https-proxy-agent": "^7.0.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@ungap/structured-clone": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz",
+ "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/@vscode/test-electron": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/@vscode/test-electron/-/test-electron-2.5.2.tgz",
+ "integrity": "sha512-8ukpxv4wYe0iWMRQU18jhzJOHkeGKbnw7xWRX3Zw1WJA4cEKbHcmmLPdPrPtL6rhDcrlCZN+xKRpv09n4gRHYg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "http-proxy-agent": "^7.0.2",
+ "https-proxy-agent": "^7.0.5",
+ "jszip": "^3.10.1",
+ "ora": "^8.1.0",
+ "semver": "^7.6.2"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@vscode/vsce": {
+ "version": "2.32.0",
+ "resolved": "https://registry.npmjs.org/@vscode/vsce/-/vsce-2.32.0.tgz",
+ "integrity": "sha512-3EFJfsgrSftIqt3EtdRcAygy/OJ3hstyI1cDmIgkU9CFZW5C+3djr6mfosndCUqcVYuyjmxOK1xmFp/Bq7+NIg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@azure/identity": "^4.1.0",
+ "@vscode/vsce-sign": "^2.0.0",
+ "azure-devops-node-api": "^12.5.0",
+ "chalk": "^2.4.2",
+ "cheerio": "^1.0.0-rc.9",
+ "cockatiel": "^3.1.2",
+ "commander": "^6.2.1",
+ "form-data": "^4.0.0",
+ "glob": "^7.0.6",
+ "hosted-git-info": "^4.0.2",
+ "jsonc-parser": "^3.2.0",
+ "leven": "^3.1.0",
+ "markdown-it": "^12.3.2",
+ "mime": "^1.3.4",
+ "minimatch": "^3.0.3",
+ "parse-semver": "^1.1.1",
+ "read": "^1.0.7",
+ "semver": "^7.5.2",
+ "tmp": "^0.2.1",
+ "typed-rest-client": "^1.8.4",
+ "url-join": "^4.0.1",
+ "xml2js": "^0.5.0",
+ "yauzl": "^2.3.1",
+ "yazl": "^2.2.2"
+ },
+ "bin": {
+ "vsce": "vsce"
+ },
+ "engines": {
+ "node": ">= 16"
+ },
+ "optionalDependencies": {
+ "keytar": "^7.7.0"
+ }
+ },
+ "node_modules/@vscode/vsce-sign": {
+ "version": "2.0.9",
+ "resolved": "https://registry.npmjs.org/@vscode/vsce-sign/-/vsce-sign-2.0.9.tgz",
+ "integrity": "sha512-8IvaRvtFyzUnGGl3f5+1Cnor3LqaUWvhaUjAYO8Y39OUYlOf3cRd+dowuQYLpZcP3uwSG+mURwjEBOSq4SOJ0g==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "SEE LICENSE IN LICENSE.txt",
+ "optionalDependencies": {
+ "@vscode/vsce-sign-alpine-arm64": "2.0.6",
+ "@vscode/vsce-sign-alpine-x64": "2.0.6",
+ "@vscode/vsce-sign-darwin-arm64": "2.0.6",
+ "@vscode/vsce-sign-darwin-x64": "2.0.6",
+ "@vscode/vsce-sign-linux-arm": "2.0.6",
+ "@vscode/vsce-sign-linux-arm64": "2.0.6",
+ "@vscode/vsce-sign-linux-x64": "2.0.6",
+ "@vscode/vsce-sign-win32-arm64": "2.0.6",
+ "@vscode/vsce-sign-win32-x64": "2.0.6"
+ }
+ },
+ "node_modules/@vscode/vsce-sign-alpine-arm64": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-alpine-arm64/-/vsce-sign-alpine-arm64-2.0.6.tgz",
+ "integrity": "sha512-wKkJBsvKF+f0GfsUuGT0tSW0kZL87QggEiqNqK6/8hvqsXvpx8OsTEc3mnE1kejkh5r+qUyQ7PtF8jZYN0mo8Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "SEE LICENSE IN LICENSE.txt",
+ "optional": true,
+ "os": [
+ "alpine"
+ ]
+ },
+ "node_modules/@vscode/vsce-sign-alpine-x64": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-alpine-x64/-/vsce-sign-alpine-x64-2.0.6.tgz",
+ "integrity": "sha512-YoAGlmdK39vKi9jA18i4ufBbd95OqGJxRvF3n6ZbCyziwy3O+JgOpIUPxv5tjeO6gQfx29qBivQ8ZZTUF2Ba0w==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "SEE LICENSE IN LICENSE.txt",
+ "optional": true,
+ "os": [
+ "alpine"
+ ]
+ },
+ "node_modules/@vscode/vsce-sign-darwin-arm64": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-darwin-arm64/-/vsce-sign-darwin-arm64-2.0.6.tgz",
+ "integrity": "sha512-5HMHaJRIQuozm/XQIiJiA0W9uhdblwwl2ZNDSSAeXGO9YhB9MH5C4KIHOmvyjUnKy4UCuiP43VKpIxW1VWP4tQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "SEE LICENSE IN LICENSE.txt",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@vscode/vsce-sign-darwin-x64": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-darwin-x64/-/vsce-sign-darwin-x64-2.0.6.tgz",
+ "integrity": "sha512-25GsUbTAiNfHSuRItoQafXOIpxlYj+IXb4/qarrXu7kmbH94jlm5sdWSCKrrREs8+GsXF1b+l3OB7VJy5jsykw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "SEE LICENSE IN LICENSE.txt",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@vscode/vsce-sign-linux-arm": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-linux-arm/-/vsce-sign-linux-arm-2.0.6.tgz",
+ "integrity": "sha512-UndEc2Xlq4HsuMPnwu7420uqceXjs4yb5W8E2/UkaHBB9OWCwMd3/bRe/1eLe3D8kPpxzcaeTyXiK3RdzS/1CA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "SEE LICENSE IN LICENSE.txt",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@vscode/vsce-sign-linux-arm64": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-linux-arm64/-/vsce-sign-linux-arm64-2.0.6.tgz",
+ "integrity": "sha512-cfb1qK7lygtMa4NUl2582nP7aliLYuDEVpAbXJMkDq1qE+olIw/es+C8j1LJwvcRq1I2yWGtSn3EkDp9Dq5FdA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "SEE LICENSE IN LICENSE.txt",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@vscode/vsce-sign-linux-x64": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-linux-x64/-/vsce-sign-linux-x64-2.0.6.tgz",
+ "integrity": "sha512-/olerl1A4sOqdP+hjvJ1sbQjKN07Y3DVnxO4gnbn/ahtQvFrdhUi0G1VsZXDNjfqmXw57DmPi5ASnj/8PGZhAA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "SEE LICENSE IN LICENSE.txt",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@vscode/vsce-sign-win32-arm64": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-win32-arm64/-/vsce-sign-win32-arm64-2.0.6.tgz",
+ "integrity": "sha512-ivM/MiGIY0PJNZBoGtlRBM/xDpwbdlCWomUWuLmIxbi1Cxe/1nooYrEQoaHD8ojVRgzdQEUzMsRbyF5cJJgYOg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "SEE LICENSE IN LICENSE.txt",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@vscode/vsce-sign-win32-x64": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-win32-x64/-/vsce-sign-win32-x64-2.0.6.tgz",
+ "integrity": "sha512-mgth9Kvze+u8CruYMmhHw6Zgy3GRX2S+Ed5oSokDEK5vPEwGGKnmuXua9tmFhomeAnhgJnL4DCna3TiNuGrBTQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "SEE LICENSE IN LICENSE.txt",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@vscode/vsce/node_modules/brace-expansion": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/@vscode/vsce/node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@vscode/vsce/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/acorn": {
+ "version": "8.15.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
+ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-jsx": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/agent-base": {
+ "version": "7.1.4",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz",
+ "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ansi-colors": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz",
+ "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/anymatch": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+ "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true,
+ "license": "Python-2.0"
+ },
+ "node_modules/array-union": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/azure-devops-node-api": {
+ "version": "12.5.0",
+ "resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-12.5.0.tgz",
+ "integrity": "sha512-R5eFskGvOm3U/GzeAuxRkUsAl0hrAwGgWn6zAd2KrZmrEhWZVqLew4OOupbQlXUuojUzpGtq62SmdhJ06N88og==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tunnel": "0.0.6",
+ "typed-rest-client": "^1.8.4"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "license": "MIT"
+ },
+ "node_modules/base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/binary-extensions": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
+ "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/bl": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
+ "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "buffer": "^5.5.0",
+ "inherits": "^2.0.4",
+ "readable-stream": "^3.4.0"
+ }
+ },
+ "node_modules/bl/node_modules/readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/boolbase": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+ "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/brace-expansion": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
+ "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fill-range": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/browser-stdout": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
+ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/buffer": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
+ "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.1.13"
+ }
+ },
+ "node_modules/buffer-crc32": {
+ "version": "0.2.13",
+ "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
+ "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/buffer-equal-constant-time": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
+ "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==",
+ "dev": true,
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/bundle-name": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz",
+ "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "run-applescript": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/call-bind-apply-helpers": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
+ "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/call-bound": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
+ "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "get-intrinsic": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/camelcase": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
+ "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/cheerio": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.1.2.tgz",
+ "integrity": "sha512-IkxPpb5rS/d1IiLbHMgfPuS0FgiWTtFIm/Nj+2woXDLTZ7fOT2eqzgYbdMlLweqlHbsZjxEChoVK+7iph7jyQg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cheerio-select": "^2.1.0",
+ "dom-serializer": "^2.0.0",
+ "domhandler": "^5.0.3",
+ "domutils": "^3.2.2",
+ "encoding-sniffer": "^0.2.1",
+ "htmlparser2": "^10.0.0",
+ "parse5": "^7.3.0",
+ "parse5-htmlparser2-tree-adapter": "^7.1.0",
+ "parse5-parser-stream": "^7.1.2",
+ "undici": "^7.12.0",
+ "whatwg-mimetype": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=20.18.1"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/cheerio?sponsor=1"
+ }
+ },
+ "node_modules/cheerio-select": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz",
+ "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "boolbase": "^1.0.0",
+ "css-select": "^5.1.0",
+ "css-what": "^6.1.0",
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3",
+ "domutils": "^3.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/chokidar": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
+ "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/chokidar/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/chownr": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
+ "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
+ "dev": true,
+ "license": "ISC",
+ "optional": true
+ },
+ "node_modules/cli-cursor": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz",
+ "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "restore-cursor": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cli-spinners": {
+ "version": "2.9.2",
+ "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz",
+ "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cliui": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
+ "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0",
+ "wrap-ansi": "^7.0.0"
+ }
+ },
+ "node_modules/cliui/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/cliui/node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/cliui/node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cliui/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cliui/node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cliui/node_modules/wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/cockatiel": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/cockatiel/-/cockatiel-3.2.1.tgz",
+ "integrity": "sha512-gfrHV6ZPkquExvMh9IOkKsBzNDk6sDuZ6DdBGUBkvFnTCqCxzpuq48RySgP0AnaqQkw2zynOFj9yly6T1Q2G5Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "delayed-stream": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/commander": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz",
+ "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/core-util-is": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
+ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/css-select": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz",
+ "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "boolbase": "^1.0.0",
+ "css-what": "^6.1.0",
+ "domhandler": "^5.0.2",
+ "domutils": "^3.0.1",
+ "nth-check": "^2.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/css-what": {
+ "version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz",
+ "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">= 6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/debug": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/decamelize": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz",
+ "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/decompress-response": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
+ "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "mimic-response": "^3.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/deep-extend": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
+ "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/deep-is": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/default-browser": {
+ "version": "5.4.0",
+ "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.4.0.tgz",
+ "integrity": "sha512-XDuvSq38Hr1MdN47EDvYtx3U0MTqpCEn+F6ft8z2vYDzMrvQhVp0ui9oQdqW3MvK3vqUETglt1tVGgjLuJ5izg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bundle-name": "^4.1.0",
+ "default-browser-id": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/default-browser-id": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.1.tgz",
+ "integrity": "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/define-lazy-prop": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz",
+ "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/detect-libc": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
+ "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/diff": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz",
+ "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.3.1"
+ }
+ },
+ "node_modules/dir-glob": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+ "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-type": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/doctrine": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
+ "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "esutils": "^2.0.2"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/dom-serializer": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
+ "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.2",
+ "entities": "^4.2.0"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+ }
+ },
+ "node_modules/domelementtype": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
+ "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ],
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/domhandler": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+ "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "domelementtype": "^2.3.0"
+ },
+ "engines": {
+ "node": ">= 4"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domhandler?sponsor=1"
+ }
+ },
+ "node_modules/domutils": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz",
+ "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "dom-serializer": "^2.0.0",
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domutils?sponsor=1"
+ }
+ },
+ "node_modules/dunder-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
+ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/eastasianwidth": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
+ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ecdsa-sig-formatter": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
+ "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "node_modules/emoji-regex": {
+ "version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz",
+ "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/encoding-sniffer": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz",
+ "integrity": "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "iconv-lite": "^0.6.3",
+ "whatwg-encoding": "^3.1.1"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/encoding-sniffer?sponsor=1"
+ }
+ },
+ "node_modules/end-of-stream": {
+ "version": "1.4.5",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz",
+ "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "once": "^1.4.0"
+ }
+ },
+ "node_modules/entities": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/es-define-property": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
+ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-errors": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-object-atoms": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
+ "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-set-tostringtag": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
+ "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/escalade": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/eslint": {
+ "version": "8.57.1",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz",
+ "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==",
+ "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.2.0",
+ "@eslint-community/regexpp": "^4.6.1",
+ "@eslint/eslintrc": "^2.1.4",
+ "@eslint/js": "8.57.1",
+ "@humanwhocodes/config-array": "^0.13.0",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@nodelib/fs.walk": "^1.2.8",
+ "@ungap/structured-clone": "^1.2.0",
+ "ajv": "^6.12.4",
+ "chalk": "^4.0.0",
+ "cross-spawn": "^7.0.2",
+ "debug": "^4.3.2",
+ "doctrine": "^3.0.0",
+ "escape-string-regexp": "^4.0.0",
+ "eslint-scope": "^7.2.2",
+ "eslint-visitor-keys": "^3.4.3",
+ "espree": "^9.6.1",
+ "esquery": "^1.4.2",
+ "esutils": "^2.0.2",
+ "fast-deep-equal": "^3.1.3",
+ "file-entry-cache": "^6.0.1",
+ "find-up": "^5.0.0",
+ "glob-parent": "^6.0.2",
+ "globals": "^13.19.0",
+ "graphemer": "^1.4.0",
+ "ignore": "^5.2.0",
+ "imurmurhash": "^0.1.4",
+ "is-glob": "^4.0.0",
+ "is-path-inside": "^3.0.3",
+ "js-yaml": "^4.1.0",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "levn": "^0.4.1",
+ "lodash.merge": "^4.6.2",
+ "minimatch": "^3.1.2",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.3",
+ "strip-ansi": "^6.0.1",
+ "text-table": "^0.2.0"
+ },
+ "bin": {
+ "eslint": "bin/eslint.js"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "7.2.2",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
+ "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-visitor-keys": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/eslint/node_modules/brace-expansion": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/eslint/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/eslint/node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/eslint/node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/eslint/node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/eslint/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/eslint/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/espree": {
+ "version": "9.6.1",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
+ "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "acorn": "^8.9.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^3.4.1"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/esquery": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
+ "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "estraverse": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/expand-template": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
+ "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",
+ "dev": true,
+ "license": "(MIT OR WTFPL)",
+ "optional": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-glob": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
+ "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.8"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "node_modules/fast-glob/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fastq": {
+ "version": "1.19.1",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz",
+ "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/fd-slicer": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
+ "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "pend": "~1.2.0"
+ }
+ },
+ "node_modules/file-entry-cache": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
+ "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flat-cache": "^3.0.4"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ }
+ },
+ "node_modules/fill-range": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/flat": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
+ "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "bin": {
+ "flat": "cli.js"
+ }
+ },
+ "node_modules/flat-cache": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz",
+ "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flatted": "^3.2.9",
+ "keyv": "^4.5.3",
+ "rimraf": "^3.0.2"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ }
+ },
+ "node_modules/flatted": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz",
+ "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/foreground-child": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
+ "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "cross-spawn": "^7.0.6",
+ "signal-exit": "^4.0.1"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/form-data": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz",
+ "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "es-set-tostringtag": "^2.1.0",
+ "hasown": "^2.0.2",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/fs-constants": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
+ "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": "6.* || 8.* || >= 10.*"
+ }
+ },
+ "node_modules/get-east-asian-width": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz",
+ "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/get-intrinsic": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+ "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
+ "function-bind": "^1.1.2",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "math-intrinsics": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
+ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/github-from-package": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
+ "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/glob": {
+ "version": "10.5.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz",
+ "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^3.1.2",
+ "minimatch": "^9.0.4",
+ "minipass": "^7.1.2",
+ "package-json-from-dist": "^1.0.0",
+ "path-scurry": "^1.11.1"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/glob/node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/globals": {
+ "version": "13.24.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
+ "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "type-fest": "^0.20.2"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/globby": {
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
+ "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-union": "^2.1.0",
+ "dir-glob": "^3.0.1",
+ "fast-glob": "^3.2.9",
+ "ignore": "^5.2.0",
+ "merge2": "^1.4.1",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/gopd": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/graphemer": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
+ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/has-symbols": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
+ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-tostringtag": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
+ "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-symbols": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/he": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
+ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "he": "bin/he"
+ }
+ },
+ "node_modules/hosted-git-info": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
+ "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/htmlparser2": {
+ "version": "10.0.0",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.0.0.tgz",
+ "integrity": "sha512-TwAZM+zE5Tq3lrEHvOlvwgj1XLWQCtaaibSN11Q+gGBAS7Y1uZSWwXXRe4iF6OXnaq1riyQAPFOBtYc77Mxq0g==",
+ "dev": true,
+ "funding": [
+ "https://github.com/fb55/htmlparser2?sponsor=1",
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3",
+ "domutils": "^3.2.1",
+ "entities": "^6.0.0"
+ }
+ },
+ "node_modules/htmlparser2/node_modules/entities": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz",
+ "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/http-proxy-agent": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
+ "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "^7.1.0",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/https-proxy-agent": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
+ "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "^7.1.2",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/iconv-lite": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ieee754": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "BSD-3-Clause",
+ "optional": true
+ },
+ "node_modules/ignore": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/immediate": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
+ "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/import-fresh": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
+ "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/ini": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
+ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
+ "dev": true,
+ "license": "ISC",
+ "optional": true
+ },
+ "node_modules/is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "binary-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-docker": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz",
+ "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "is-docker": "cli.js"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-inside-container": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz",
+ "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-docker": "^3.0.0"
+ },
+ "bin": {
+ "is-inside-container": "cli.js"
+ },
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-interactive": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz",
+ "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/is-path-inside": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
+ "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-plain-obj": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
+ "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-unicode-supported": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz",
+ "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-wsl": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz",
+ "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-inside-container": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/jackspeak": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
+ "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "@isaacs/cliui": "^8.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ },
+ "optionalDependencies": {
+ "@pkgjs/parseargs": "^0.11.0"
+ }
+ },
+ "node_modules/js-yaml": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
+ "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/json-buffer": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
+ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/jsonc-parser": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz",
+ "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/jsonwebtoken": {
+ "version": "9.0.2",
+ "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz",
+ "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "jws": "^3.2.2",
+ "lodash.includes": "^4.3.0",
+ "lodash.isboolean": "^3.0.3",
+ "lodash.isinteger": "^4.0.4",
+ "lodash.isnumber": "^3.0.3",
+ "lodash.isplainobject": "^4.0.6",
+ "lodash.isstring": "^4.0.1",
+ "lodash.once": "^4.0.0",
+ "ms": "^2.1.1",
+ "semver": "^7.5.4"
+ },
+ "engines": {
+ "node": ">=12",
+ "npm": ">=6"
+ }
+ },
+ "node_modules/jszip": {
+ "version": "3.10.1",
+ "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz",
+ "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==",
+ "dev": true,
+ "license": "(MIT OR GPL-3.0-or-later)",
+ "dependencies": {
+ "lie": "~3.3.0",
+ "pako": "~1.0.2",
+ "readable-stream": "~2.3.6",
+ "setimmediate": "^1.0.5"
+ }
+ },
+ "node_modules/jwa": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.2.tgz",
+ "integrity": "sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "buffer-equal-constant-time": "^1.0.1",
+ "ecdsa-sig-formatter": "1.0.11",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "node_modules/jws": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
+ "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "jwa": "^1.4.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "node_modules/keytar": {
+ "version": "7.9.0",
+ "resolved": "https://registry.npmjs.org/keytar/-/keytar-7.9.0.tgz",
+ "integrity": "sha512-VPD8mtVtm5JNtA2AErl6Chp06JBfy7diFQ7TQQhdpWOl6MrCRB+eRbvAZUsbGQS9kiMq0coJsy0W0vHpDCkWsQ==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "node-addon-api": "^4.3.0",
+ "prebuild-install": "^7.0.1"
+ }
+ },
+ "node_modules/keyv": {
+ "version": "4.5.4",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
+ "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "json-buffer": "3.0.1"
+ }
+ },
+ "node_modules/leven": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
+ "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/levn": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
+ "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1",
+ "type-check": "~0.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/lie": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz",
+ "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "immediate": "~3.0.5"
+ }
+ },
+ "node_modules/linkify-it": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz",
+ "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "uc.micro": "^1.0.1"
+ }
+ },
+ "node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/lodash.includes": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
+ "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.isboolean": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
+ "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.isinteger": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
+ "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.isnumber": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
+ "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.isplainobject": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
+ "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.isstring": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
+ "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.merge": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.once": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
+ "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/log-symbols": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-6.0.0.tgz",
+ "integrity": "sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^5.3.0",
+ "is-unicode-supported": "^1.3.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/log-symbols/node_modules/chalk": {
+ "version": "5.6.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz",
+ "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.17.0 || ^14.13 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/log-symbols/node_modules/is-unicode-supported": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz",
+ "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/markdown-it": {
+ "version": "12.3.2",
+ "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz",
+ "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^2.0.1",
+ "entities": "~2.1.0",
+ "linkify-it": "^3.0.1",
+ "mdurl": "^1.0.1",
+ "uc.micro": "^1.0.5"
+ },
+ "bin": {
+ "markdown-it": "bin/markdown-it.js"
+ }
+ },
+ "node_modules/markdown-it/node_modules/entities": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz",
+ "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/math-intrinsics": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/mdurl": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
+ "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "braces": "^3.0.3",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/mime": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "mime": "cli.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mimic-function": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz",
+ "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/mimic-response": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
+ "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "9.0.3",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
+ "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/minimist": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/minipass": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
+ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/mkdirp-classic": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
+ "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/mocha": {
+ "version": "10.8.2",
+ "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.8.2.tgz",
+ "integrity": "sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-colors": "^4.1.3",
+ "browser-stdout": "^1.3.1",
+ "chokidar": "^3.5.3",
+ "debug": "^4.3.5",
+ "diff": "^5.2.0",
+ "escape-string-regexp": "^4.0.0",
+ "find-up": "^5.0.0",
+ "glob": "^8.1.0",
+ "he": "^1.2.0",
+ "js-yaml": "^4.1.0",
+ "log-symbols": "^4.1.0",
+ "minimatch": "^5.1.6",
+ "ms": "^2.1.3",
+ "serialize-javascript": "^6.0.2",
+ "strip-json-comments": "^3.1.1",
+ "supports-color": "^8.1.1",
+ "workerpool": "^6.5.1",
+ "yargs": "^16.2.0",
+ "yargs-parser": "^20.2.9",
+ "yargs-unparser": "^2.0.0"
+ },
+ "bin": {
+ "_mocha": "bin/_mocha",
+ "mocha": "bin/mocha.js"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/mocha/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/mocha/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/mocha/node_modules/chalk/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/mocha/node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/mocha/node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/mocha/node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/mocha/node_modules/glob": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
+ "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^5.0.1",
+ "once": "^1.3.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/mocha/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/mocha/node_modules/is-unicode-supported": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
+ "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/mocha/node_modules/log-symbols": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
+ "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^4.1.0",
+ "is-unicode-supported": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/mocha/node_modules/minimatch": {
+ "version": "5.1.6",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
+ "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/mocha/node_modules/supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/mute-stream": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
+ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/napi-build-utils": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz",
+ "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/node-abi": {
+ "version": "3.85.0",
+ "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.85.0.tgz",
+ "integrity": "sha512-zsFhmbkAzwhTft6nd3VxcG0cvJsT70rL+BIGHWVq5fi6MwGrHwzqKaxXE+Hl2GmnGItnDKPPkO5/LQqjVkIdFg==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "semver": "^7.3.5"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/node-addon-api": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz",
+ "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/nth-check": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
+ "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "boolbase": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/nth-check?sponsor=1"
+ }
+ },
+ "node_modules/object-inspect": {
+ "version": "1.13.4",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
+ "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/onetime": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz",
+ "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mimic-function": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/open": {
+ "version": "10.2.0",
+ "resolved": "https://registry.npmjs.org/open/-/open-10.2.0.tgz",
+ "integrity": "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "default-browser": "^5.2.1",
+ "define-lazy-prop": "^3.0.0",
+ "is-inside-container": "^1.0.0",
+ "wsl-utils": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/optionator": {
+ "version": "0.9.4",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
+ "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "deep-is": "^0.1.3",
+ "fast-levenshtein": "^2.0.6",
+ "levn": "^0.4.1",
+ "prelude-ls": "^1.2.1",
+ "type-check": "^0.4.0",
+ "word-wrap": "^1.2.5"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/ora": {
+ "version": "8.2.0",
+ "resolved": "https://registry.npmjs.org/ora/-/ora-8.2.0.tgz",
+ "integrity": "sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^5.3.0",
+ "cli-cursor": "^5.0.0",
+ "cli-spinners": "^2.9.2",
+ "is-interactive": "^2.0.0",
+ "is-unicode-supported": "^2.0.0",
+ "log-symbols": "^6.0.0",
+ "stdin-discarder": "^0.2.2",
+ "string-width": "^7.2.0",
+ "strip-ansi": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ora/node_modules/ansi-regex": {
+ "version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
+ "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/ora/node_modules/chalk": {
+ "version": "5.6.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz",
+ "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.17.0 || ^14.13 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/ora/node_modules/strip-ansi": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz",
+ "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/package-json-from-dist": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
+ "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
+ "dev": true,
+ "license": "BlueOak-1.0.0"
+ },
+ "node_modules/pako": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
+ "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
+ "dev": true,
+ "license": "(MIT AND Zlib)"
+ },
+ "node_modules/parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "callsites": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/parse-semver": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/parse-semver/-/parse-semver-1.1.1.tgz",
+ "integrity": "sha512-Eg1OuNntBMH0ojvEKSrvDSnwLmvVuUOSdylH/pSCPNMIspLlweJyIWXCE+k/5hm3cj/EBUYwmWkjhBALNP4LXQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "semver": "^5.1.0"
+ }
+ },
+ "node_modules/parse-semver/node_modules/semver": {
+ "version": "5.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+ "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
+ "node_modules/parse5": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz",
+ "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "entities": "^6.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/inikulin/parse5?sponsor=1"
+ }
+ },
+ "node_modules/parse5-htmlparser2-tree-adapter": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz",
+ "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "domhandler": "^5.0.3",
+ "parse5": "^7.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/inikulin/parse5?sponsor=1"
+ }
+ },
+ "node_modules/parse5-parser-stream": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz",
+ "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "parse5": "^7.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/inikulin/parse5?sponsor=1"
+ }
+ },
+ "node_modules/parse5/node_modules/entities": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz",
+ "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-scurry": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
+ "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "lru-cache": "^10.2.0",
+ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/path-scurry/node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/path-type": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pend": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
+ "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/prebuild-install": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz",
+ "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "detect-libc": "^2.0.0",
+ "expand-template": "^2.0.3",
+ "github-from-package": "0.0.0",
+ "minimist": "^1.2.3",
+ "mkdirp-classic": "^0.5.3",
+ "napi-build-utils": "^2.0.0",
+ "node-abi": "^3.3.0",
+ "pump": "^3.0.0",
+ "rc": "^1.2.7",
+ "simple-get": "^4.0.0",
+ "tar-fs": "^2.0.0",
+ "tunnel-agent": "^0.6.0"
+ },
+ "bin": {
+ "prebuild-install": "bin.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/prelude-ls": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
+ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/process-nextick-args": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/pump": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz",
+ "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ },
+ "node_modules/punycode": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
+ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/qs": {
+ "version": "6.14.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
+ "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "side-channel": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/randombytes": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+ "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "node_modules/rc": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
+ "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
+ "dev": true,
+ "license": "(BSD-2-Clause OR MIT OR Apache-2.0)",
+ "optional": true,
+ "dependencies": {
+ "deep-extend": "^0.6.0",
+ "ini": "~1.3.0",
+ "minimist": "^1.2.0",
+ "strip-json-comments": "~2.0.1"
+ },
+ "bin": {
+ "rc": "cli.js"
+ }
+ },
+ "node_modules/rc/node_modules/strip-json-comments": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+ "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/read": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz",
+ "integrity": "sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "mute-stream": "~0.0.4"
+ },
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/readable-stream": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
+ "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "node_modules/readable-stream/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "picomatch": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ }
+ },
+ "node_modules/require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/restore-cursor": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz",
+ "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "onetime": "^7.0.0",
+ "signal-exit": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/reusify": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
+ "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "deprecated": "Rimraf versions prior to v4 are no longer supported",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/rimraf/node_modules/brace-expansion": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/rimraf/node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/rimraf/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/run-applescript": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz",
+ "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/sax": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.3.tgz",
+ "integrity": "sha512-yqYn1JhPczigF94DMS+shiDMjDowYO6y9+wB/4WgO0Y19jWYk0lQ4tuG5KI7kj4FTp1wxPj5IFfcrz/s1c3jjQ==",
+ "dev": true,
+ "license": "BlueOak-1.0.0"
+ },
+ "node_modules/semver": {
+ "version": "7.7.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
+ "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/serialize-javascript": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz",
+ "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "randombytes": "^2.1.0"
+ }
+ },
+ "node_modules/setimmediate": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
+ "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/side-channel": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
+ "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3",
+ "side-channel-list": "^1.0.0",
+ "side-channel-map": "^1.0.1",
+ "side-channel-weakmap": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-list": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
+ "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-map": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
+ "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-weakmap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
+ "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3",
+ "side-channel-map": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/signal-exit": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
+ "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/simple-concat": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
+ "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/simple-get": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz",
+ "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "decompress-response": "^6.0.0",
+ "once": "^1.3.1",
+ "simple-concat": "^1.0.0"
+ }
+ },
+ "node_modules/slash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/stdin-discarder": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.2.2.tgz",
+ "integrity": "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "node_modules/string_decoder/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/string-width": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",
+ "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^10.3.0",
+ "get-east-asian-width": "^1.0.0",
+ "strip-ansi": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/string-width-cjs": {
+ "name": "string-width",
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width-cjs/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/string-width/node_modules/ansi-regex": {
+ "version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
+ "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/string-width/node_modules/strip-ansi": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz",
+ "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi-cjs": {
+ "name": "strip-ansi",
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/tar-fs": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz",
+ "integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "chownr": "^1.1.1",
+ "mkdirp-classic": "^0.5.2",
+ "pump": "^3.0.0",
+ "tar-stream": "^2.1.4"
+ }
+ },
+ "node_modules/tar-stream": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
+ "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "bl": "^4.0.3",
+ "end-of-stream": "^1.4.1",
+ "fs-constants": "^1.0.0",
+ "inherits": "^2.0.3",
+ "readable-stream": "^3.1.1"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/tar-stream/node_modules/readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/text-table": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/tmp": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz",
+ "integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.14"
+ }
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/ts-api-utils": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz",
+ "integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=16"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.2.0"
+ }
+ },
+ "node_modules/tslib": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
+ "dev": true,
+ "license": "0BSD"
+ },
+ "node_modules/tunnel": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
+ "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.6.11 <=0.7.0 || >=0.7.3"
+ }
+ },
+ "node_modules/tunnel-agent": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+ "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "dependencies": {
+ "safe-buffer": "^5.0.1"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/type-check": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+ "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/type-fest": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
+ "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
+ "dev": true,
+ "license": "(MIT OR CC0-1.0)",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/typed-rest-client": {
+ "version": "1.8.11",
+ "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.8.11.tgz",
+ "integrity": "sha512-5UvfMpd1oelmUPRbbaVnq+rHP7ng2cE4qoQkQeAqxRL6PklkxsM0g32/HL0yfvruK6ojQ5x8EE+HF4YV6DtuCA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "qs": "^6.9.1",
+ "tunnel": "0.0.6",
+ "underscore": "^1.12.1"
+ }
+ },
+ "node_modules/typescript": {
+ "version": "5.9.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
+ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "peer": true,
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/uc.micro": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
+ "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/underscore": {
+ "version": "1.13.7",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.7.tgz",
+ "integrity": "sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/undici": {
+ "version": "7.16.0",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-7.16.0.tgz",
+ "integrity": "sha512-QEg3HPMll0o3t2ourKwOeUAZ159Kn9mx5pnzHRQO8+Wixmh88YdZRiIwat0iNzNNXn0yoEtXJqFpyW7eM8BV7g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=20.18.1"
+ }
+ },
+ "node_modules/undici-types": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
+ "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/url-join": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz",
+ "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/uuid": {
+ "version": "8.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
+ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "uuid": "dist/bin/uuid"
+ }
+ },
+ "node_modules/vscode-jsonrpc": {
+ "version": "8.2.0",
+ "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz",
+ "integrity": "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/vscode-languageclient": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-9.0.1.tgz",
+ "integrity": "sha512-JZiimVdvimEuHh5olxhxkht09m3JzUGwggb5eRUkzzJhZ2KjCN0nh55VfiED9oez9DyF8/fz1g1iBV3h+0Z2EA==",
+ "license": "MIT",
+ "dependencies": {
+ "minimatch": "^5.1.0",
+ "semver": "^7.3.7",
+ "vscode-languageserver-protocol": "3.17.5"
+ },
+ "engines": {
+ "vscode": "^1.82.0"
+ }
+ },
+ "node_modules/vscode-languageclient/node_modules/minimatch": {
+ "version": "5.1.6",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
+ "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/vscode-languageserver-protocol": {
+ "version": "3.17.5",
+ "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz",
+ "integrity": "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==",
+ "license": "MIT",
+ "dependencies": {
+ "vscode-jsonrpc": "8.2.0",
+ "vscode-languageserver-types": "3.17.5"
+ }
+ },
+ "node_modules/vscode-languageserver-types": {
+ "version": "3.17.5",
+ "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz",
+ "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==",
+ "license": "MIT"
+ },
+ "node_modules/whatwg-encoding": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz",
+ "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "iconv-lite": "0.6.3"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/whatwg-mimetype": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz",
+ "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/word-wrap": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
+ "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/workerpool": {
+ "version": "6.5.1",
+ "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz",
+ "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/wrap-ansi": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
+ "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^6.1.0",
+ "string-width": "^5.0.1",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs": {
+ "name": "wrap-ansi",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/ansi-regex": {
+ "version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
+ "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/ansi-styles": {
+ "version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz",
+ "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/emoji-regex": {
+ "version": "9.2.2",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
+ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/wrap-ansi/node_modules/string-width": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
+ "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eastasianwidth": "^0.2.0",
+ "emoji-regex": "^9.2.2",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/strip-ansi": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz",
+ "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/wsl-utils": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.1.0.tgz",
+ "integrity": "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-wsl": "^3.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/xml2js": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz",
+ "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "sax": ">=0.6.0",
+ "xmlbuilder": "~11.0.0"
+ },
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/xmlbuilder": {
+ "version": "11.0.1",
+ "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
+ "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/yargs": {
+ "version": "16.2.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
+ "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cliui": "^7.0.2",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.0",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^20.2.2"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yargs-parser": {
+ "version": "20.2.9",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
+ "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yargs-unparser": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz",
+ "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "camelcase": "^6.0.0",
+ "decamelize": "^4.0.0",
+ "flat": "^5.0.2",
+ "is-plain-obj": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yargs/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/yargs/node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/yauzl": {
+ "version": "2.10.0",
+ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
+ "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "buffer-crc32": "~0.2.3",
+ "fd-slicer": "~1.1.0"
+ }
+ },
+ "node_modules/yazl": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz",
+ "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "buffer-crc32": "~0.2.3"
+ }
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ }
+ }
+}
diff --git a/vscode-extension/package.json b/vscode-extension/package.json
new file mode 100644
index 0000000..4986aea
--- /dev/null
+++ b/vscode-extension/package.json
@@ -0,0 +1,248 @@
+{
+ "name": "gosqlx",
+ "displayName": "GoSQLX",
+ "description": "High-performance SQL parsing, validation, formatting, and analysis powered by GoSQLX",
+ "version": "0.1.0",
+ "publisher": "ajitpratap0",
+ "license": "AGPL-3.0",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/ajitpratap0/GoSQLX"
+ },
+ "bugs": {
+ "url": "https://github.com/ajitpratap0/GoSQLX/issues"
+ },
+ "homepage": "https://github.com/ajitpratap0/GoSQLX#readme",
+ "engines": {
+ "vscode": "^1.85.0"
+ },
+ "categories": [
+ "Programming Languages",
+ "Linters",
+ "Formatters"
+ ],
+ "keywords": [
+ "sql",
+ "parser",
+ "linter",
+ "formatter",
+ "gosqlx",
+ "postgresql",
+ "mysql",
+ "sqlserver",
+ "oracle",
+ "sqlite"
+ ],
+ "activationEvents": [
+ "onLanguage:sql",
+ "onLanguage:gosqlx"
+ ],
+ "main": "./out/extension.js",
+ "contributes": {
+ "languages": [
+ {
+ "id": "sql",
+ "aliases": ["SQL", "sql"],
+ "extensions": [".sql", ".pgsql", ".psql", ".mysql"],
+ "configuration": "./language-configuration.json"
+ }
+ ],
+ "grammars": [
+ {
+ "language": "sql",
+ "scopeName": "source.sql",
+ "path": "./syntaxes/sql.tmLanguage.json"
+ }
+ ],
+ "configuration": {
+ "title": "GoSQLX",
+ "properties": {
+ "gosqlx.enable": {
+ "type": "boolean",
+ "default": true,
+ "scope": "resource",
+ "description": "Enable GoSQLX language server"
+ },
+ "gosqlx.executablePath": {
+ "type": "string",
+ "default": "gosqlx",
+ "scope": "machine-overridable",
+ "description": "Path to the gosqlx executable"
+ },
+ "gosqlx.trace.server": {
+ "type": "string",
+ "enum": ["off", "messages", "verbose"],
+ "default": "off",
+ "scope": "window",
+ "description": "Traces the communication between VS Code and the GoSQLX language server"
+ },
+ "gosqlx.format.indentSize": {
+ "type": "number",
+ "default": 2,
+ "scope": "resource",
+ "description": "Number of spaces for indentation when formatting SQL"
+ },
+ "gosqlx.format.uppercaseKeywords": {
+ "type": "boolean",
+ "default": true,
+ "scope": "resource",
+ "description": "Convert SQL keywords to uppercase when formatting"
+ },
+ "gosqlx.validation.enable": {
+ "type": "boolean",
+ "default": true,
+ "scope": "resource",
+ "description": "Enable real-time SQL validation"
+ },
+ "gosqlx.dialect": {
+ "type": "string",
+ "enum": ["generic", "postgresql", "mysql", "sqlserver", "oracle", "sqlite"],
+ "default": "generic",
+ "scope": "resource",
+ "description": "SQL dialect for validation and formatting"
+ },
+ "gosqlx.timeouts.startup": {
+ "type": "number",
+ "default": 10000,
+ "minimum": 1000,
+ "maximum": 300000,
+ "description": "Timeout for language server startup in milliseconds"
+ },
+ "gosqlx.timeouts.validation": {
+ "type": "number",
+ "default": 5000,
+ "minimum": 1000,
+ "maximum": 60000,
+ "description": "Timeout for executable validation in milliseconds"
+ },
+ "gosqlx.timeouts.analysis": {
+ "type": "number",
+ "default": 30000,
+ "minimum": 5000,
+ "maximum": 300000,
+ "description": "Timeout for SQL analysis command in milliseconds"
+ },
+ "gosqlx.telemetry.enable": {
+ "type": "boolean",
+ "default": false,
+ "description": "Enable anonymous usage telemetry to help improve GoSQLX. No SQL content or file paths are collected."
+ },
+ "gosqlx.performance.showStatusBar": {
+ "type": "boolean",
+ "default": false,
+ "description": "Show performance metrics in status bar"
+ },
+ "gosqlx.performance.collectMetrics": {
+ "type": "boolean",
+ "default": true,
+ "description": "Collect performance metrics for debugging"
+ }
+ }
+ },
+ "commands": [
+ {
+ "command": "gosqlx.validate",
+ "title": "Validate SQL",
+ "category": "GoSQLX"
+ },
+ {
+ "command": "gosqlx.format",
+ "title": "Format SQL",
+ "category": "GoSQLX"
+ },
+ {
+ "command": "gosqlx.analyze",
+ "title": "Analyze SQL",
+ "category": "GoSQLX"
+ },
+ {
+ "command": "gosqlx.restartServer",
+ "title": "Restart Language Server",
+ "category": "GoSQLX"
+ },
+ {
+ "command": "gosqlx.showOutput",
+ "title": "Show Output Channel",
+ "category": "GoSQLX"
+ },
+ {
+ "command": "gosqlx.showMetrics",
+ "title": "Show Performance Metrics",
+ "category": "GoSQLX"
+ },
+ {
+ "command": "gosqlx.validateConfiguration",
+ "title": "Validate Configuration",
+ "category": "GoSQLX"
+ }
+ ],
+ "menus": {
+ "editor/context": [
+ {
+ "when": "resourceLangId == sql",
+ "command": "gosqlx.validate",
+ "group": "gosqlx@1"
+ },
+ {
+ "when": "resourceLangId == sql",
+ "command": "gosqlx.format",
+ "group": "gosqlx@2"
+ },
+ {
+ "when": "resourceLangId == sql",
+ "command": "gosqlx.analyze",
+ "group": "gosqlx@3"
+ }
+ ],
+ "commandPalette": [
+ {
+ "command": "gosqlx.validate",
+ "when": "resourceLangId == sql"
+ },
+ {
+ "command": "gosqlx.format",
+ "when": "resourceLangId == sql"
+ },
+ {
+ "command": "gosqlx.analyze",
+ "when": "resourceLangId == sql"
+ }
+ ]
+ },
+ "keybindings": [
+ {
+ "command": "gosqlx.format",
+ "key": "ctrl+shift+f",
+ "mac": "cmd+shift+f",
+ "when": "resourceLangId == sql && editorTextFocus"
+ }
+ ]
+ },
+ "scripts": {
+ "vscode:prepublish": "npm run compile",
+ "compile": "tsc -p ./",
+ "watch": "tsc -watch -p ./",
+ "pretest": "npm run compile && npm run lint",
+ "lint": "eslint src --ext ts",
+ "test": "node ./out/test/runTest.js",
+ "package": "vsce package",
+ "publish": "vsce publish"
+ },
+ "dependencies": {
+ "vscode-languageclient": "^9.0.1"
+ },
+ "devDependencies": {
+ "@types/glob": "^8.1.0",
+ "@types/mocha": "^10.0.6",
+ "@types/node": "^20.10.0",
+ "@types/vscode": "^1.85.0",
+ "@typescript-eslint/eslint-plugin": "^6.13.0",
+ "@typescript-eslint/parser": "^6.13.0",
+ "@vscode/test-electron": "^2.3.8",
+ "@vscode/vsce": "^2.22.0",
+ "eslint": "^8.54.0",
+ "glob": "^10.3.10",
+ "mocha": "^10.2.0",
+ "typescript": "^5.3.2"
+ }
+}
diff --git a/vscode-extension/src/extension.ts b/vscode-extension/src/extension.ts
new file mode 100644
index 0000000..31ce8c5
--- /dev/null
+++ b/vscode-extension/src/extension.ts
@@ -0,0 +1,689 @@
+import * as vscode from 'vscode';
+import * as path from 'path';
+import * as os from 'os';
+import { spawn } from 'child_process';
+import {
+ LanguageClient,
+ LanguageClientOptions,
+ ServerOptions,
+ TransportKind
+} from 'vscode-languageclient/node';
+
+import {
+ validateConfiguration,
+ isSqlLanguageId,
+ getExecutableNotFoundMessage,
+ getLspStartFailureMessage,
+ getAnalysisErrorMessage,
+ extractErrorCode,
+ formatError,
+ TelemetryManager,
+ MetricsCollector,
+ PerformanceTimer,
+ showMetricsReport,
+ createPerformanceStatusBarItem,
+ updatePerformanceStatusBar
+} from './utils';
+
+let client: LanguageClient | undefined;
+let outputChannel: vscode.OutputChannel;
+let statusBarItem: vscode.StatusBarItem;
+let performanceStatusBarItem: vscode.StatusBarItem | undefined;
+let extensionContext: vscode.ExtensionContext | undefined;
+let telemetry: TelemetryManager;
+let metrics: MetricsCollector;
+
+export async function activate(context: vscode.ExtensionContext): Promise {
+ // Store context for restart functionality
+ extensionContext = context;
+
+ // Initialize utilities
+ const packageJson = context.extension.packageJSON;
+ telemetry = TelemetryManager.getInstance(packageJson.version || '0.1.0');
+ metrics = MetricsCollector.getInstance();
+
+ outputChannel = vscode.window.createOutputChannel('GoSQLX');
+ context.subscriptions.push(outputChannel);
+
+ // Create status bar item
+ statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 100);
+ statusBarItem.text = '$(database) GoSQLX';
+ statusBarItem.tooltip = 'GoSQLX Language Server';
+ statusBarItem.command = 'gosqlx.showOutput';
+ context.subscriptions.push(statusBarItem);
+
+ // Create performance status bar item if enabled
+ const config = vscode.workspace.getConfiguration('gosqlx');
+ if (config.get('performance.showStatusBar', false)) {
+ performanceStatusBarItem = createPerformanceStatusBarItem();
+ context.subscriptions.push(performanceStatusBarItem);
+ }
+
+ // Validate configuration on startup
+ await validateAndWarnConfiguration();
+
+ // Register commands
+ context.subscriptions.push(
+ vscode.commands.registerCommand('gosqlx.validate', validateCommand),
+ vscode.commands.registerCommand('gosqlx.format', formatCommand),
+ vscode.commands.registerCommand('gosqlx.analyze', analyzeCommand),
+ vscode.commands.registerCommand('gosqlx.restartServer', restartServerCommand),
+ vscode.commands.registerCommand('gosqlx.showOutput', () => outputChannel.show()),
+ vscode.commands.registerCommand('gosqlx.showMetrics', showMetricsCommand),
+ vscode.commands.registerCommand('gosqlx.validateConfiguration', validateConfigurationCommand)
+ );
+
+ // Start the language server
+ if (config.get('enable', true)) {
+ await startLanguageServer(context);
+ }
+
+ // Watch for configuration changes
+ context.subscriptions.push(
+ vscode.workspace.onDidChangeConfiguration(async (e) => {
+ if (e.affectsConfiguration('gosqlx')) {
+ telemetry.recordEvent('config.changed');
+
+ // Re-validate configuration
+ await validateAndWarnConfiguration();
+
+ const newConfig = vscode.workspace.getConfiguration('gosqlx');
+
+ // Handle enable/disable
+ if (newConfig.get('enable', true)) {
+ if (!client) {
+ await startLanguageServer(context);
+ }
+ } else {
+ await stopLanguageServer();
+ }
+
+ // Handle performance status bar toggle
+ if (e.affectsConfiguration('gosqlx.performance.showStatusBar')) {
+ if (newConfig.get('performance.showStatusBar', false)) {
+ if (!performanceStatusBarItem) {
+ performanceStatusBarItem = createPerformanceStatusBarItem();
+ context.subscriptions.push(performanceStatusBarItem);
+ }
+ updatePerformanceStatusBar(performanceStatusBarItem, metrics);
+ } else {
+ performanceStatusBarItem?.hide();
+ }
+ }
+ }
+ })
+ );
+
+ // Record activation
+ telemetry.recordEvent('extension.activated');
+ outputChannel.appendLine('GoSQLX extension activated');
+}
+
+/**
+ * Validates configuration and shows warnings for invalid settings.
+ */
+async function validateAndWarnConfiguration(): Promise {
+ const config = vscode.workspace.getConfiguration('gosqlx');
+
+ // Build config object for validation
+ const configObj: Record = {
+ enable: config.get('enable'),
+ executablePath: config.get('executablePath'),
+ dialect: config.get('dialect'),
+ format: {
+ indentSize: config.get('format.indentSize'),
+ uppercaseKeywords: config.get('format.uppercaseKeywords')
+ },
+ timeouts: {
+ startup: config.get('timeouts.startup'),
+ validation: config.get('timeouts.validation'),
+ analysis: config.get('timeouts.analysis')
+ },
+ 'trace.server': config.get('trace.server')
+ };
+
+ const results = validateConfiguration(configObj);
+ const errors = results.filter(r => !r.valid);
+
+ if (errors.length > 0) {
+ outputChannel.appendLine('Configuration validation warnings:');
+ for (const error of errors) {
+ outputChannel.appendLine(` - ${error.message}`);
+ if (error.suggestion) {
+ outputChannel.appendLine(` Suggestion: ${error.suggestion}`);
+ }
+ }
+
+ const action = await vscode.window.showWarningMessage(
+ `GoSQLX: ${errors.length} configuration issue(s) detected`,
+ 'Show Details',
+ 'Open Settings'
+ );
+
+ if (action === 'Show Details') {
+ outputChannel.show();
+ } else if (action === 'Open Settings') {
+ vscode.commands.executeCommand('workbench.action.openSettings', 'gosqlx');
+ }
+ }
+}
+
+/**
+ * Validates that the gosqlx executable exists and is runnable.
+ */
+async function validateExecutable(executablePath: string): Promise {
+ const config = vscode.workspace.getConfiguration('gosqlx');
+ const timeout = config.get('timeouts.validation', 5000);
+
+ const timer = new PerformanceTimer();
+ timer.start();
+
+ return new Promise((resolve) => {
+ const child = spawn(executablePath, ['--version'], { stdio: 'pipe' });
+ const timeoutHandle = setTimeout(() => {
+ child.kill();
+ metrics.record('executable.check', timer.stop(), false, { reason: 'timeout' });
+ resolve(false);
+ }, timeout);
+
+ child.on('close', (code) => {
+ clearTimeout(timeoutHandle);
+ const success = code === 0;
+ metrics.record('executable.check', timer.stop(), success, { exitCode: code ?? -1 });
+ resolve(success);
+ });
+
+ child.on('error', (err: NodeJS.ErrnoException) => {
+ clearTimeout(timeoutHandle);
+ metrics.record('executable.check', timer.stop(), false, { error: err.code || 'unknown' });
+ resolve(false);
+ });
+ });
+}
+
+async function startLanguageServer(context: vscode.ExtensionContext, retryCount: number = 0): Promise {
+ const config = vscode.workspace.getConfiguration('gosqlx');
+ const executablePath = config.get('executablePath', 'gosqlx');
+ const maxRetries = 3;
+
+ const timer = new PerformanceTimer();
+ timer.start();
+
+ // Validate executable before starting
+ const isValid = await validateExecutable(executablePath);
+ if (!isValid) {
+ const message = getExecutableNotFoundMessage(executablePath, os.platform());
+ outputChannel.appendLine(message);
+
+ telemetry.recordError('ENOENT', 'lsp.startup');
+
+ const action = await vscode.window.showErrorMessage(
+ `GoSQLX executable not found or not working: ${executablePath}`,
+ 'Show Details',
+ 'Install Guide',
+ 'Open Settings'
+ );
+
+ if (action === 'Show Details') {
+ outputChannel.show();
+ } else if (action === 'Install Guide') {
+ vscode.env.openExternal(
+ vscode.Uri.parse('https://github.com/ajitpratap0/GoSQLX#installation')
+ );
+ } else if (action === 'Open Settings') {
+ vscode.commands.executeCommand('workbench.action.openSettings', 'gosqlx.executablePath');
+ }
+
+ statusBarItem.text = '$(error) GoSQLX';
+ statusBarItem.tooltip = 'GoSQLX: Executable not found - Click for details';
+ statusBarItem.show();
+ return;
+ }
+
+ // Server options - spawn the gosqlx lsp command
+ const debugLogPath = path.join(os.tmpdir(), 'gosqlx-lsp-debug.log');
+
+ const serverOptions: ServerOptions = {
+ run: {
+ command: executablePath,
+ args: ['lsp'],
+ transport: TransportKind.stdio
+ },
+ debug: {
+ command: executablePath,
+ args: ['lsp', '--log', debugLogPath],
+ transport: TransportKind.stdio
+ }
+ };
+
+ // Client options
+ const clientOptions: LanguageClientOptions = {
+ documentSelector: [
+ { scheme: 'file', language: 'sql' },
+ { scheme: 'untitled', language: 'sql' }
+ ],
+ synchronize: {
+ fileEvents: vscode.workspace.createFileSystemWatcher('**/*.sql')
+ },
+ outputChannel: outputChannel,
+ traceOutputChannel: outputChannel,
+ initializationOptions: {
+ dialect: config.get('dialect', 'generic'),
+ format: {
+ indentSize: config.get('format.indentSize', 2),
+ uppercaseKeywords: config.get('format.uppercaseKeywords', true)
+ }
+ }
+ };
+
+ // Create and start the client
+ client = new LanguageClient(
+ 'gosqlx',
+ 'GoSQLX Language Server',
+ serverOptions,
+ clientOptions
+ );
+
+ try {
+ await client.start();
+ const duration = timer.stop();
+
+ metrics.record('lsp.startup', duration, true);
+ telemetry.recordLspOperation('started', { duration });
+
+ statusBarItem.text = '$(database) GoSQLX';
+ statusBarItem.tooltip = 'GoSQLX Language Server - Running';
+ statusBarItem.show();
+
+ if (performanceStatusBarItem) {
+ updatePerformanceStatusBar(performanceStatusBarItem, metrics);
+ }
+
+ outputChannel.appendLine(`GoSQLX Language Server started successfully (${duration}ms)`);
+ vscode.window.showInformationMessage('GoSQLX Language Server started');
+ } catch (error) {
+ const duration = timer.stop();
+ const errorMessage = formatError(error);
+ const errorCode = extractErrorCode(error);
+
+ metrics.record('lsp.startup', duration, false, { error: errorCode || 'unknown' });
+ telemetry.recordLspOperation('error', { errorCode: errorCode || 'unknown', attempt: retryCount });
+
+ outputChannel.appendLine(`Failed to start GoSQLX Language Server: ${errorMessage}`);
+
+ // Retry logic
+ if (retryCount < maxRetries) {
+ const retryDelay = Math.pow(2, retryCount) * 1000; // Exponential backoff
+
+ telemetry.recordLspOperation('retry', { attempt: retryCount + 1, retryDelay });
+ outputChannel.appendLine(`Retrying in ${retryDelay / 1000} seconds... (attempt ${retryCount + 1}/${maxRetries})`);
+
+ statusBarItem.text = '$(sync~spin) GoSQLX';
+ statusBarItem.tooltip = `GoSQLX: Retrying... (${retryCount + 1}/${maxRetries})`;
+ statusBarItem.show();
+
+ await new Promise(resolve => setTimeout(resolve, retryDelay));
+ return startLanguageServer(context, retryCount + 1);
+ }
+
+ const detailedMessage = getLspStartFailureMessage(
+ errorMessage,
+ maxRetries,
+ maxRetries,
+ executablePath
+ );
+ outputChannel.appendLine(detailedMessage);
+
+ const action = await vscode.window.showErrorMessage(
+ `Failed to start GoSQLX Language Server after ${maxRetries} attempts`,
+ 'Show Details',
+ 'Restart',
+ 'Open Settings'
+ );
+
+ if (action === 'Show Details') {
+ outputChannel.show();
+ } else if (action === 'Restart') {
+ await restartServerCommand();
+ } else if (action === 'Open Settings') {
+ vscode.commands.executeCommand('workbench.action.openSettings', 'gosqlx');
+ }
+
+ statusBarItem.text = '$(error) GoSQLX';
+ statusBarItem.tooltip = 'GoSQLX: Failed to start - Click for details';
+ statusBarItem.show();
+ }
+}
+
+async function stopLanguageServer(): Promise {
+ if (client) {
+ const timer = new PerformanceTimer();
+ timer.start();
+
+ await client.stop();
+ client = undefined;
+
+ metrics.record('lsp.shutdown', timer.stop(), true);
+ telemetry.recordLspOperation('stopped');
+
+ statusBarItem.hide();
+ outputChannel.appendLine('GoSQLX Language Server stopped');
+ }
+}
+
+async function restartServerCommand(): Promise {
+ outputChannel.appendLine('Restarting GoSQLX Language Server...');
+ await stopLanguageServer();
+
+ const context = getExtensionContext();
+ if (context) {
+ await startLanguageServer(context);
+ }
+}
+
+function getExtensionContext(): vscode.ExtensionContext | undefined {
+ return extensionContext;
+}
+
+async function validateCommand(): Promise {
+ const timer = new PerformanceTimer();
+ timer.start();
+
+ const editor = vscode.window.activeTextEditor;
+ if (!editor || !isSqlLanguageId(editor.document.languageId)) {
+ vscode.window.showWarningMessage(
+ 'No SQL file is open. Open a .sql file to validate.',
+ 'Open File'
+ ).then(action => {
+ if (action === 'Open File') {
+ vscode.commands.executeCommand('workbench.action.files.openFile');
+ }
+ });
+ return;
+ }
+
+ if (!client) {
+ const action = await vscode.window.showErrorMessage(
+ 'GoSQLX Language Server is not running',
+ 'Start Server',
+ 'Show Output'
+ );
+
+ if (action === 'Start Server') {
+ await restartServerCommand();
+ } else if (action === 'Show Output') {
+ outputChannel.show();
+ }
+ return;
+ }
+
+ const uri = editor.document.uri;
+ outputChannel.appendLine(`Validating: ${uri.fsPath}`);
+
+ try {
+ // Force document sync by waiting for diagnostics
+ if (editor.document.isDirty) {
+ await new Promise(resolve => setTimeout(resolve, 200));
+ }
+
+ // Get current diagnostics for the document
+ const diagnostics = vscode.languages.getDiagnostics(uri);
+ const sqlDiagnostics = diagnostics.filter(d =>
+ d.source === 'gosqlx' || d.source === 'GoSQLX' || d.source === undefined
+ );
+
+ const duration = timer.stop();
+ metrics.record('command.validate', duration, true, { diagnosticCount: sqlDiagnostics.length });
+ telemetry.recordCommand('validate', duration, true);
+
+ if (sqlDiagnostics.length === 0) {
+ vscode.window.showInformationMessage('SQL validation complete. No issues found.');
+ } else {
+ const errorCount = sqlDiagnostics.filter(d => d.severity === vscode.DiagnosticSeverity.Error).length;
+ const warningCount = sqlDiagnostics.filter(d => d.severity === vscode.DiagnosticSeverity.Warning).length;
+ const infoCount = sqlDiagnostics.length - errorCount - warningCount;
+
+ const message = 'SQL validation complete: ';
+ const parts: string[] = [];
+ if (errorCount > 0) { parts.push(`${errorCount} error(s)`); }
+ if (warningCount > 0) { parts.push(`${warningCount} warning(s)`); }
+ if (infoCount > 0) { parts.push(`${infoCount} info`); }
+
+ if (parts.length === 0) {
+ vscode.window.showInformationMessage('SQL validation complete. No issues found.');
+ } else if (errorCount > 0) {
+ vscode.window.showErrorMessage(`${message}${parts.join(', ')}. Check the Problems panel.`);
+ } else {
+ vscode.window.showWarningMessage(`${message}${parts.join(', ')}. Check the Problems panel.`);
+ }
+ }
+
+ // Focus the Problems panel if there are issues
+ if (sqlDiagnostics.length > 0) {
+ await vscode.commands.executeCommand('workbench.actions.view.problems');
+ }
+
+ if (performanceStatusBarItem) {
+ updatePerformanceStatusBar(performanceStatusBarItem, metrics);
+ }
+ } catch (error) {
+ const duration = timer.stop();
+ const errorMessage = formatError(error);
+
+ metrics.record('command.validate', duration, false);
+ telemetry.recordCommand('validate', duration, false, extractErrorCode(error));
+
+ outputChannel.appendLine(`Validation error: ${errorMessage}`);
+ vscode.window.showInformationMessage('SQL validation triggered. Check the Problems panel for any issues.');
+ }
+}
+
+async function formatCommand(): Promise {
+ const timer = new PerformanceTimer();
+ timer.start();
+
+ const editor = vscode.window.activeTextEditor;
+ if (!editor || !isSqlLanguageId(editor.document.languageId)) {
+ vscode.window.showWarningMessage(
+ 'No SQL file is open. Open a .sql file to format.',
+ 'Open File'
+ ).then(action => {
+ if (action === 'Open File') {
+ vscode.commands.executeCommand('workbench.action.files.openFile');
+ }
+ });
+ return;
+ }
+
+ if (!client) {
+ const action = await vscode.window.showErrorMessage(
+ 'GoSQLX Language Server is not running',
+ 'Start Server',
+ 'Show Output'
+ );
+
+ if (action === 'Start Server') {
+ await restartServerCommand();
+ } else if (action === 'Show Output') {
+ outputChannel.show();
+ }
+ return;
+ }
+
+ try {
+ // Use VS Code's built-in format command which will use our LSP server
+ await vscode.commands.executeCommand('editor.action.formatDocument');
+
+ const duration = timer.stop();
+ metrics.record('command.format', duration, true);
+ telemetry.recordCommand('format', duration, true);
+
+ outputChannel.appendLine(`Formatted: ${editor.document.uri.fsPath} (${duration}ms)`);
+
+ if (performanceStatusBarItem) {
+ updatePerformanceStatusBar(performanceStatusBarItem, metrics);
+ }
+ } catch (error) {
+ const duration = timer.stop();
+ const errorMessage = formatError(error);
+
+ metrics.record('command.format', duration, false);
+ telemetry.recordCommand('format', duration, false, extractErrorCode(error));
+
+ vscode.window.showErrorMessage(`Format failed: ${errorMessage}`);
+ }
+}
+
+async function analyzeCommand(): Promise {
+ const timer = new PerformanceTimer();
+ timer.start();
+
+ const editor = vscode.window.activeTextEditor;
+ if (!editor || !isSqlLanguageId(editor.document.languageId)) {
+ vscode.window.showWarningMessage(
+ 'No SQL file is open. Open a .sql file to analyze.',
+ 'Open File'
+ ).then(action => {
+ if (action === 'Open File') {
+ vscode.commands.executeCommand('workbench.action.files.openFile');
+ }
+ });
+ return;
+ }
+
+ const text = editor.document.getText();
+ const config = vscode.workspace.getConfiguration('gosqlx');
+ const executablePath = config.get('executablePath', 'gosqlx');
+ const analysisTimeout = config.get('timeouts.analysis', 30000);
+
+ // Show progress indicator
+ await vscode.window.withProgress({
+ location: vscode.ProgressLocation.Notification,
+ title: 'Analyzing SQL...',
+ cancellable: true
+ }, async (progress, cancellationToken) => {
+ try {
+ const result = await new Promise<{ stdout: string; stderr: string }>((resolve, reject) => {
+ const child = spawn(executablePath, ['analyze'], {
+ stdio: ['pipe', 'pipe', 'pipe']
+ });
+
+ let stdout = '';
+ let stderr = '';
+ let outputSize = 0;
+ const maxSize = 5 * 1024 * 1024; // 5MB limit
+
+ // Set a timeout using configured value
+ const timeout = setTimeout(() => {
+ child.kill();
+ reject(new Error(`Analysis timed out after ${analysisTimeout / 1000} seconds. Try increasing gosqlx.timeouts.analysis in settings.`));
+ }, analysisTimeout);
+
+ // Handle cancellation
+ cancellationToken.onCancellationRequested(() => {
+ child.kill();
+ clearTimeout(timeout);
+ reject(new Error('Analysis cancelled by user'));
+ });
+
+ if (child.stdout) {
+ child.stdout.on('data', (data: Buffer) => {
+ outputSize += data.length;
+ if (outputSize < maxSize) {
+ stdout += data.toString();
+ }
+ });
+ }
+
+ if (child.stderr) {
+ child.stderr.on('data', (data: Buffer) => {
+ stderr += data.toString();
+ });
+ }
+
+ child.on('close', (code: number | null) => {
+ clearTimeout(timeout);
+ if (code === 0 || code === null) {
+ resolve({ stdout, stderr });
+ } else {
+ reject(new Error(`Process exited with code ${code}: ${stderr || 'Unknown error'}`));
+ }
+ });
+
+ child.on('error', (err: Error) => {
+ clearTimeout(timeout);
+ reject(err);
+ });
+
+ // Send SQL content via stdin
+ if (child.stdin) {
+ child.stdin.write(text);
+ child.stdin.end();
+ }
+ });
+
+ const duration = timer.stop();
+ metrics.record('command.analyze', duration, true, { outputSize: result.stdout.length });
+ telemetry.recordCommand('analyze', duration, true);
+
+ if (result.stderr) {
+ outputChannel.appendLine(`Analysis stderr: ${result.stderr}`);
+ }
+
+ // Show analysis results in a new document
+ const doc = await vscode.workspace.openTextDocument({
+ content: result.stdout || 'No analysis output',
+ language: 'markdown'
+ });
+ await vscode.window.showTextDocument(doc, { preview: true });
+
+ outputChannel.appendLine(`Analyzed: ${editor.document.uri.fsPath} (${duration}ms)`);
+
+ if (performanceStatusBarItem) {
+ updatePerformanceStatusBar(performanceStatusBarItem, metrics);
+ }
+ } catch (error) {
+ const duration = timer.stop();
+ const errorMessage = formatError(error);
+ const errorCode = extractErrorCode(error);
+
+ metrics.record('command.analyze', duration, false, { error: errorCode || 'unknown' });
+ telemetry.recordCommand('analyze', duration, false, errorCode);
+
+ const detailedMessage = getAnalysisErrorMessage(errorMessage);
+ outputChannel.appendLine(detailedMessage);
+
+ vscode.window.showErrorMessage(
+ `Analysis failed: ${errorMessage}`,
+ 'Show Details'
+ ).then(action => {
+ if (action === 'Show Details') {
+ outputChannel.show();
+ }
+ });
+ }
+ });
+}
+
+async function showMetricsCommand(): Promise {
+ await showMetricsReport();
+}
+
+async function validateConfigurationCommand(): Promise {
+ await validateAndWarnConfiguration();
+ outputChannel.show();
+ vscode.window.showInformationMessage('Configuration validation complete. Check the output channel for details.');
+}
+
+export async function deactivate(): Promise {
+ telemetry.recordEvent('extension.deactivated');
+
+ // Get final metrics summary
+ const summary = metrics.getSummary();
+ outputChannel.appendLine('\n' + summary);
+
+ // Cleanup
+ await stopLanguageServer();
+ telemetry.dispose();
+ metrics.dispose();
+}
diff --git a/vscode-extension/src/test/extension.test.ts b/vscode-extension/src/test/extension.test.ts
new file mode 100644
index 0000000..f21c85e
--- /dev/null
+++ b/vscode-extension/src/test/extension.test.ts
@@ -0,0 +1,83 @@
+import * as assert from 'assert';
+import * as vscode from 'vscode';
+
+suite('GoSQLX Extension Test Suite', () => {
+ vscode.window.showInformationMessage('Starting GoSQLX extension tests');
+
+ test('Extension should be present', () => {
+ const extension = vscode.extensions.getExtension('ajitpratap0.gosqlx');
+ assert.ok(extension, 'Extension should be installed');
+ });
+
+ test('Extension should activate on SQL file', async () => {
+ // Create a new SQL document
+ const document = await vscode.workspace.openTextDocument({
+ language: 'sql',
+ content: 'SELECT * FROM users;'
+ });
+
+ // Show the document to trigger activation
+ await vscode.window.showTextDocument(document);
+
+ // Give the extension time to activate
+ await new Promise(resolve => setTimeout(resolve, 1000));
+
+ const extension = vscode.extensions.getExtension('ajitpratap0.gosqlx');
+ if (extension) {
+ // Extension may or may not be active depending on LSP availability
+ assert.ok(true, 'Extension loaded without errors');
+ }
+ });
+
+ test('Commands should be registered', async () => {
+ const commands = await vscode.commands.getCommands(true);
+
+ const expectedCommands = [
+ 'gosqlx.validate',
+ 'gosqlx.format',
+ 'gosqlx.analyze',
+ 'gosqlx.restartServer',
+ 'gosqlx.showOutput'
+ ];
+
+ for (const cmd of expectedCommands) {
+ assert.ok(
+ commands.includes(cmd),
+ `Command ${cmd} should be registered`
+ );
+ }
+ });
+
+ test('Configuration should have defaults', () => {
+ const config = vscode.workspace.getConfiguration('gosqlx');
+
+ assert.strictEqual(config.get('enable'), true, 'enable should default to true');
+ assert.strictEqual(config.get('executablePath'), 'gosqlx', 'executablePath should default to gosqlx');
+ assert.strictEqual(config.get('format.indentSize'), 2, 'indentSize should default to 2');
+ assert.strictEqual(config.get('format.uppercaseKeywords'), true, 'uppercaseKeywords should default to true');
+ assert.strictEqual(config.get('dialect'), 'generic', 'dialect should default to generic');
+ });
+
+ test('SQL language should be recognized', async () => {
+ const document = await vscode.workspace.openTextDocument({
+ language: 'sql',
+ content: 'SELECT 1;'
+ });
+
+ assert.strictEqual(document.languageId, 'sql', 'Document should be recognized as SQL');
+ });
+
+ test('Validate command should handle missing editor gracefully', async () => {
+ // Close all editors
+ await vscode.commands.executeCommand('workbench.action.closeAllEditors');
+
+ // This should not throw an error, just show a warning
+ try {
+ await vscode.commands.executeCommand('gosqlx.validate');
+ assert.ok(true, 'Validate command handled missing editor');
+ } catch (error) {
+ // Command might fail if no editor is open, which is expected behavior
+ assert.ok(true, 'Validate command threw expected error');
+ }
+ });
+});
diff --git a/vscode-extension/src/test/runTest.ts b/vscode-extension/src/test/runTest.ts
new file mode 100644
index 0000000..4b2208d
--- /dev/null
+++ b/vscode-extension/src/test/runTest.ts
@@ -0,0 +1,20 @@
+import * as path from 'path';
+import { runTests } from '@vscode/test-electron';
+
+async function main() {
+ try {
+ // The folder containing the Extension Manifest package.json
+ const extensionDevelopmentPath = path.resolve(__dirname, '../../');
+
+ // The path to the test runner script
+ const extensionTestsPath = path.resolve(__dirname, './suite/index');
+
+ // Download VS Code, unzip it, and run the integration tests
+ await runTests({ extensionDevelopmentPath, extensionTestsPath });
+ } catch (err) {
+ console.error('Failed to run tests:', err);
+ process.exit(1);
+ }
+}
+
+main();
diff --git a/vscode-extension/src/test/suite/index.ts b/vscode-extension/src/test/suite/index.ts
new file mode 100644
index 0000000..3b8863a
--- /dev/null
+++ b/vscode-extension/src/test/suite/index.ts
@@ -0,0 +1,35 @@
+import * as path from 'path';
+import Mocha from 'mocha';
+import { glob } from 'glob';
+
+export async function run(): Promise {
+ // Create the mocha test
+ const mocha = new Mocha({
+ ui: 'tdd',
+ color: true,
+ timeout: 60000
+ });
+
+ const testsRoot = path.resolve(__dirname, '..');
+
+ const files = await glob('**/**.test.js', { cwd: testsRoot });
+
+ // Add files to the test suite
+ files.forEach((f: string) => mocha.addFile(path.resolve(testsRoot, f)));
+
+ return new Promise((resolve, reject) => {
+ try {
+ // Run the mocha test
+ mocha.run((failures: number) => {
+ if (failures > 0) {
+ reject(new Error(`${failures} tests failed.`));
+ } else {
+ resolve();
+ }
+ });
+ } catch (err) {
+ console.error(err);
+ reject(err);
+ }
+ });
+}
diff --git a/vscode-extension/src/test/unit/commands.test.ts b/vscode-extension/src/test/unit/commands.test.ts
new file mode 100644
index 0000000..38e509f
--- /dev/null
+++ b/vscode-extension/src/test/unit/commands.test.ts
@@ -0,0 +1,542 @@
+import * as assert from 'assert';
+import * as os from 'os';
+import * as path from 'path';
+
+/**
+ * Unit tests for GoSQLX extension command functions.
+ * These tests validate individual functions without external dependencies.
+ */
+
+// Configuration validation tests
+suite('Configuration Validation Unit Tests', () => {
+
+ test('validateIndentSize should accept valid values', () => {
+ const validValues = [1, 2, 4, 8];
+ for (const value of validValues) {
+ const result = validateIndentSize(value);
+ assert.strictEqual(result.valid, true, `Indent size ${value} should be valid`);
+ }
+ });
+
+ test('validateIndentSize should reject invalid values', () => {
+ const invalidValues = [-1, 0, 100, NaN];
+ for (const value of invalidValues) {
+ const result = validateIndentSize(value);
+ assert.strictEqual(result.valid, false, `Indent size ${value} should be invalid`);
+ }
+ });
+
+ test('validateDialect should accept valid dialects', () => {
+ const validDialects = ['generic', 'postgresql', 'mysql', 'sqlserver', 'oracle', 'sqlite'];
+ for (const dialect of validDialects) {
+ const result = validateDialect(dialect);
+ assert.strictEqual(result.valid, true, `Dialect ${dialect} should be valid`);
+ }
+ });
+
+ test('validateDialect should reject invalid dialects', () => {
+ const invalidDialects = ['nosql', 'mongodb', 'invalid', ''];
+ for (const dialect of invalidDialects) {
+ const result = validateDialect(dialect);
+ assert.strictEqual(result.valid, false, `Dialect ${dialect} should be invalid`);
+ }
+ });
+
+ test('validateExecutablePath should handle path formats', () => {
+ // Valid paths
+ assert.strictEqual(validateExecutablePath('gosqlx').valid, true);
+ assert.strictEqual(validateExecutablePath('/usr/local/bin/gosqlx').valid, true);
+ assert.strictEqual(validateExecutablePath('C:\\Program Files\\gosqlx\\gosqlx.exe').valid, true);
+
+ // Invalid paths
+ assert.strictEqual(validateExecutablePath('').valid, false);
+ });
+
+ test('validateTimeout should accept reasonable values', () => {
+ assert.strictEqual(validateTimeout(1000).valid, true);
+ assert.strictEqual(validateTimeout(5000).valid, true);
+ assert.strictEqual(validateTimeout(30000).valid, true);
+ assert.strictEqual(validateTimeout(60000).valid, true);
+
+ // Edge cases
+ assert.strictEqual(validateTimeout(0).valid, false);
+ assert.strictEqual(validateTimeout(-1).valid, false);
+ assert.strictEqual(validateTimeout(1000000).valid, false); // Too high
+ });
+});
+
+// Error message generation tests
+suite('Error Message Generation Unit Tests', () => {
+
+ test('getExecutableNotFoundMessage should include installation instructions', () => {
+ const message = getExecutableNotFoundMessage('gosqlx');
+ assert.ok(message.includes('go install'), 'Should include go install command');
+ assert.ok(message.includes('PATH'), 'Should mention PATH');
+ });
+
+ test('getExecutableNotFoundMessage should handle custom paths', () => {
+ const message = getExecutableNotFoundMessage('/custom/path/gosqlx');
+ assert.ok(message.includes('/custom/path/gosqlx'), 'Should include the custom path');
+ assert.ok(message.includes('check if the file exists'), 'Should suggest checking file');
+ });
+
+ test('getLspStartFailureMessage should provide retry info', () => {
+ const message = getLspStartFailureMessage('connection refused', 2, 3);
+ assert.ok(message.includes('connection refused'), 'Should include error');
+ assert.ok(message.includes('2'), 'Should include attempt number');
+ });
+
+ test('getConfigurationErrorMessage should suggest fixes', () => {
+ const message = getConfigurationErrorMessage('indentSize', -1);
+ assert.ok(message.includes('indentSize'), 'Should include setting name');
+ assert.ok(message.includes('valid'), 'Should mention valid values');
+ });
+
+ test('getCommonSetupErrorMessage should identify common issues', () => {
+ // ENOENT - executable not found
+ const enoent = getCommonSetupErrorMessage('ENOENT');
+ assert.ok(enoent.includes('not found') || enoent.includes('install'), 'Should explain ENOENT');
+
+ // EACCES - permission denied
+ const eacces = getCommonSetupErrorMessage('EACCES');
+ assert.ok(eacces.includes('permission') || eacces.includes('chmod'), 'Should explain EACCES');
+
+ // ETIMEDOUT - connection timeout
+ const timeout = getCommonSetupErrorMessage('ETIMEDOUT');
+ assert.ok(timeout.includes('timeout') || timeout.includes('slow'), 'Should explain timeout');
+ });
+});
+
+// Diagnostic filtering tests
+suite('Diagnostic Filtering Unit Tests', () => {
+
+ test('filterSqlDiagnostics should filter by source', () => {
+ const mockDiagnostics = [
+ { source: 'gosqlx', message: 'error 1', severity: 0 },
+ { source: 'typescript', message: 'ts error', severity: 0 },
+ { source: 'GoSQLX', message: 'error 2', severity: 1 },
+ { source: undefined, message: 'unknown', severity: 2 }
+ ] as MockDiagnostic[];
+
+ const filtered = filterSqlDiagnostics(mockDiagnostics);
+ assert.strictEqual(filtered.length, 3, 'Should include gosqlx, GoSQLX, and undefined sources');
+ });
+
+ test('countDiagnosticsBySeverity should categorize correctly', () => {
+ const mockDiagnostics = [
+ { severity: 0 }, // Error
+ { severity: 0 }, // Error
+ { severity: 1 }, // Warning
+ { severity: 2 }, // Info
+ { severity: 2 } // Info
+ ] as MockDiagnostic[];
+
+ const counts = countDiagnosticsBySeverity(mockDiagnostics);
+ assert.strictEqual(counts.errors, 2);
+ assert.strictEqual(counts.warnings, 1);
+ assert.strictEqual(counts.info, 2);
+ });
+
+ test('formatDiagnosticMessage should handle various counts', () => {
+ assert.strictEqual(
+ formatDiagnosticMessage({ errors: 0, warnings: 0, info: 0 }),
+ 'No issues found.'
+ );
+
+ assert.ok(
+ formatDiagnosticMessage({ errors: 1, warnings: 0, info: 0 }).includes('1 error')
+ );
+
+ assert.ok(
+ formatDiagnosticMessage({ errors: 2, warnings: 3, info: 1 }).includes('2 error')
+ );
+ });
+});
+
+// Timeout calculation tests
+suite('Timeout Calculation Unit Tests', () => {
+
+ test('calculateExponentialBackoff should increase exponentially', () => {
+ assert.strictEqual(calculateExponentialBackoff(0), 1000);
+ assert.strictEqual(calculateExponentialBackoff(1), 2000);
+ assert.strictEqual(calculateExponentialBackoff(2), 4000);
+ assert.strictEqual(calculateExponentialBackoff(3), 8000);
+ });
+
+ test('calculateExponentialBackoff should cap at maximum', () => {
+ const maxBackoff = 30000;
+ const result = calculateExponentialBackoff(10, maxBackoff);
+ assert.ok(result <= maxBackoff, 'Should not exceed max backoff');
+ });
+
+ test('getEffectiveTimeout should apply user override', () => {
+ const defaultTimeout = 30000;
+ const userTimeout = 60000;
+
+ assert.strictEqual(
+ getEffectiveTimeout(undefined, defaultTimeout),
+ defaultTimeout
+ );
+
+ assert.strictEqual(
+ getEffectiveTimeout(userTimeout, defaultTimeout),
+ userTimeout
+ );
+ });
+});
+
+// Path handling tests
+suite('Path Handling Unit Tests', () => {
+
+ test('normalizeExecutablePath should handle platform differences', () => {
+ // Unix-style paths
+ assert.strictEqual(
+ normalizeExecutablePath('/usr/local/bin/gosqlx'),
+ '/usr/local/bin/gosqlx'
+ );
+
+ // Simple command names
+ assert.strictEqual(
+ normalizeExecutablePath('gosqlx'),
+ 'gosqlx'
+ );
+ });
+
+ test('isAbsolutePath should detect absolute paths', () => {
+ // Unix absolute
+ assert.strictEqual(isAbsolutePath('/usr/bin/gosqlx'), true);
+
+ // Windows absolute
+ assert.strictEqual(isAbsolutePath('C:\\Program Files\\gosqlx'), true);
+
+ // Relative
+ assert.strictEqual(isAbsolutePath('gosqlx'), false);
+ assert.strictEqual(isAbsolutePath('./gosqlx'), false);
+ });
+
+ test('getDebugLogPath should create valid path', () => {
+ const logPath = getDebugLogPath();
+ assert.ok(logPath.includes('gosqlx'), 'Should include gosqlx in path');
+ assert.ok(logPath.endsWith('.log'), 'Should end with .log');
+ });
+});
+
+// Language detection tests
+suite('Language Detection Unit Tests', () => {
+
+ test('isSqlLanguageId should recognize SQL variants', () => {
+ assert.strictEqual(isSqlLanguageId('sql'), true);
+ assert.strictEqual(isSqlLanguageId('SQL'), true);
+ assert.strictEqual(isSqlLanguageId('pgsql'), true);
+ assert.strictEqual(isSqlLanguageId('mysql'), true);
+ assert.strictEqual(isSqlLanguageId('plpgsql'), true);
+
+ assert.strictEqual(isSqlLanguageId('javascript'), false);
+ assert.strictEqual(isSqlLanguageId('python'), false);
+ });
+
+ test('getSqlFileExtensions should return all supported extensions', () => {
+ const extensions = getSqlFileExtensions();
+ assert.ok(extensions.includes('.sql'));
+ assert.ok(extensions.includes('.pgsql'));
+ assert.ok(extensions.includes('.psql'));
+ assert.ok(extensions.includes('.mysql'));
+ });
+});
+
+// Telemetry sanitization tests
+suite('Telemetry Data Sanitization Unit Tests', () => {
+
+ test('sanitizeTelemetryData should remove sensitive info', () => {
+ const data = {
+ command: 'validate',
+ filePath: '/home/user/secret/query.sql',
+ sqlContent: 'SELECT password FROM users',
+ timestamp: Date.now()
+ };
+
+ const sanitized = sanitizeTelemetryData(data);
+
+ // Should keep command and timestamp
+ assert.strictEqual(sanitized.command, 'validate');
+ assert.ok(sanitized.timestamp);
+
+ // Should sanitize or remove sensitive data
+ assert.ok(!sanitized.sqlContent || sanitized.sqlContent === '[redacted]');
+ assert.ok(!sanitized.filePath?.includes('secret'));
+ });
+
+ test('extractFileExtension should get extension safely', () => {
+ assert.strictEqual(extractFileExtension('/path/to/file.sql'), '.sql');
+ assert.strictEqual(extractFileExtension('query.pgsql'), '.pgsql');
+ assert.strictEqual(extractFileExtension('noextension'), '');
+ });
+});
+
+// Performance metrics tests
+suite('Performance Metrics Unit Tests', () => {
+
+ test('PerformanceTimer should measure duration', async () => {
+ const timer = new PerformanceTimer();
+ timer.start();
+
+ await new Promise(resolve => setTimeout(resolve, 50));
+
+ const duration = timer.stop();
+ assert.ok(duration >= 40, 'Duration should be at least 40ms');
+ assert.ok(duration < 200, 'Duration should be less than 200ms');
+ });
+
+ test('MetricsCollector should track operation counts', () => {
+ const collector = new MetricsCollector();
+
+ collector.recordOperation('validate');
+ collector.recordOperation('validate');
+ collector.recordOperation('format');
+
+ const stats = collector.getStats();
+ assert.strictEqual(stats.validate, 2);
+ assert.strictEqual(stats.format, 1);
+ });
+
+ test('MetricsCollector should calculate averages', () => {
+ const collector = new MetricsCollector();
+
+ collector.recordDuration('validate', 100);
+ collector.recordDuration('validate', 200);
+ collector.recordDuration('validate', 300);
+
+ const avg = collector.getAverageDuration('validate');
+ assert.strictEqual(avg, 200);
+ });
+});
+
+// =========================================================================
+// Implementation stubs for unit testing
+// These would typically be imported from the main extension module
+// =========================================================================
+
+interface ValidationResult {
+ valid: boolean;
+ message?: string;
+}
+
+interface MockDiagnostic {
+ source?: string;
+ message?: string;
+ severity: number;
+}
+
+interface DiagnosticCounts {
+ errors: number;
+ warnings: number;
+ info: number;
+}
+
+interface TelemetryData {
+ command?: string;
+ filePath?: string;
+ sqlContent?: string;
+ timestamp?: number;
+ fileExtension?: string;
+}
+
+function validateIndentSize(value: number): ValidationResult {
+ if (isNaN(value) || value < 1 || value > 16) {
+ return { valid: false, message: 'Indent size must be between 1 and 16' };
+ }
+ return { valid: true };
+}
+
+function validateDialect(dialect: string): ValidationResult {
+ const validDialects = ['generic', 'postgresql', 'mysql', 'sqlserver', 'oracle', 'sqlite'];
+ if (!validDialects.includes(dialect.toLowerCase())) {
+ return { valid: false, message: `Invalid dialect. Valid options: ${validDialects.join(', ')}` };
+ }
+ return { valid: true };
+}
+
+function validateExecutablePath(path: string): ValidationResult {
+ if (!path || path.trim().length === 0) {
+ return { valid: false, message: 'Executable path cannot be empty' };
+ }
+ return { valid: true };
+}
+
+function validateTimeout(timeout: number): ValidationResult {
+ if (timeout <= 0) {
+ return { valid: false, message: 'Timeout must be positive' };
+ }
+ if (timeout > 300000) { // 5 minutes max
+ return { valid: false, message: 'Timeout cannot exceed 5 minutes (300000ms)' };
+ }
+ return { valid: true };
+}
+
+function getExecutableNotFoundMessage(executablePath: string): string {
+ if (executablePath === 'gosqlx') {
+ return `GoSQLX executable not found. Please install it:\n\n` +
+ ` go install github.com/ajitpratap0/GoSQLX/cmd/gosqlx@latest\n\n` +
+ `Then ensure it's in your PATH. You can verify with:\n\n` +
+ ` which gosqlx\n` +
+ ` gosqlx --version`;
+ }
+ return `GoSQLX executable not found at: ${executablePath}\n\n` +
+ `Please check if the file exists and has execute permissions.\n` +
+ `You can also try using just 'gosqlx' if it's in your PATH.`;
+}
+
+function getLspStartFailureMessage(error: string, attempt: number, maxAttempts: number): string {
+ return `Failed to start GoSQLX Language Server (attempt ${attempt}/${maxAttempts}):\n${error}\n\n` +
+ `Check the GoSQLX output channel for more details.`;
+}
+
+function getConfigurationErrorMessage(settingName: string, value: unknown): string {
+ return `Invalid configuration for '${settingName}': ${value}\n` +
+ `Please check your settings for valid values.`;
+}
+
+function getCommonSetupErrorMessage(errorCode: string): string {
+ const messages: { [key: string]: string } = {
+ 'ENOENT': 'The gosqlx executable was not found. Please install it with: go install github.com/ajitpratap0/GoSQLX/cmd/gosqlx@latest',
+ 'EACCES': 'Permission denied. Please check that gosqlx has execute permissions: chmod +x $(which gosqlx)',
+ 'ETIMEDOUT': 'Connection timed out. The language server may be slow to start. Try increasing the timeout in settings.',
+ 'ECONNREFUSED': 'Connection refused. The language server may have crashed. Try restarting it.',
+ };
+ return messages[errorCode] || `An error occurred: ${errorCode}. Check the output channel for details.`;
+}
+
+function filterSqlDiagnostics(diagnostics: MockDiagnostic[]): MockDiagnostic[] {
+ return diagnostics.filter(d =>
+ d.source === 'gosqlx' || d.source === 'GoSQLX' || d.source === undefined
+ );
+}
+
+function countDiagnosticsBySeverity(diagnostics: MockDiagnostic[]): DiagnosticCounts {
+ return {
+ errors: diagnostics.filter(d => d.severity === 0).length,
+ warnings: diagnostics.filter(d => d.severity === 1).length,
+ info: diagnostics.filter(d => d.severity === 2 || d.severity === 3).length
+ };
+}
+
+function formatDiagnosticMessage(counts: DiagnosticCounts): string {
+ if (counts.errors === 0 && counts.warnings === 0 && counts.info === 0) {
+ return 'No issues found.';
+ }
+
+ const parts: string[] = [];
+ if (counts.errors > 0) {
+ parts.push(`${counts.errors} error${counts.errors !== 1 ? 's' : ''}`);
+ }
+ if (counts.warnings > 0) {
+ parts.push(`${counts.warnings} warning${counts.warnings !== 1 ? 's' : ''}`);
+ }
+ if (counts.info > 0) {
+ parts.push(`${counts.info} info`);
+ }
+
+ return parts.join(', ');
+}
+
+function calculateExponentialBackoff(attempt: number, maxBackoff: number = 30000): number {
+ const backoff = Math.pow(2, attempt) * 1000;
+ return Math.min(backoff, maxBackoff);
+}
+
+function getEffectiveTimeout(userTimeout: number | undefined, defaultTimeout: number): number {
+ return userTimeout !== undefined ? userTimeout : defaultTimeout;
+}
+
+function normalizeExecutablePath(execPath: string): string {
+ return execPath.trim();
+}
+
+function isAbsolutePath(filePath: string): boolean {
+ return filePath.startsWith('/') || /^[a-zA-Z]:[\\/]/.test(filePath);
+}
+
+function getDebugLogPath(): string {
+ return path.join(os.tmpdir(), 'gosqlx-lsp-debug.log');
+}
+
+function isSqlLanguageId(languageId: string): boolean {
+ const sqlLanguages = ['sql', 'pgsql', 'mysql', 'plpgsql', 'tsql', 'plsql'];
+ return sqlLanguages.includes(languageId.toLowerCase());
+}
+
+function getSqlFileExtensions(): string[] {
+ return ['.sql', '.pgsql', '.psql', '.mysql', '.tsql', '.plsql'];
+}
+
+function sanitizeTelemetryData(data: TelemetryData): TelemetryData {
+ const sanitized: TelemetryData = {};
+
+ if (data.command) {
+ sanitized.command = data.command;
+ }
+
+ if (data.timestamp) {
+ sanitized.timestamp = data.timestamp;
+ }
+
+ if (data.filePath) {
+ // Only keep the extension, not the full path
+ sanitized.fileExtension = extractFileExtension(data.filePath);
+ }
+
+ // Never include SQL content
+ if (data.sqlContent) {
+ sanitized.sqlContent = '[redacted]';
+ }
+
+ return sanitized;
+}
+
+function extractFileExtension(filePath: string): string {
+ const lastDot = filePath.lastIndexOf('.');
+ if (lastDot === -1 || lastDot === filePath.length - 1) {
+ return '';
+ }
+ return filePath.substring(lastDot);
+}
+
+class PerformanceTimer {
+ private startTime: number = 0;
+
+ start(): void {
+ this.startTime = Date.now();
+ }
+
+ stop(): number {
+ return Date.now() - this.startTime;
+ }
+}
+
+class MetricsCollector {
+ private operations: { [key: string]: number } = {};
+ private durations: { [key: string]: number[] } = {};
+
+ recordOperation(name: string): void {
+ this.operations[name] = (this.operations[name] || 0) + 1;
+ }
+
+ recordDuration(name: string, duration: number): void {
+ if (!this.durations[name]) {
+ this.durations[name] = [];
+ }
+ this.durations[name].push(duration);
+ }
+
+ getStats(): { [key: string]: number } {
+ return { ...this.operations };
+ }
+
+ getAverageDuration(name: string): number {
+ const durations = this.durations[name];
+ if (!durations || durations.length === 0) {
+ return 0;
+ }
+ return durations.reduce((a, b) => a + b, 0) / durations.length;
+ }
+}
diff --git a/vscode-extension/src/utils/errors.ts b/vscode-extension/src/utils/errors.ts
new file mode 100644
index 0000000..001f269
--- /dev/null
+++ b/vscode-extension/src/utils/errors.ts
@@ -0,0 +1,310 @@
+/**
+ * Error messaging utilities for GoSQLX extension.
+ * Provides detailed, actionable error messages for common issues.
+ */
+
+import * as os from 'os';
+
+export interface ErrorContext {
+ code?: string;
+ message?: string;
+ executablePath?: string;
+ attempt?: number;
+ maxAttempts?: number;
+ platform?: NodeJS.Platform;
+}
+
+/**
+ * Common error codes and their meanings.
+ */
+export const ERROR_CODES = {
+ ENOENT: 'File or command not found',
+ EACCES: 'Permission denied',
+ ETIMEDOUT: 'Operation timed out',
+ ECONNREFUSED: 'Connection refused',
+ ECONNRESET: 'Connection reset',
+ EPERM: 'Operation not permitted',
+ ENOTFOUND: 'DNS lookup failed',
+ EADDRINUSE: 'Address already in use'
+} as const;
+
+/**
+ * Gets a detailed, actionable error message for executable not found.
+ */
+export function getExecutableNotFoundMessage(executablePath: string, platform: NodeJS.Platform = os.platform()): string {
+ const isDefaultPath = executablePath === 'gosqlx';
+ const isWindows = platform === 'win32';
+
+ let message = `GoSQLX executable not found: "${executablePath}"\n\n`;
+
+ if (isDefaultPath) {
+ message += `The 'gosqlx' command was not found in your system PATH.\n\n`;
+ message += `To fix this, install GoSQLX:\n\n`;
+ message += ` go install github.com/ajitpratap0/GoSQLX/cmd/gosqlx@latest\n\n`;
+
+ if (isWindows) {
+ message += `Then verify installation:\n`;
+ message += ` where gosqlx\n`;
+ message += ` gosqlx --version\n\n`;
+ message += `If 'go install' succeeded but 'where gosqlx' fails:\n`;
+ message += ` 1. Ensure %GOPATH%\\bin is in your PATH\n`;
+ message += ` 2. Default GOPATH is %USERPROFILE%\\go\n`;
+ message += ` 3. Restart VS Code after modifying PATH\n`;
+ } else {
+ message += `Then verify installation:\n`;
+ message += ` which gosqlx\n`;
+ message += ` gosqlx --version\n\n`;
+ message += `If 'go install' succeeded but 'which gosqlx' fails:\n`;
+ message += ` 1. Ensure $GOPATH/bin is in your PATH\n`;
+ message += ` 2. Add to ~/.bashrc or ~/.zshrc:\n`;
+ message += ` export PATH="$PATH:$(go env GOPATH)/bin"\n`;
+ message += ` 3. Restart your terminal and VS Code\n`;
+ }
+ } else {
+ message += `The specified path does not exist or is not executable.\n\n`;
+ message += `To fix this:\n`;
+ message += ` 1. Check if the file exists:\n`;
+ message += isWindows
+ ? ` dir "${executablePath}"\n`
+ : ` ls -la "${executablePath}"\n`;
+ message += ` 2. If it doesn't exist, either:\n`;
+ message += ` - Install gosqlx and update the path in settings\n`;
+ message += ` - Remove the custom path to use PATH lookup\n\n`;
+
+ if (!isWindows) {
+ message += ` 3. Ensure execute permissions:\n`;
+ message += ` chmod +x "${executablePath}"\n`;
+ }
+ }
+
+ return message;
+}
+
+/**
+ * Gets a detailed error message for LSP startup failure.
+ */
+export function getLspStartFailureMessage(
+ error: string,
+ attempt: number,
+ maxAttempts: number,
+ executablePath: string
+): string {
+ let message = `Failed to start GoSQLX Language Server`;
+
+ if (maxAttempts > 1) {
+ message += ` (attempt ${attempt}/${maxAttempts})`;
+ }
+
+ message += `:\n\n${error}\n\n`;
+
+ // Provide specific guidance based on error content
+ if (error.includes('ENOENT') || error.includes('not found')) {
+ message += `The gosqlx executable was not found.\n`;
+ message += `Run: go install github.com/ajitpratap0/GoSQLX/cmd/gosqlx@latest\n`;
+ } else if (error.includes('EACCES') || error.includes('permission')) {
+ message += `Permission denied when trying to execute gosqlx.\n`;
+ message += `Run: chmod +x "${executablePath}"\n`;
+ } else if (error.includes('timeout') || error.includes('ETIMEDOUT')) {
+ message += `The language server took too long to start.\n`;
+ message += `Try increasing the startup timeout in settings.\n`;
+ } else if (error.includes('JSON') || error.includes('parse')) {
+ message += `The language server returned invalid data.\n`;
+ message += `This may indicate a version mismatch. Try reinstalling:\n`;
+ message += ` go install github.com/ajitpratap0/GoSQLX/cmd/gosqlx@latest\n`;
+ } else if (error.includes('port') || error.includes('EADDRINUSE')) {
+ message += `A port conflict was detected.\n`;
+ message += `Another instance may be running. Try restarting VS Code.\n`;
+ } else {
+ message += `Troubleshooting steps:\n`;
+ message += ` 1. Check the GoSQLX output channel for details\n`;
+ message += ` 2. Verify gosqlx works: gosqlx --version\n`;
+ message += ` 3. Try restarting the language server\n`;
+ }
+
+ return message;
+}
+
+/**
+ * Gets a detailed error message for common setup issues.
+ */
+export function getCommonSetupErrorMessage(errorCode: string, context?: ErrorContext): string {
+ const platform = context?.platform ?? os.platform();
+ const isWindows = platform === 'win32';
+
+ switch (errorCode) {
+ case 'ENOENT':
+ return getExecutableNotFoundMessage(
+ context?.executablePath ?? 'gosqlx',
+ platform
+ );
+
+ case 'EACCES':
+ case 'EPERM':
+ if (isWindows) {
+ return `Permission denied when accessing GoSQLX.\n\n` +
+ `To fix this:\n` +
+ ` 1. Run VS Code as Administrator\n` +
+ ` 2. Check Windows Defender or antivirus settings\n` +
+ ` 3. Verify the executable is not blocked`;
+ }
+ return `Permission denied when executing gosqlx.\n\n` +
+ `To fix this:\n` +
+ ` 1. Check file permissions: ls -la $(which gosqlx)\n` +
+ ` 2. Add execute permission: chmod +x $(which gosqlx)\n` +
+ ` 3. Check if the directory is mounted with noexec`;
+
+ case 'ETIMEDOUT':
+ return `Connection timed out while starting the language server.\n\n` +
+ `Possible causes:\n` +
+ ` - System is under heavy load\n` +
+ ` - Very large SQL files being processed\n` +
+ ` - Antivirus scanning the process\n\n` +
+ `To fix this:\n` +
+ ` 1. Increase timeout in settings: gosqlx.timeouts.startup\n` +
+ ` 2. Try closing other resource-intensive applications\n` +
+ ` 3. Temporarily disable antivirus and test`;
+
+ case 'ECONNREFUSED':
+ return `Connection refused by the language server.\n\n` +
+ `This usually means the server crashed or failed to start.\n\n` +
+ `To fix this:\n` +
+ ` 1. Check the GoSQLX output channel for error details\n` +
+ ` 2. Try restarting the language server\n` +
+ ` 3. Reinstall: go install github.com/ajitpratap0/GoSQLX/cmd/gosqlx@latest`;
+
+ case 'ECONNRESET':
+ return `Connection to the language server was reset.\n\n` +
+ `This may happen if:\n` +
+ ` - The server crashed unexpectedly\n` +
+ ` - System went to sleep and woke up\n` +
+ ` - Network issues on remote development\n\n` +
+ `To fix this: Try restarting the language server.`;
+
+ case 'EADDRINUSE':
+ return `The required port is already in use.\n\n` +
+ `Another instance of the language server may be running.\n\n` +
+ `To fix this:\n` +
+ ` 1. Close other VS Code windows using GoSQLX\n` +
+ ` 2. Restart VS Code\n` +
+ ` 3. Check for zombie processes: ps aux | grep gosqlx`;
+
+ default:
+ return `An error occurred: ${errorCode}\n\n` +
+ (context?.message ? `Details: ${context.message}\n\n` : '') +
+ `General troubleshooting:\n` +
+ ` 1. Check the GoSQLX output channel for details\n` +
+ ` 2. Verify gosqlx is installed: gosqlx --version\n` +
+ ` 3. Try restarting VS Code\n` +
+ ` 4. Reinstall: go install github.com/ajitpratap0/GoSQLX/cmd/gosqlx@latest`;
+ }
+}
+
+/**
+ * Gets an error message for configuration issues.
+ */
+export function getConfigurationErrorMessage(
+ settingName: string,
+ value: unknown,
+ suggestion?: string
+): string {
+ let message = `Invalid configuration for "gosqlx.${settingName}"\n\n`;
+ message += `Current value: ${JSON.stringify(value)}\n\n`;
+
+ if (suggestion) {
+ message += `${suggestion}\n\n`;
+ }
+
+ message += `To fix this:\n`;
+ message += ` 1. Open Settings (Ctrl+,)\n`;
+ message += ` 2. Search for "gosqlx.${settingName}"\n`;
+ message += ` 3. Update to a valid value\n`;
+
+ return message;
+}
+
+/**
+ * Gets an error message for validation failures.
+ */
+export function getValidationErrorMessage(documentUri: string, error: string): string {
+ return `Failed to validate SQL file:\n\n` +
+ `File: ${documentUri}\n` +
+ `Error: ${error}\n\n` +
+ `The file may contain syntax that GoSQLX doesn't recognize.\n` +
+ `Check the Problems panel for specific error locations.`;
+}
+
+/**
+ * Gets an error message for format failures.
+ */
+export function getFormatErrorMessage(documentUri: string, error: string): string {
+ let message = `Failed to format SQL file:\n\n`;
+ message += `File: ${documentUri}\n`;
+ message += `Error: ${error}\n\n`;
+
+ if (error.includes('parse') || error.includes('syntax')) {
+ message += `The file contains syntax errors that prevent formatting.\n`;
+ message += `Fix the syntax errors first, then try formatting again.`;
+ } else {
+ message += `Try the following:\n`;
+ message += ` 1. Check for syntax errors in the file\n`;
+ message += ` 2. Restart the language server\n`;
+ message += ` 3. Check the GoSQLX output channel for details`;
+ }
+
+ return message;
+}
+
+/**
+ * Gets an error message for analysis failures.
+ */
+export function getAnalysisErrorMessage(error: string): string {
+ let message = `Failed to analyze SQL:\n\n${error}\n\n`;
+
+ if (error.includes('timeout')) {
+ message += `The analysis took too long.\n`;
+ message += `Try with a smaller SQL query or increase the timeout.`;
+ } else if (error.includes('empty') || error.includes('no content')) {
+ message += `No SQL content to analyze.\n`;
+ message += `Make sure the file contains valid SQL statements.`;
+ } else {
+ message += `Troubleshooting:\n`;
+ message += ` 1. Check that the SQL syntax is valid\n`;
+ message += ` 2. Try with a simpler query first\n`;
+ message += ` 3. Check the GoSQLX output channel`;
+ }
+
+ return message;
+}
+
+/**
+ * Extracts an error code from an error object or string.
+ */
+export function extractErrorCode(error: unknown): string | undefined {
+ if (error && typeof error === 'object') {
+ const err = error as { code?: string; errno?: string };
+ return err.code ?? err.errno;
+ }
+ if (typeof error === 'string') {
+ // Try to extract error code from string
+ const match = error.match(/\b(E[A-Z]+)\b/);
+ return match?.[1];
+ }
+ return undefined;
+}
+
+/**
+ * Creates a user-friendly error message from any error type.
+ */
+export function formatError(error: unknown): string {
+ if (error instanceof Error) {
+ return error.message;
+ }
+ if (typeof error === 'string') {
+ return error;
+ }
+ if (error && typeof error === 'object') {
+ const err = error as { message?: string; toString?: () => string };
+ return err.message ?? err.toString?.() ?? 'Unknown error';
+ }
+ return 'An unknown error occurred';
+}
diff --git a/vscode-extension/src/utils/index.ts b/vscode-extension/src/utils/index.ts
new file mode 100644
index 0000000..06eacad
--- /dev/null
+++ b/vscode-extension/src/utils/index.ts
@@ -0,0 +1,62 @@
+/**
+ * GoSQLX Extension Utilities
+ *
+ * This module exports all utility functions and classes used by the extension.
+ */
+
+// Validation utilities
+export {
+ ValidationResult,
+ SqlDialect,
+ VALID_DIALECTS,
+ SQL_LANGUAGE_IDS,
+ SQL_FILE_EXTENSIONS,
+ validateIndentSize,
+ validateDialect,
+ validateExecutablePath,
+ validateTimeout,
+ validateTraceLevel,
+ validateConfiguration,
+ isSqlLanguageId,
+ getSqlFileExtensions,
+ extractFileExtension,
+ isAbsolutePath,
+ normalizeExecutablePath
+} from './validation';
+
+// Error messaging utilities
+export {
+ ErrorContext,
+ ERROR_CODES,
+ getExecutableNotFoundMessage,
+ getLspStartFailureMessage,
+ getCommonSetupErrorMessage,
+ getConfigurationErrorMessage,
+ getValidationErrorMessage,
+ getFormatErrorMessage,
+ getAnalysisErrorMessage,
+ extractErrorCode,
+ formatError
+} from './errors';
+
+// Telemetry utilities
+export {
+ TelemetryEventType,
+ TelemetryEvent,
+ SanitizedTelemetryData,
+ TelemetryManager,
+ promptTelemetryOptIn,
+ withTelemetry
+} from './telemetry';
+
+// Performance metrics utilities
+export {
+ OperationType,
+ PerformanceMeasurement,
+ OperationStats,
+ PerformanceTimer,
+ MetricsCollector,
+ showMetricsReport,
+ createPerformanceStatusBarItem,
+ updatePerformanceStatusBar
+} from './metrics';
diff --git a/vscode-extension/src/utils/metrics.ts b/vscode-extension/src/utils/metrics.ts
new file mode 100644
index 0000000..f497aa5
--- /dev/null
+++ b/vscode-extension/src/utils/metrics.ts
@@ -0,0 +1,412 @@
+/**
+ * Performance metrics utilities for GoSQLX extension.
+ * Tracks LSP operation performance and provides insights.
+ */
+
+import * as vscode from 'vscode';
+
+/**
+ * Operation types tracked by the metrics system.
+ */
+export type OperationType =
+ | 'lsp.startup'
+ | 'lsp.shutdown'
+ | 'lsp.validate'
+ | 'lsp.format'
+ | 'lsp.analyze'
+ | 'lsp.hover'
+ | 'lsp.completion'
+ | 'lsp.diagnostics'
+ | 'command.validate'
+ | 'command.format'
+ | 'command.analyze'
+ | 'executable.check';
+
+/**
+ * A single performance measurement.
+ */
+export interface PerformanceMeasurement {
+ operation: OperationType;
+ duration: number;
+ timestamp: number;
+ success: boolean;
+ metadata?: Record;
+}
+
+/**
+ * Aggregated statistics for an operation type.
+ */
+export interface OperationStats {
+ count: number;
+ successCount: number;
+ failureCount: number;
+ totalDuration: number;
+ minDuration: number;
+ maxDuration: number;
+ avgDuration: number;
+ p95Duration: number;
+ lastDuration: number;
+ lastTimestamp: number;
+}
+
+/**
+ * Performance timer for measuring operation durations.
+ */
+export class PerformanceTimer {
+ private startTime: number = 0;
+ private running: boolean = false;
+
+ /**
+ * Starts the timer.
+ */
+ public start(): void {
+ this.startTime = Date.now();
+ this.running = true;
+ }
+
+ /**
+ * Stops the timer and returns the elapsed duration in milliseconds.
+ */
+ public stop(): number {
+ if (!this.running) {
+ return 0;
+ }
+ this.running = false;
+ return Date.now() - this.startTime;
+ }
+
+ /**
+ * Gets the current elapsed time without stopping the timer.
+ */
+ public elapsed(): number {
+ if (!this.running) {
+ return 0;
+ }
+ return Date.now() - this.startTime;
+ }
+
+ /**
+ * Checks if the timer is running.
+ */
+ public isRunning(): boolean {
+ return this.running;
+ }
+
+ /**
+ * Resets the timer.
+ */
+ public reset(): void {
+ this.startTime = 0;
+ this.running = false;
+ }
+}
+
+/**
+ * Collects and manages performance metrics.
+ */
+export class MetricsCollector {
+ private static instance: MetricsCollector | undefined;
+ private measurements: Map = new Map();
+ private maxMeasurements: number = 1000; // Per operation type
+ private enabled: boolean = true;
+
+ private constructor() { }
+
+ /**
+ * Gets the singleton instance.
+ */
+ public static getInstance(): MetricsCollector {
+ if (!MetricsCollector.instance) {
+ MetricsCollector.instance = new MetricsCollector();
+ }
+ return MetricsCollector.instance;
+ }
+
+ /**
+ * Enables metrics collection.
+ */
+ public enable(): void {
+ this.enabled = true;
+ }
+
+ /**
+ * Disables metrics collection and clears data.
+ */
+ public disable(): void {
+ this.enabled = false;
+ this.measurements.clear();
+ }
+
+ /**
+ * Records a performance measurement.
+ */
+ public record(
+ operation: OperationType,
+ duration: number,
+ success: boolean = true,
+ metadata?: Record
+ ): void {
+ if (!this.enabled) {
+ return;
+ }
+
+ const measurement: PerformanceMeasurement = {
+ operation,
+ duration,
+ timestamp: Date.now(),
+ success,
+ metadata
+ };
+
+ if (!this.measurements.has(operation)) {
+ this.measurements.set(operation, []);
+ }
+
+ const measurements = this.measurements.get(operation)!;
+ measurements.push(measurement);
+
+ // Limit stored measurements
+ while (measurements.length > this.maxMeasurements) {
+ measurements.shift();
+ }
+ }
+
+ /**
+ * Records a duration measurement with a timer.
+ */
+ public recordWithTimer(
+ operation: OperationType,
+ fn: () => T,
+ metadata?: Record
+ ): T {
+ const timer = new PerformanceTimer();
+ timer.start();
+
+ try {
+ const result = fn();
+ this.record(operation, timer.stop(), true, metadata);
+ return result;
+ } catch (error) {
+ this.record(operation, timer.stop(), false, metadata);
+ throw error;
+ }
+ }
+
+ /**
+ * Records an async duration measurement with a timer.
+ */
+ public async recordWithTimerAsync(
+ operation: OperationType,
+ fn: () => Promise,
+ metadata?: Record
+ ): Promise {
+ const timer = new PerformanceTimer();
+ timer.start();
+
+ try {
+ const result = await fn();
+ this.record(operation, timer.stop(), true, metadata);
+ return result;
+ } catch (error) {
+ this.record(operation, timer.stop(), false, metadata);
+ throw error;
+ }
+ }
+
+ /**
+ * Gets statistics for an operation type.
+ */
+ public getStats(operation: OperationType): OperationStats | undefined {
+ const measurements = this.measurements.get(operation);
+ if (!measurements || measurements.length === 0) {
+ return undefined;
+ }
+
+ const durations = measurements.map(m => m.duration);
+ const sortedDurations = [...durations].sort((a, b) => a - b);
+
+ const successCount = measurements.filter(m => m.success).length;
+ const totalDuration = durations.reduce((a, b) => a + b, 0);
+ const p95Index = Math.floor(sortedDurations.length * 0.95);
+
+ return {
+ count: measurements.length,
+ successCount,
+ failureCount: measurements.length - successCount,
+ totalDuration,
+ minDuration: sortedDurations[0],
+ maxDuration: sortedDurations[sortedDurations.length - 1],
+ avgDuration: totalDuration / measurements.length,
+ p95Duration: sortedDurations[p95Index] ?? sortedDurations[sortedDurations.length - 1],
+ lastDuration: durations[durations.length - 1],
+ lastTimestamp: measurements[measurements.length - 1].timestamp
+ };
+ }
+
+ /**
+ * Gets statistics for all operation types.
+ */
+ public getAllStats(): Map {
+ const stats = new Map();
+
+ for (const operation of this.measurements.keys()) {
+ const opStats = this.getStats(operation);
+ if (opStats) {
+ stats.set(operation, opStats);
+ }
+ }
+
+ return stats;
+ }
+
+ /**
+ * Gets a summary of all metrics.
+ */
+ public getSummary(): string {
+ const stats = this.getAllStats();
+ const lines: string[] = ['=== GoSQLX Performance Metrics ===', ''];
+
+ if (stats.size === 0) {
+ lines.push('No metrics collected yet.');
+ return lines.join('\n');
+ }
+
+ for (const [operation, opStats] of stats) {
+ lines.push(`${operation}:`);
+ lines.push(` Count: ${opStats.count} (${opStats.successCount} success, ${opStats.failureCount} failed)`);
+ lines.push(` Duration: avg=${opStats.avgDuration.toFixed(1)}ms, min=${opStats.minDuration}ms, max=${opStats.maxDuration}ms, p95=${opStats.p95Duration.toFixed(1)}ms`);
+ lines.push('');
+ }
+
+ return lines.join('\n');
+ }
+
+ /**
+ * Gets recent measurements for an operation.
+ */
+ public getRecentMeasurements(operation: OperationType, count: number = 10): PerformanceMeasurement[] {
+ const measurements = this.measurements.get(operation);
+ if (!measurements) {
+ return [];
+ }
+ return measurements.slice(-count);
+ }
+
+ /**
+ * Gets the success rate for an operation.
+ */
+ public getSuccessRate(operation: OperationType): number | undefined {
+ const stats = this.getStats(operation);
+ if (!stats || stats.count === 0) {
+ return undefined;
+ }
+ return stats.successCount / stats.count;
+ }
+
+ /**
+ * Checks if an operation is performing slowly.
+ */
+ public isSlowOperation(operation: OperationType, thresholdMs: number = 1000): boolean {
+ const stats = this.getStats(operation);
+ if (!stats) {
+ return false;
+ }
+ return stats.avgDuration > thresholdMs;
+ }
+
+ /**
+ * Clears all collected metrics.
+ */
+ public clear(): void {
+ this.measurements.clear();
+ }
+
+ /**
+ * Clears metrics for a specific operation.
+ */
+ public clearOperation(operation: OperationType): void {
+ this.measurements.delete(operation);
+ }
+
+ /**
+ * Disposes the metrics collector.
+ */
+ public dispose(): void {
+ this.measurements.clear();
+ MetricsCollector.instance = undefined;
+ }
+}
+
+/**
+ * Shows performance metrics in a new document.
+ */
+export async function showMetricsReport(): Promise {
+ const collector = MetricsCollector.getInstance();
+ const summary = collector.getSummary();
+
+ const document = await vscode.workspace.openTextDocument({
+ content: summary,
+ language: 'markdown'
+ });
+
+ await vscode.window.showTextDocument(document, { preview: true });
+}
+
+/**
+ * Creates a status bar item for performance monitoring.
+ */
+export function createPerformanceStatusBarItem(): vscode.StatusBarItem {
+ const item = vscode.window.createStatusBarItem(
+ vscode.StatusBarAlignment.Right,
+ 50
+ );
+ item.name = 'GoSQLX Performance';
+ item.command = 'gosqlx.showMetrics';
+ return item;
+}
+
+/**
+ * Updates the performance status bar item.
+ */
+export function updatePerformanceStatusBar(
+ item: vscode.StatusBarItem,
+ collector: MetricsCollector
+): void {
+ const lspStats = collector.getStats('lsp.diagnostics');
+ const validateStats = collector.getStats('command.validate');
+
+ if (!lspStats && !validateStats) {
+ item.hide();
+ return;
+ }
+
+ const avgLatency = lspStats?.avgDuration ?? validateStats?.avgDuration ?? 0;
+ const successRate = lspStats
+ ? collector.getSuccessRate('lsp.diagnostics') ?? 1
+ : collector.getSuccessRate('command.validate') ?? 1;
+
+ // Choose icon based on performance
+ let icon: string;
+ let status: string;
+
+ if (successRate < 0.8) {
+ icon = '$(warning)';
+ status = 'Issues detected';
+ } else if (avgLatency > 500) {
+ icon = '$(clock)';
+ status = 'Slow';
+ } else if (avgLatency > 100) {
+ icon = '$(pulse)';
+ status = 'Normal';
+ } else {
+ icon = '$(zap)';
+ status = 'Fast';
+ }
+
+ item.text = `${icon} ${avgLatency.toFixed(0)}ms`;
+ item.tooltip = `GoSQLX Performance: ${status}\n` +
+ `Avg latency: ${avgLatency.toFixed(1)}ms\n` +
+ `Success rate: ${(successRate * 100).toFixed(1)}%\n` +
+ `Click to see detailed metrics`;
+ item.show();
+}
diff --git a/vscode-extension/src/utils/telemetry.ts b/vscode-extension/src/utils/telemetry.ts
new file mode 100644
index 0000000..fc8472a
--- /dev/null
+++ b/vscode-extension/src/utils/telemetry.ts
@@ -0,0 +1,368 @@
+/**
+ * Telemetry utilities for GoSQLX extension.
+ * All telemetry is opt-in and respects user privacy.
+ * No SQL content or file paths are ever collected.
+ */
+
+import * as vscode from 'vscode';
+import * as os from 'os';
+import { extractFileExtension } from './validation';
+
+/**
+ * Telemetry event types.
+ */
+export type TelemetryEventType =
+ | 'extension.activated'
+ | 'extension.deactivated'
+ | 'command.validate'
+ | 'command.format'
+ | 'command.analyze'
+ | 'command.restartServer'
+ | 'lsp.started'
+ | 'lsp.stopped'
+ | 'lsp.error'
+ | 'lsp.retry'
+ | 'config.changed'
+ | 'error.occurred';
+
+/**
+ * Telemetry event data (sanitized).
+ */
+export interface TelemetryEvent {
+ type: TelemetryEventType;
+ timestamp: number;
+ sessionId: string;
+ properties?: Record;
+}
+
+/**
+ * Sanitized telemetry data - never contains sensitive information.
+ */
+export interface SanitizedTelemetryData {
+ // Extension info
+ extensionVersion: string;
+ vscodeVersion: string;
+
+ // Platform info (generic, non-identifying)
+ platform: string;
+ platformVersion: string;
+ arch: string;
+
+ // Configuration (non-sensitive)
+ dialect?: string;
+ indentSize?: number;
+ uppercaseKeywords?: boolean;
+
+ // Usage metrics (aggregated)
+ fileExtension?: string;
+ operationDuration?: number;
+ success?: boolean;
+ errorCode?: string;
+}
+
+/**
+ * Manages telemetry collection with user consent.
+ */
+export class TelemetryManager {
+ private static instance: TelemetryManager | undefined;
+ private enabled: boolean = false;
+ private sessionId: string;
+ private events: TelemetryEvent[] = [];
+ private extensionVersion: string;
+ private maxEvents: number = 100; // Buffer limit
+
+ private constructor(extensionVersion: string) {
+ this.extensionVersion = extensionVersion;
+ this.sessionId = this.generateSessionId();
+ this.loadEnabledState();
+ }
+
+ /**
+ * Gets the singleton instance.
+ */
+ public static getInstance(extensionVersion: string = '0.0.0'): TelemetryManager {
+ if (!TelemetryManager.instance) {
+ TelemetryManager.instance = new TelemetryManager(extensionVersion);
+ }
+ return TelemetryManager.instance;
+ }
+
+ /**
+ * Checks if telemetry is enabled.
+ */
+ public isEnabled(): boolean {
+ return this.enabled && this.isVscodeTelemetryEnabled();
+ }
+
+ /**
+ * Enables telemetry collection.
+ */
+ public enable(): void {
+ this.enabled = true;
+ this.saveEnabledState();
+ }
+
+ /**
+ * Disables telemetry collection and clears buffered events.
+ */
+ public disable(): void {
+ this.enabled = false;
+ this.events = [];
+ this.saveEnabledState();
+ }
+
+ /**
+ * Records a telemetry event if telemetry is enabled.
+ */
+ public recordEvent(
+ type: TelemetryEventType,
+ properties?: Record
+ ): void {
+ if (!this.isEnabled()) {
+ return;
+ }
+
+ const event: TelemetryEvent = {
+ type,
+ timestamp: Date.now(),
+ sessionId: this.sessionId,
+ properties: properties ? this.sanitizeProperties(properties) : undefined
+ };
+
+ this.events.push(event);
+
+ // Limit buffer size
+ if (this.events.length > this.maxEvents) {
+ this.events.shift();
+ }
+ }
+
+ /**
+ * Records a command execution.
+ */
+ public recordCommand(
+ command: string,
+ duration: number,
+ success: boolean,
+ errorCode?: string
+ ): void {
+ this.recordEvent(`command.${command}` as TelemetryEventType, {
+ duration,
+ success,
+ ...(errorCode && { errorCode })
+ });
+ }
+
+ /**
+ * Records an LSP operation.
+ */
+ public recordLspOperation(
+ operation: 'started' | 'stopped' | 'error' | 'retry',
+ details?: Record
+ ): void {
+ this.recordEvent(`lsp.${operation}` as TelemetryEventType, details);
+ }
+
+ /**
+ * Records an error occurrence.
+ */
+ public recordError(errorCode: string, component: string): void {
+ this.recordEvent('error.occurred', {
+ errorCode,
+ component
+ });
+ }
+
+ /**
+ * Gets sanitized environment data for telemetry.
+ */
+ public getSanitizedEnvironment(): SanitizedTelemetryData {
+ return {
+ extensionVersion: this.extensionVersion,
+ vscodeVersion: vscode.version,
+ platform: os.platform(),
+ platformVersion: os.release(),
+ arch: os.arch()
+ };
+ }
+
+ /**
+ * Sanitizes file path to only extract extension.
+ * Never includes the actual path.
+ */
+ public sanitizeFilePath(filePath: string): { fileExtension: string } {
+ return {
+ fileExtension: extractFileExtension(filePath) || 'unknown'
+ };
+ }
+
+ /**
+ * Gets buffered events for potential submission.
+ * Events are cleared after retrieval.
+ */
+ public getAndClearEvents(): TelemetryEvent[] {
+ if (!this.isEnabled()) {
+ return [];
+ }
+ const events = [...this.events];
+ this.events = [];
+ return events;
+ }
+
+ /**
+ * Gets aggregated statistics (for potential future use).
+ */
+ public getStats(): {
+ totalEvents: number;
+ eventsByType: Record;
+ } {
+ const eventsByType: Record = {};
+
+ for (const event of this.events) {
+ eventsByType[event.type] = (eventsByType[event.type] || 0) + 1;
+ }
+
+ return {
+ totalEvents: this.events.length,
+ eventsByType
+ };
+ }
+
+ /**
+ * Disposes the telemetry manager.
+ */
+ public dispose(): void {
+ this.events = [];
+ TelemetryManager.instance = undefined;
+ }
+
+ /**
+ * Generates a random session ID (not tied to user identity).
+ */
+ private generateSessionId(): string {
+ const chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
+ let result = '';
+ for (let i = 0; i < 16; i++) {
+ result += chars.charAt(Math.floor(Math.random() * chars.length));
+ }
+ return result;
+ }
+
+ /**
+ * Checks if VS Code's global telemetry setting is enabled.
+ */
+ private isVscodeTelemetryEnabled(): boolean {
+ const telemetryConfig = vscode.workspace.getConfiguration('telemetry');
+ const level = telemetryConfig.get('telemetryLevel', 'all');
+ return level !== 'off';
+ }
+
+ /**
+ * Loads the enabled state from configuration.
+ */
+ private loadEnabledState(): void {
+ const config = vscode.workspace.getConfiguration('gosqlx');
+ this.enabled = config.get('telemetry.enable', false);
+ }
+
+ /**
+ * Saves the enabled state to configuration.
+ */
+ private saveEnabledState(): void {
+ const config = vscode.workspace.getConfiguration('gosqlx');
+ config.update('telemetry.enable', this.enabled, vscode.ConfigurationTarget.Global);
+ }
+
+ /**
+ * Sanitizes properties to ensure no sensitive data is included.
+ */
+ private sanitizeProperties(
+ properties: Record
+ ): Record {
+ const sanitized: Record = {};
+
+ // Whitelist of allowed property names
+ const allowedKeys = new Set([
+ 'duration',
+ 'success',
+ 'errorCode',
+ 'dialect',
+ 'indentSize',
+ 'uppercaseKeywords',
+ 'fileExtension',
+ 'attempt',
+ 'maxAttempts',
+ 'retryDelay'
+ ]);
+
+ for (const [key, value] of Object.entries(properties)) {
+ if (allowedKeys.has(key)) {
+ // Ensure values are not too long (potential PII)
+ if (typeof value === 'string' && value.length > 50) {
+ sanitized[key] = value.substring(0, 50);
+ } else {
+ sanitized[key] = value;
+ }
+ }
+ }
+
+ return sanitized;
+ }
+}
+
+/**
+ * Prompts user to opt-in to telemetry.
+ */
+export async function promptTelemetryOptIn(): Promise {
+ const message = 'Would you like to help improve GoSQLX by sharing anonymous usage data? ' +
+ 'No SQL content or file paths are ever collected.';
+
+ const learnMore = 'Learn More';
+ const yes = 'Yes, help improve';
+ const no = 'No thanks';
+
+ const choice = await vscode.window.showInformationMessage(
+ message,
+ learnMore,
+ yes,
+ no
+ );
+
+ if (choice === learnMore) {
+ vscode.env.openExternal(
+ vscode.Uri.parse('https://github.com/ajitpratap0/GoSQLX/blob/main/PRIVACY.md')
+ );
+ // Re-prompt after they've had a chance to read
+ return promptTelemetryOptIn();
+ }
+
+ return choice === yes;
+}
+
+/**
+ * Creates a telemetry event wrapper that measures duration.
+ */
+export function withTelemetry(
+ telemetry: TelemetryManager,
+ eventType: TelemetryEventType,
+ operation: () => Promise
+): Promise {
+ const startTime = Date.now();
+
+ return operation()
+ .then((result) => {
+ telemetry.recordEvent(eventType, {
+ duration: Date.now() - startTime,
+ success: true
+ });
+ return result;
+ })
+ .catch((error) => {
+ telemetry.recordEvent(eventType, {
+ duration: Date.now() - startTime,
+ success: false,
+ errorCode: error?.code || 'UNKNOWN'
+ });
+ throw error;
+ });
+}
diff --git a/vscode-extension/src/utils/validation.ts b/vscode-extension/src/utils/validation.ts
new file mode 100644
index 0000000..43970dd
--- /dev/null
+++ b/vscode-extension/src/utils/validation.ts
@@ -0,0 +1,342 @@
+/**
+ * Configuration validation utilities for GoSQLX extension.
+ * Provides validation functions and helpful error messages for all settings.
+ */
+
+export interface ValidationResult {
+ valid: boolean;
+ message?: string;
+ suggestion?: string;
+}
+
+export const VALID_DIALECTS = ['generic', 'postgresql', 'mysql', 'sqlserver', 'oracle', 'sqlite'] as const;
+export type SqlDialect = typeof VALID_DIALECTS[number];
+
+export const SQL_LANGUAGE_IDS = ['sql', 'pgsql', 'mysql', 'plpgsql', 'tsql', 'plsql', 'gosqlx'] as const;
+export const SQL_FILE_EXTENSIONS = ['.sql', '.pgsql', '.psql', '.mysql', '.tsql', '.plsql'] as const;
+
+/**
+ * Validates the indent size configuration value.
+ */
+export function validateIndentSize(value: unknown): ValidationResult {
+ if (typeof value !== 'number' || isNaN(value)) {
+ return {
+ valid: false,
+ message: 'Indent size must be a number',
+ suggestion: 'Set gosqlx.format.indentSize to 2 or 4'
+ };
+ }
+
+ if (value < 1 || value > 16) {
+ return {
+ valid: false,
+ message: `Indent size ${value} is out of range (1-16)`,
+ suggestion: 'Common values are 2 or 4 spaces'
+ };
+ }
+
+ if (!Number.isInteger(value)) {
+ return {
+ valid: false,
+ message: 'Indent size must be a whole number',
+ suggestion: `Use ${Math.round(value)} instead`
+ };
+ }
+
+ return { valid: true };
+}
+
+/**
+ * Validates the SQL dialect configuration value.
+ */
+export function validateDialect(dialect: unknown): ValidationResult {
+ if (typeof dialect !== 'string') {
+ return {
+ valid: false,
+ message: 'Dialect must be a string',
+ suggestion: `Valid dialects: ${VALID_DIALECTS.join(', ')}`
+ };
+ }
+
+ const normalized = dialect.toLowerCase().trim();
+
+ if (!VALID_DIALECTS.includes(normalized as SqlDialect)) {
+ // Try to suggest the closest match
+ const suggestions = findClosestDialect(normalized);
+ return {
+ valid: false,
+ message: `Unknown SQL dialect: "${dialect}"`,
+ suggestion: suggestions
+ ? `Did you mean "${suggestions}"? Valid dialects: ${VALID_DIALECTS.join(', ')}`
+ : `Valid dialects: ${VALID_DIALECTS.join(', ')}`
+ };
+ }
+
+ return { valid: true };
+}
+
+/**
+ * Validates the executable path configuration value.
+ */
+export function validateExecutablePath(execPath: unknown): ValidationResult {
+ if (typeof execPath !== 'string') {
+ return {
+ valid: false,
+ message: 'Executable path must be a string',
+ suggestion: 'Set to "gosqlx" or provide full path like "/usr/local/bin/gosqlx"'
+ };
+ }
+
+ const trimmed = execPath.trim();
+
+ if (trimmed.length === 0) {
+ return {
+ valid: false,
+ message: 'Executable path cannot be empty',
+ suggestion: 'Set to "gosqlx" to use PATH lookup, or provide full path'
+ };
+ }
+
+ // Check for suspicious characters that might indicate a typo
+ if (trimmed.includes(' ') || trimmed.includes('\n') || trimmed.includes('\t')) {
+ return {
+ valid: false,
+ message: 'Executable path contains invalid whitespace',
+ suggestion: 'Remove extra spaces or newlines from the path'
+ };
+ }
+
+ return { valid: true };
+}
+
+/**
+ * Validates timeout configuration values.
+ */
+export function validateTimeout(timeout: unknown, settingName: string = 'timeout'): ValidationResult {
+ if (typeof timeout !== 'number' || isNaN(timeout)) {
+ return {
+ valid: false,
+ message: `${settingName} must be a number`,
+ suggestion: 'Specify timeout in milliseconds (e.g., 30000 for 30 seconds)'
+ };
+ }
+
+ if (timeout <= 0) {
+ return {
+ valid: false,
+ message: `${settingName} must be positive`,
+ suggestion: 'Use at least 1000ms (1 second)'
+ };
+ }
+
+ if (timeout > 300000) { // 5 minutes
+ return {
+ valid: false,
+ message: `${settingName} of ${timeout}ms exceeds maximum (300000ms)`,
+ suggestion: 'Maximum allowed timeout is 5 minutes (300000ms)'
+ };
+ }
+
+ if (timeout < 1000) {
+ return {
+ valid: true,
+ message: `Warning: ${settingName} of ${timeout}ms may be too short`,
+ suggestion: 'Consider using at least 5000ms for reliable operation'
+ };
+ }
+
+ return { valid: true };
+}
+
+/**
+ * Validates trace level configuration.
+ */
+export function validateTraceLevel(level: unknown): ValidationResult {
+ const validLevels = ['off', 'messages', 'verbose'];
+
+ if (typeof level !== 'string') {
+ return {
+ valid: false,
+ message: 'Trace level must be a string',
+ suggestion: `Valid levels: ${validLevels.join(', ')}`
+ };
+ }
+
+ if (!validLevels.includes(level.toLowerCase())) {
+ return {
+ valid: false,
+ message: `Unknown trace level: "${level}"`,
+ suggestion: `Valid levels: ${validLevels.join(', ')}`
+ };
+ }
+
+ return { valid: true };
+}
+
+/**
+ * Validates the complete gosqlx configuration object.
+ */
+export function validateConfiguration(config: Record): ValidationResult[] {
+ const results: ValidationResult[] = [];
+
+ if (config.enable !== undefined && typeof config.enable !== 'boolean') {
+ results.push({
+ valid: false,
+ message: 'gosqlx.enable must be a boolean',
+ suggestion: 'Set to true or false'
+ });
+ }
+
+ if (config.executablePath !== undefined) {
+ const execResult = validateExecutablePath(config.executablePath);
+ if (!execResult.valid) {
+ results.push(execResult);
+ }
+ }
+
+ if (config.dialect !== undefined) {
+ const dialectResult = validateDialect(config.dialect);
+ if (!dialectResult.valid) {
+ results.push(dialectResult);
+ }
+ }
+
+ // Validate format options
+ const format = config.format as Record | undefined;
+ if (format) {
+ if (format.indentSize !== undefined) {
+ const indentResult = validateIndentSize(format.indentSize);
+ if (!indentResult.valid) {
+ results.push(indentResult);
+ }
+ }
+
+ if (format.uppercaseKeywords !== undefined && typeof format.uppercaseKeywords !== 'boolean') {
+ results.push({
+ valid: false,
+ message: 'gosqlx.format.uppercaseKeywords must be a boolean',
+ suggestion: 'Set to true or false'
+ });
+ }
+ }
+
+ // Validate timeouts
+ const timeouts = config.timeouts as Record | undefined;
+ if (timeouts) {
+ if (timeouts.validation !== undefined) {
+ const result = validateTimeout(timeouts.validation, 'validation timeout');
+ if (!result.valid) {
+ results.push(result);
+ }
+ }
+ if (timeouts.analysis !== undefined) {
+ const result = validateTimeout(timeouts.analysis, 'analysis timeout');
+ if (!result.valid) {
+ results.push(result);
+ }
+ }
+ if (timeouts.startup !== undefined) {
+ const result = validateTimeout(timeouts.startup, 'startup timeout');
+ if (!result.valid) {
+ results.push(result);
+ }
+ }
+ }
+
+ if (config['trace.server'] !== undefined) {
+ const traceResult = validateTraceLevel(config['trace.server']);
+ if (!traceResult.valid) {
+ results.push(traceResult);
+ }
+ }
+
+ return results;
+}
+
+/**
+ * Checks if a language ID represents SQL.
+ */
+export function isSqlLanguageId(languageId: string): boolean {
+ return SQL_LANGUAGE_IDS.includes(languageId.toLowerCase() as typeof SQL_LANGUAGE_IDS[number]);
+}
+
+/**
+ * Gets all supported SQL file extensions.
+ */
+export function getSqlFileExtensions(): readonly string[] {
+ return SQL_FILE_EXTENSIONS;
+}
+
+/**
+ * Extracts file extension from a path.
+ */
+export function extractFileExtension(filePath: string): string {
+ const lastDot = filePath.lastIndexOf('.');
+ const lastSep = Math.max(filePath.lastIndexOf('/'), filePath.lastIndexOf('\\'));
+
+ if (lastDot === -1 || lastDot < lastSep || lastDot === filePath.length - 1) {
+ return '';
+ }
+
+ return filePath.substring(lastDot).toLowerCase();
+}
+
+/**
+ * Checks if a path is absolute.
+ */
+export function isAbsolutePath(filePath: string): boolean {
+ // Unix absolute paths
+ if (filePath.startsWith('/')) {
+ return true;
+ }
+ // Windows absolute paths (C:\, D:\, etc.)
+ if (/^[a-zA-Z]:[\\/]/.test(filePath)) {
+ return true;
+ }
+ // UNC paths (\\server\share)
+ if (filePath.startsWith('\\\\')) {
+ return true;
+ }
+ return false;
+}
+
+/**
+ * Normalizes an executable path for the current platform.
+ */
+export function normalizeExecutablePath(execPath: string): string {
+ return execPath.trim();
+}
+
+/**
+ * Finds the closest matching dialect for typo correction.
+ */
+function findClosestDialect(input: string): string | undefined {
+ const lowercaseInput = input.toLowerCase();
+
+ // Common aliases and typos
+ const aliases: { [key: string]: SqlDialect } = {
+ 'postgres': 'postgresql',
+ 'pg': 'postgresql',
+ 'pgsql': 'postgresql',
+ 'mariadb': 'mysql',
+ 'mssql': 'sqlserver',
+ 'sql server': 'sqlserver',
+ 'microsoftsql': 'sqlserver',
+ 'ora': 'oracle',
+ 'sqlite3': 'sqlite',
+ 'lite': 'sqlite'
+ };
+
+ if (aliases[lowercaseInput]) {
+ return aliases[lowercaseInput];
+ }
+
+ // Simple Levenshtein-like matching for close typos
+ for (const dialect of VALID_DIALECTS) {
+ if (dialect.startsWith(lowercaseInput) || lowercaseInput.startsWith(dialect)) {
+ return dialect;
+ }
+ }
+
+ return undefined;
+}
diff --git a/vscode-extension/syntaxes/sql.tmLanguage.json b/vscode-extension/syntaxes/sql.tmLanguage.json
new file mode 100644
index 0000000..d0bb00a
--- /dev/null
+++ b/vscode-extension/syntaxes/sql.tmLanguage.json
@@ -0,0 +1,368 @@
+{
+ "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json",
+ "name": "SQL",
+ "scopeName": "source.sql",
+ "patterns": [
+ { "include": "#comments" },
+ { "include": "#strings" },
+ { "include": "#numbers" },
+ { "include": "#operators" },
+ { "include": "#keywords" },
+ { "include": "#functions" },
+ { "include": "#types" },
+ { "include": "#identifiers" }
+ ],
+ "repository": {
+ "comments": {
+ "patterns": [
+ {
+ "name": "comment.line.double-dash.sql",
+ "match": "--.*$"
+ },
+ {
+ "name": "comment.line.hash.sql",
+ "comment": "MySQL-style hash comments",
+ "match": "#.*$"
+ },
+ {
+ "name": "comment.block.sql",
+ "begin": "/\\*",
+ "end": "\\*/",
+ "patterns": [
+ { "include": "#comments" }
+ ]
+ }
+ ]
+ },
+ "strings": {
+ "patterns": [
+ {
+ "name": "string.quoted.single.sql",
+ "begin": "'",
+ "end": "'",
+ "patterns": [
+ {
+ "name": "constant.character.escape.sql",
+ "match": "''"
+ },
+ {
+ "name": "constant.character.escape.sql",
+ "match": "\\\\."
+ }
+ ]
+ },
+ {
+ "name": "string.quoted.double.sql",
+ "begin": "\"",
+ "end": "\"",
+ "patterns": [
+ {
+ "name": "constant.character.escape.sql",
+ "match": "\\\\\""
+ }
+ ]
+ },
+ {
+ "name": "string.quoted.dollar.sql",
+ "comment": "PostgreSQL dollar-quoted strings",
+ "begin": "(\\$[a-zA-Z_]*\\$)",
+ "end": "(\\1)",
+ "beginCaptures": {
+ "1": { "name": "punctuation.definition.string.begin.sql" }
+ },
+ "endCaptures": {
+ "1": { "name": "punctuation.definition.string.end.sql" }
+ }
+ },
+ {
+ "name": "string.quoted.backtick.sql",
+ "comment": "MySQL backtick-quoted identifiers",
+ "begin": "`",
+ "end": "`"
+ },
+ {
+ "name": "string.quoted.bracket.sql",
+ "comment": "SQL Server bracket-quoted identifiers",
+ "begin": "\\[",
+ "end": "\\]"
+ },
+ {
+ "name": "string.quoted.national.sql",
+ "comment": "National character string literal (N'...')",
+ "begin": "[nN]'",
+ "end": "'",
+ "patterns": [
+ {
+ "name": "constant.character.escape.sql",
+ "match": "''"
+ }
+ ]
+ }
+ ]
+ },
+ "numbers": {
+ "patterns": [
+ {
+ "name": "constant.numeric.float.sql",
+ "match": "\\b\\d+\\.\\d+([eE][+-]?\\d+)?\\b"
+ },
+ {
+ "name": "constant.numeric.integer.sql",
+ "match": "\\b\\d+\\b"
+ },
+ {
+ "name": "constant.numeric.hex.sql",
+ "match": "\\b0[xX][0-9a-fA-F]+\\b"
+ },
+ {
+ "name": "constant.numeric.binary.sql",
+ "comment": "Binary literals (MySQL, PostgreSQL)",
+ "match": "\\b0[bB][01]+\\b"
+ },
+ {
+ "name": "constant.numeric.bit.sql",
+ "comment": "Bit string literal (PostgreSQL)",
+ "match": "[bB]'[01]+'"
+ }
+ ]
+ },
+ "operators": {
+ "patterns": [
+ {
+ "name": "keyword.operator.comparison.sql",
+ "match": "<=|>=|<>|!=|!<|!>|<|>|="
+ },
+ {
+ "name": "keyword.operator.arithmetic.sql",
+ "match": "\\+|-|\\*|/|%|\\^"
+ },
+ {
+ "name": "keyword.operator.concatenation.sql",
+ "match": "\\|\\|"
+ },
+ {
+ "name": "keyword.operator.json.sql",
+ "comment": "PostgreSQL JSON operators",
+ "match": "->|->>|#>|#>>|@>|<@|\\?|\\?\\||\\?&|@\\?|@@"
+ },
+ {
+ "name": "keyword.operator.array.sql",
+ "comment": "PostgreSQL array operators",
+ "match": "&&|@>|<@|\\|\\|"
+ },
+ {
+ "name": "keyword.operator.assignment.sql",
+ "match": ":=|::="
+ },
+ {
+ "name": "keyword.operator.cast.sql",
+ "comment": "PostgreSQL cast operator",
+ "match": "::"
+ },
+ {
+ "name": "keyword.operator.range.sql",
+ "comment": "PostgreSQL range operators",
+ "match": "-\\|-|&&|<<|>>|&<|&>|@>|<@|-|-"
+ },
+ {
+ "name": "keyword.operator.bitwise.sql",
+ "match": "&|\\||~|\\^|<<|>>"
+ },
+ {
+ "name": "keyword.operator.regex.sql",
+ "comment": "PostgreSQL regex operators",
+ "match": "~|~\\*|!~|!~\\*"
+ }
+ ]
+ },
+ "keywords": {
+ "patterns": [
+ {
+ "name": "keyword.control.sql",
+ "match": "(?i)\\b(SELECT|FROM|WHERE|AND|OR|NOT|IN|EXISTS|BETWEEN|LIKE|ILIKE|RLIKE|REGEXP|IS|NULL|TRUE|FALSE|CASE|WHEN|THEN|ELSE|END|IF|ELSEIF|LOOP|WHILE|FOR|FOREACH|RETURN|RETURNS|EXIT|CONTINUE|GOTO|BREAK|THROW)\\b"
+ },
+ {
+ "name": "keyword.other.DML.sql",
+ "match": "(?i)\\b(INSERT|INTO|VALUES|UPDATE|SET|DELETE|MERGE|USING|MATCHED|TRUNCATE|REPLACE|UPSERT|ON|DUPLICATE|KEY|CONFLICT|DO|NOTHING|EXCLUDED|OVERRIDING|SYSTEM|VALUE)\\b"
+ },
+ {
+ "name": "keyword.other.DDL.sql",
+ "match": "(?i)\\b(CREATE|ALTER|DROP|TABLE|VIEW|INDEX|SEQUENCE|SCHEMA|DATABASE|TRIGGER|PROCEDURE|FUNCTION|TYPE|DOMAIN|CONSTRAINT|PRIMARY|FOREIGN|KEY|REFERENCES|UNIQUE|CHECK|DEFAULT|CASCADE|RESTRICT|TEMPORARY|TEMP|UNLOGGED|MATERIALIZED|REFRESH|CONCURRENTLY|RENAME|ADD|MODIFY|COLUMN|TABLESPACE|STORAGE|ENGINE|CHARSET|COLLATE|AUTO_INCREMENT|IDENTITY|GENERATED|ALWAYS|STORED|VIRTUAL|INVISIBLE|VISIBLE|COMMENT|PARTITION|PARTITIONS|HASH|RANGE|LIST|SUBPARTITION)\\b"
+ },
+ {
+ "name": "keyword.other.DML.II.sql",
+ "match": "(?i)\\b(GROUP|BY|HAVING|ORDER|ASC|DESC|NULLS|FIRST|LAST|LIMIT|OFFSET|FETCH|NEXT|ROWS|ONLY|PERCENT|WITH|TIES|DISTINCT|ALL|UNION|INTERSECT|EXCEPT|MINUS|TOP|SKIP|ROW|SAMPLE|TABLESAMPLE|BERNOULLI|SYSTEM)\\b"
+ },
+ {
+ "name": "keyword.other.join.sql",
+ "match": "(?i)\\b(JOIN|INNER|LEFT|RIGHT|FULL|OUTER|CROSS|NATURAL|ON|USING|LATERAL|APPLY|STRAIGHT_JOIN)\\b"
+ },
+ {
+ "name": "keyword.other.alias.sql",
+ "match": "(?i)\\b(AS)\\b"
+ },
+ {
+ "name": "keyword.other.transaction.sql",
+ "match": "(?i)\\b(BEGIN|COMMIT|ROLLBACK|SAVEPOINT|TRANSACTION|START|WORK|ISOLATION|LEVEL|READ|WRITE|UNCOMMITTED|COMMITTED|REPEATABLE|SERIALIZABLE|SNAPSHOT|CHAIN|RELEASE|LOCK|UNLOCK|TABLES|NOWAIT|WAIT|SKIP|LOCKED)\\b"
+ },
+ {
+ "name": "keyword.other.authorization.sql",
+ "match": "(?i)\\b(GRANT|REVOKE|PRIVILEGES|TO|PUBLIC|ROLE|USER|OWNER|USAGE|EXECUTE|REFERENCES|DENY|WITH|ADMIN|OPTION|GRANTED)\\b"
+ },
+ {
+ "name": "keyword.other.CTE.sql",
+ "match": "(?i)\\b(WITH|RECURSIVE|SEARCH|CYCLE|DEPTH|BREADTH|SET)\\b"
+ },
+ {
+ "name": "keyword.other.window.sql",
+ "match": "(?i)\\b(OVER|PARTITION|WINDOW|RANGE|ROWS|GROUPS|UNBOUNDED|PRECEDING|FOLLOWING|CURRENT|ROW|EXCLUDE|NO|OTHERS|FRAME)\\b"
+ },
+ {
+ "name": "keyword.other.grouping.sql",
+ "match": "(?i)\\b(GROUPING|SETS|ROLLUP|CUBE)\\b"
+ },
+ {
+ "name": "keyword.other.postgresql.sql",
+ "comment": "PostgreSQL-specific keywords",
+ "match": "(?i)\\b(RETURNING|INHERITS|LIKE|INCLUDING|EXCLUDING|CONSTRAINTS|INDEXES|DEFAULTS|STATISTICS|STORAGE|COMMENTS|GENERATED|ALWAYS|IDENTITY|OVERRIDING|USER|VALUE|LISTEN|NOTIFY|UNLISTEN|VACUUM|ANALYZE|REINDEX|CLUSTER|DISCARD|RESET|SHOW|EXPLAIN|PREPARE|EXECUTE|DEALLOCATE|COPY|MOVE|FETCH|CLOSE|DECLARE|CURSOR|HOLD|SCROLL|NO|INSENSITIVE|ASENSITIVE|READ_ONLY|READ_WRITE|RETURNS|TABLE|PARALLEL|SAFE|UNSAFE|RESTRICTED|COST|SUPPORT|LANGUAGE|PLPGSQL|SQL|C|INTERNAL)\\b"
+ },
+ {
+ "name": "keyword.other.mysql.sql",
+ "comment": "MySQL-specific keywords",
+ "match": "(?i)\\b(ALGORITHM|UNDEFINED|MERGE|TEMPTABLE|DEFINER|INVOKER|SECURITY|SQL|CASCADED|LOCAL|DELAYED|LOW_PRIORITY|HIGH_PRIORITY|IGNORE|QUICK|STRAIGHT_JOIN|SQL_SMALL_RESULT|SQL_BIG_RESULT|SQL_BUFFER_RESULT|SQL_CACHE|SQL_NO_CACHE|SQL_CALC_FOUND_ROWS|FORCE|USE|NATURAL|DUAL|PROCEDURE|ANALYSE|OUTFILE|DUMPFILE|LOAD|DATA|INFILE|ENCLOSED|ESCAPED|OPTIONALLY|LINES|TERMINATED|STARTING|PURGE|BINARY|LOGS|MASTER|SLAVE|BINLOG|RELAY|EVENTS|HANDLER|OPEN|READ|PREV|OPTIMIZE|REPAIR|CHECKSUM|ANALYZE|CHECK|FLUSH|PRIVILEGES|STATUS|PROCESSLIST|RESET|QUERY|CACHE|PROFILES)\\b"
+ },
+ {
+ "name": "keyword.other.sqlserver.sql",
+ "comment": "SQL Server-specific keywords",
+ "match": "(?i)\\b(TOP|OUTPUT|INSERTED|DELETED|MERGE|MATCHED|WHEN|THEN|HOLDLOCK|NOLOCK|PAGLOCK|ROWLOCK|TABLOCK|TABLOCKX|UPDLOCK|XLOCK|READUNCOMMITTED|READCOMMITTED|REPEATABLEREAD|SNAPSHOT|SERIALIZABLE|READPAST|NOEXPAND|TRY|CATCH|THROW|RAISERROR|PRINT|WAITFOR|DELAY|TIME|EXECUTE|EXEC|OPENQUERY|OPENROWSET|OPENDATASOURCE|PIVOT|UNPIVOT|CROSS|APPLY|OUTER|APPLY|CONTAINS|CONTAINSTABLE|FREETEXT|FREETEXTTABLE|OPTION|RECOMPILE|MAXRECURSION|OPTIMIZE|FOR|UNKNOWN|FORCESEEK|FORCESCAN|KEEPFIXED|PLAN|ROBUST|PLAN|FAST|MAXDOP|MERGE|JOIN|LOOP|JOIN|HASH|JOIN|REMOTE|PARAMETERIZATION|SIMPLE|FORCED|KEEPIDENTITY|KEEPDEFAULTS|IGNORE_DUP_KEY|FIRE_TRIGGERS|CHECK_CONSTRAINTS)\\b"
+ },
+ {
+ "name": "keyword.other.oracle.sql",
+ "comment": "Oracle-specific keywords",
+ "match": "(?i)\\b(CONNECT|BY|PRIOR|START|WITH|NOCYCLE|SIBLINGS|ROWNUM|ROWID|SYSDATE|SYSTIMESTAMP|DUAL|LEVEL|DECODE|NVL|NVL2|LNNVL|NULLIF|COALESCE|SIGN|ABS|MOD|POWER|SQRT|CEIL|FLOOR|ROUND|TRUNC|GREATEST|LEAST|FLASHBACK|VERSIONS|BETWEEN|SCN|TIMESTAMP|AS|OF|UNDO|RETENTION|PIVOT|UNPIVOT|XML|MODEL|DIMENSION|MEASURES|RULES|AUTOMATIC|ORDER|SEQUENTIAL|ITERATE|UNTIL|NAV|SINGLE|REFERENCE|UNIQUE|IGNORE|NAV|KEEP|RETURN|UPDATED|UPSERT|ALL|DIMENSION|CV|PRESENTV|PRESENTNNV|PREVIOUS|SAMPLE|BLOCK|SEED)\\b"
+ },
+ {
+ "name": "keyword.other.sqlite.sql",
+ "comment": "SQLite-specific keywords",
+ "match": "(?i)\\b(VACUUM|ATTACH|DETACH|REINDEX|ANALYZE|GLOB|INDEXED|NOCASE|RTRIM|ABORT|FAIL|IGNORE|REPLACE|ROLLBACK|AUTOINCREMENT|WITHOUT|ROWID|VIRTUAL|USING|FTS3|FTS4|FTS5|MATCH|AGAINST|HIGHLIGHT|SNIPPET|OFFSETS|MATCHINFO|RANK|BM25)\\b"
+ },
+ {
+ "name": "constant.language.sql",
+ "match": "(?i)\\b(NULL|TRUE|FALSE|UNKNOWN|DEFAULT|CURRENT_DATE|CURRENT_TIME|CURRENT_TIMESTAMP|LOCALTIME|LOCALTIMESTAMP|CURRENT_USER|SESSION_USER|SYSTEM_USER|CURRENT_CATALOG|CURRENT_SCHEMA|CURRENT_ROLE)\\b"
+ }
+ ]
+ },
+ "functions": {
+ "patterns": [
+ {
+ "name": "support.function.aggregate.sql",
+ "match": "(?i)\\b(COUNT|SUM|AVG|MIN|MAX|ARRAY_AGG|STRING_AGG|GROUP_CONCAT|LISTAGG|JSON_AGG|JSONB_AGG|JSON_ARRAYAGG|JSON_OBJECTAGG|BOOL_AND|BOOL_OR|BIT_AND|BIT_OR|BIT_XOR|EVERY|STDDEV|STDDEV_POP|STDDEV_SAMP|VARIANCE|VAR_POP|VAR_SAMP|CORR|COVAR_POP|COVAR_SAMP|REGR_AVGX|REGR_AVGY|REGR_COUNT|REGR_INTERCEPT|REGR_R2|REGR_SLOPE|REGR_SXX|REGR_SXY|REGR_SYY|MEDIAN|PERCENTILE_CONT|PERCENTILE_DISC|MODE|APPROX_COUNT_DISTINCT|APPROX_PERCENTILE|COLLECT|XMLAGG|CHECKSUM_AGG|STDEV|STDEVP|VAR|VARP)\\b"
+ },
+ {
+ "name": "support.function.window.sql",
+ "match": "(?i)\\b(ROW_NUMBER|RANK|DENSE_RANK|NTILE|LAG|LEAD|FIRST_VALUE|LAST_VALUE|NTH_VALUE|PERCENT_RANK|CUME_DIST|RATIO_TO_REPORT)\\b"
+ },
+ {
+ "name": "support.function.string.sql",
+ "match": "(?i)\\b(CONCAT|CONCAT_WS|LENGTH|CHAR_LENGTH|CHARACTER_LENGTH|OCTET_LENGTH|BIT_LENGTH|DATALENGTH|LEN|LOWER|UPPER|INITCAP|TRIM|LTRIM|RTRIM|BTRIM|LPAD|RPAD|LEFT|RIGHT|SUBSTRING|SUBSTR|MID|POSITION|STRPOS|INSTR|LOCATE|CHARINDEX|PATINDEX|REPLACE|STUFF|TRANSLATE|REVERSE|REPEAT|REPLICATE|SPACE|SPLIT_PART|STRING_SPLIT|REGEXP_REPLACE|REGEXP_MATCH|REGEXP_MATCHES|REGEXP_SPLIT_TO_ARRAY|REGEXP_SPLIT_TO_TABLE|REGEXP_SUBSTR|REGEXP_INSTR|REGEXP_COUNT|REGEXP_LIKE|FORMAT|QUOTE_IDENT|QUOTE_LITERAL|QUOTE_NULLABLE|QUOTENAME|ASCII|CHAR|CHR|UNICODE|NCHAR|MD5|SHA|SHA1|SHA2|SHA256|SHA512|HASHBYTES|ENCODE|DECODE|BASE64_ENCODE|BASE64_DECODE|SOUNDEX|DIFFERENCE|COMPRESS|UNCOMPRESS|FIELD|FIND_IN_SET|ELT|MAKE_SET|EXPORT_SET|CONVERT|COLLATE|BINARY|CAST|TO_CHAR|TO_NCHAR|TO_CLOB|TO_NCLOB)\\b"
+ },
+ {
+ "name": "support.function.datetime.sql",
+ "match": "(?i)\\b(NOW|GETDATE|GETUTCDATE|SYSDATETIME|SYSUTCDATETIME|SYSDATETIMEOFFSET|CURRENT_DATE|CURRENT_TIME|CURRENT_TIMESTAMP|LOCALTIME|LOCALTIMESTAMP|DATE|TIME|TIMESTAMP|DATETIME|DATETIME2|DATETIMEOFFSET|SMALLDATETIME|INTERVAL|EXTRACT|DATE_PART|DATE_TRUNC|DATEPART|DATENAME|DATEDIFF|DATEDIFF_BIG|DATEADD|AGE|CLOCK_TIMESTAMP|STATEMENT_TIMESTAMP|TRANSACTION_TIMESTAMP|TIMEOFDAY|TO_CHAR|TO_DATE|TO_TIMESTAMP|TO_NUMBER|STR_TO_DATE|DATE_FORMAT|TIME_FORMAT|CONVERT|CAST|MAKE_DATE|MAKE_TIME|MAKE_TIMESTAMP|MAKE_TIMESTAMPTZ|MAKE_INTERVAL|YEAR|MONTH|DAY|HOUR|MINUTE|SECOND|MICROSECOND|DAYOFWEEK|DAYOFMONTH|DAYOFYEAR|WEEKDAY|WEEKOFYEAR|WEEK|QUARTER|YEARWEEK|LAST_DAY|MONTHNAME|DAYNAME|EOMONTH|ISDATE|SWITCHOFFSET|TODATETIMEOFFSET|AT|TIME|ZONE|FROM_TZ|SYS_EXTRACT_UTC|TZ_OFFSET|SESSIONTIMEZONE|DBTIMEZONE|NUMTODSINTERVAL|NUMTOYMINTERVAL|TO_DSINTERVAL|TO_YMINTERVAL)\\b"
+ },
+ {
+ "name": "support.function.math.sql",
+ "match": "(?i)\\b(ABS|CEIL|CEILING|FLOOR|ROUND|TRUNC|TRUNCATE|MOD|POWER|POW|SQRT|CBRT|EXP|LN|LOG|LOG2|LOG10|SIGN|PI|DEGREES|RADIANS|SIN|COS|TAN|ASIN|ACOS|ATAN|ATAN2|COT|SINH|COSH|TANH|RANDOM|RAND|NEWID|SETSEED|WIDTH_BUCKET|GREATEST|LEAST|COALESCE|NULLIF|DIV|FACTORIAL|GCD|LCM)\\b"
+ },
+ {
+ "name": "support.function.conversion.sql",
+ "match": "(?i)\\b(CAST|CONVERT|TRY_CAST|TRY_CONVERT|TRY_PARSE|PARSE|TO_NUMBER|TO_CHAR|TO_DATE|TO_TIMESTAMP|TO_BINARY_FLOAT|TO_BINARY_DOUBLE|TO_CLOB|TO_NCLOB|TO_LOB|TO_BLOB|XMLCAST|HEXTORAW|RAWTOHEX|RAWTONHEX)\\b"
+ },
+ {
+ "name": "support.function.conditional.sql",
+ "match": "(?i)\\b(COALESCE|NULLIF|GREATEST|LEAST|IIF|IF|IFNULL|NVL|NVL2|LNNVL|NANVL|DECODE|CHOOSE|CASE|ISNULL|ISNUMERIC|ISDATE|ISJSON)\\b"
+ },
+ {
+ "name": "support.function.json.sql",
+ "match": "(?i)\\b(JSON_OBJECT|JSON_ARRAY|JSON_BUILD_OBJECT|JSON_BUILD_ARRAY|JSON_AGG|JSONB_AGG|JSON_ARRAYAGG|JSON_OBJECTAGG|JSON_OBJECT_AGG|JSONB_OBJECT_AGG|TO_JSON|TO_JSONB|ARRAY_TO_JSON|ROW_TO_JSON|JSON_EXTRACT_PATH|JSON_EXTRACT_PATH_TEXT|JSONB_EXTRACT_PATH|JSONB_EXTRACT_PATH_TEXT|JSON_ARRAY_ELEMENTS|JSONB_ARRAY_ELEMENTS|JSON_ARRAY_ELEMENTS_TEXT|JSONB_ARRAY_ELEMENTS_TEXT|JSON_EACH|JSONB_EACH|JSON_EACH_TEXT|JSONB_EACH_TEXT|JSON_KEYS|JSONB_KEYS|JSON_POPULATE_RECORD|JSONB_POPULATE_RECORD|JSON_POPULATE_RECORDSET|JSONB_POPULATE_RECORDSET|JSON_TO_RECORD|JSONB_TO_RECORD|JSON_TO_RECORDSET|JSONB_TO_RECORDSET|JSON_STRIP_NULLS|JSONB_STRIP_NULLS|JSONB_SET|JSONB_INSERT|JSONB_PRETTY|JSON_TYPEOF|JSONB_TYPEOF|JSON_VALUE|JSON_QUERY|JSON_EXISTS|JSON_TABLE|JSON_SERIALIZE|JSON_PARSE|JSON_SCALAR|JSON_MERGEPATCH|JSON_DEPTH|JSON_LENGTH|JSON_TYPE|JSON_VALID|JSON_QUOTE|JSON_UNQUOTE|JSON_CONTAINS|JSON_CONTAINS_PATH|JSON_EXTRACT|JSON_INSERT|JSON_REPLACE|JSON_SET|JSON_REMOVE|JSON_APPEND|JSON_MERGE|JSON_MERGE_PATCH|JSON_MERGE_PRESERVE|JSON_SEARCH|JSON_STORAGE_SIZE|JSON_STORAGE_FREE|OPENJSON|FOR|JSON|ISJSON|JSON_MODIFY)\\b"
+ },
+ {
+ "name": "support.function.array.sql",
+ "match": "(?i)\\b(ARRAY|ARRAY_AGG|ARRAY_APPEND|ARRAY_CAT|ARRAY_DIMS|ARRAY_FILL|ARRAY_LENGTH|ARRAY_LOWER|ARRAY_NDIMS|ARRAY_POSITION|ARRAY_POSITIONS|ARRAY_PREPEND|ARRAY_REMOVE|ARRAY_REPLACE|ARRAY_TO_STRING|ARRAY_UPPER|CARDINALITY|STRING_TO_ARRAY|UNNEST|ARRAY_CONTAINS|ARRAY_DISTINCT|ARRAY_EXCEPT|ARRAY_INTERSECT|ARRAY_JOIN|ARRAY_MAX|ARRAY_MIN|ARRAY_SORT|ARRAY_UNION|ELEMENT_AT|FLATTEN|REVERSE|SEQUENCE|SHUFFLE|SLICE|ZIP_WITH|TRANSFORM|FILTER|AGGREGATE|REDUCE|GENERATE_SERIES|GENERATE_SUBSCRIPTS)\\b"
+ },
+ {
+ "name": "support.function.xml.sql",
+ "match": "(?i)\\b(XMLAGG|XMLELEMENT|XMLFOREST|XMLATTRIBUTES|XMLCONCAT|XMLCOMMENT|XMLPI|XMLROOT|XMLPARSE|XMLSERIALIZE|XMLTABLE|XMLQUERY|XMLEXISTS|XMLNAMESPACES|XMLCAST|XPATH|EXTRACTVALUE|UPDATEXML|XMLSEQUENCE|XMLTYPE|EXISTSNODE|XMLCOLATTVAL)\\b"
+ },
+ {
+ "name": "support.function.system.sql",
+ "match": "(?i)\\b(CURRENT_USER|SESSION_USER|SYSTEM_USER|USER|CURRENT_SCHEMA|CURRENT_CATALOG|CURRENT_DATABASE|VERSION|PG_TYPEOF|PG_COLUMN_SIZE|PG_DATABASE_SIZE|PG_INDEXES_SIZE|PG_RELATION_SIZE|PG_SIZE_PRETTY|PG_TABLE_SIZE|PG_TABLESPACE_SIZE|PG_TOTAL_RELATION_SIZE|HAS_DATABASE_PRIVILEGE|HAS_SCHEMA_PRIVILEGE|HAS_TABLE_PRIVILEGE|HAS_COLUMN_PRIVILEGE|HAS_FUNCTION_PRIVILEGE|HAS_SEQUENCE_PRIVILEGE|DATABASE|SCHEMA|OBJECT_ID|OBJECT_NAME|OBJECT_SCHEMA_NAME|TYPE_ID|TYPE_NAME|COLUMNPROPERTY|DATABASEPROPERTYEX|OBJECTPROPERTY|OBJECTPROPERTYEX|SERVERPROPERTY|TYPEPROPERTY|APP_NAME|HOST_NAME|SUSER_NAME|SUSER_SNAME|USER_NAME|ORIGINAL_LOGIN|@@ROWCOUNT|@@IDENTITY|@@ERROR|@@TRANCOUNT|@@FETCH_STATUS|@@SPID|@@SERVERNAME|@@VERSION|@@LANGUAGE|@@DATEFIRST|@@DBTS|@@LANGID|@@LOCK_TIMEOUT|@@MAX_CONNECTIONS|@@NESTLEVEL|@@OPTIONS|@@PROCID|@@REMSERVER|@@TEXTSIZE|SCOPE_IDENTITY|IDENT_CURRENT|IDENT_INCR|IDENT_SEED|ROWCOUNT_BIG|ERROR_NUMBER|ERROR_MESSAGE|ERROR_SEVERITY|ERROR_STATE|ERROR_LINE|ERROR_PROCEDURE|XACT_STATE|FORMATMESSAGE|CONTEXT_INFO|SET_CONTEXT_INFO|BINARY_CHECKSUM|CHECKSUM|NEWSEQUENTIALID|SEQUENCE_NUMBER|SYS_CONTEXT|USERENV|UID|SQLCODE|SQLERRM)\\b"
+ },
+ {
+ "name": "support.function.analytic.sql",
+ "comment": "Oracle analytic functions",
+ "match": "(?i)\\b(RATIO_TO_REPORT|WIDTH_BUCKET|CORR|COVAR_POP|COVAR_SAMP|REGR_SLOPE|REGR_INTERCEPT|REGR_COUNT|REGR_R2|REGR_AVGX|REGR_AVGY|REGR_SXX|REGR_SYY|REGR_SXY|PERCENTILE_CONT|PERCENTILE_DISC|LISTAGG|COLLECT|MEDIAN|STATS_MODE|STATS_BINOMIAL_TEST|STATS_CROSSTAB|STATS_F_TEST|STATS_KS_TEST|STATS_MW_TEST|STATS_ONE_WAY_ANOVA|STATS_T_TEST_ONE|STATS_T_TEST_PAIRED|STATS_T_TEST_INDEP|STATS_T_TEST_INDEPU|STATS_WSR_TEST)\\b"
+ },
+ {
+ "name": "support.function.fulltext.sql",
+ "comment": "Full-text search functions",
+ "match": "(?i)\\b(CONTAINS|CONTAINSTABLE|FREETEXT|FREETEXTTABLE|MATCH|AGAINST|TO_TSVECTOR|TO_TSQUERY|PLAINTO_TSQUERY|PHRASETO_TSQUERY|WEBSEARCH_TO_TSQUERY|TS_HEADLINE|TS_RANK|TS_RANK_CD|SETWEIGHT|TSVECTOR_UPDATE_TRIGGER|TSVECTOR_UPDATE_TRIGGER_COLUMN|GET_CURRENT_TS_CONFIG|NUMNODE|QUERYTREE|TS_DEBUG|TS_LEXIZE|TS_PARSE|TS_TOKEN_TYPE|TS_STAT|TS_DELETE|TS_FILTER|TS_REWRITE|TSQUERY_PHRASE)\\b"
+ },
+ {
+ "name": "support.function.geospatial.sql",
+ "comment": "Geospatial functions",
+ "match": "(?i)\\b(ST_AREA|ST_ASBINARY|ST_ASEWKB|ST_ASEWKT|ST_ASGEOJSON|ST_ASGML|ST_ASSVG|ST_ASTEXT|ST_AZIMUTH|ST_BOUNDARY|ST_BUFFER|ST_CENTROID|ST_CLOSESTPOINT|ST_CLUSTERDBSCAN|ST_CLUSTERKMEANS|ST_COLLECT|ST_CONTAINS|ST_CONTAINSPROPERLY|ST_CONVEXHULL|ST_COORDDIM|ST_COVEREDBY|ST_COVERS|ST_CROSSES|ST_CURVETOLINE|ST_DIFFERENCE|ST_DIMENSION|ST_DISJOINT|ST_DISTANCE|ST_DISTANCESPHERE|ST_DISTANCESPHEROID|ST_DUMPPOINTS|ST_DUMPRINGS|ST_DWITHIN|ST_ENDPOINT|ST_ENVELOPE|ST_EQUALS|ST_EXTENT|ST_EXTERIORRING|ST_FLIPCOORDINATES|ST_FORCE2D|ST_FORCE3D|ST_FORCE3DM|ST_FORCE3DZ|ST_FORCE4D|ST_FORCECOLLECTION|ST_FORCECURVE|ST_FORCEPOLYGONCW|ST_FORCEPOLYGONCCW|ST_FORCERHR|ST_FORCESFS|ST_GENERATEPOINTS|ST_GEOGFROMTEXT|ST_GEOGFROMWKB|ST_GEOGRAPHYFROMTEXT|ST_GEOHASH|ST_GEOMCOLLFROMTEXT|ST_GEOMFROMEWKB|ST_GEOMFROMEWKT|ST_GEOMFROMGEOJSON|ST_GEOMFROMGML|ST_GEOMFROMKML|ST_GEOMFROMTEXT|ST_GEOMFROMWKB|ST_GEOMETRYFROMTEXT|ST_GEOMETRYN|ST_GEOMETRYTYPE|ST_HASARC|ST_HAUSDORFFDISTANCE|ST_INTERIORRINGN|ST_INTERSECTION|ST_INTERSECTS|ST_ISCLOSED|ST_ISCOLLECTION|ST_ISEMPTY|ST_ISPOLYGONCCW|ST_ISPOLYGONCW|ST_ISRING|ST_ISSIMPLE|ST_ISVALID|ST_ISVALIDDETAIL|ST_ISVALIDREASON|ST_LENGTH|ST_LENGTH2D|ST_LINECROSSINGDIRECTION|ST_LINEFROMMULTIPOINT|ST_LINEFROMTEXT|ST_LINEFROMWKB|ST_LINEINTERPOLATEPOINT|ST_LINEINTERPOLATEPOINTS|ST_LINELOCATEPOINT|ST_LINEMERGE|ST_LINESTRINGFROMWKB|ST_LINESUBSTRING|ST_LONGESTLINE|ST_M|ST_MAKEBOX2D|ST_MAKEENVELOPE|ST_MAKELINE|ST_MAKEPOINT|ST_MAKEPOINTM|ST_MAKEPOLYGON|ST_MAKEVALID|ST_MEMSIZE|ST_MINBOUNDINGCIRCLE|ST_MINIMUMBOUNDINGCIRCLE|ST_MINIMUMBOUNDINGRADIUS|ST_MLINEFROMTEXT|ST_MLINEFROMWKB|ST_MPOINTFROMTEXT|ST_MPOINTFROMWKB|ST_MPOLYFROMTEXT|ST_MPOLYFROMWKB|ST_MULTI|ST_NDIMS|ST_NODE|ST_NORMALIZE|ST_NPOINTS|ST_NRINGS|ST_NUMGEOMETRIES|ST_NUMINTERIORRING|ST_NUMINTERIORRINGS|ST_NUMPATCHES|ST_NUMPOINTS|ST_OFFSETCURVE|ST_ORDERINGEQUALS|ST_ORIENTEDENVELOPE|ST_OVERLAPS|ST_PERIMETER|ST_PERIMETER2D|ST_POINT|ST_POINTFROMGEOHASH|ST_POINTFROMTEXT|ST_POINTFROMWKB|ST_POINTINSIDECIRCLE|ST_POINTN|ST_POINTONSURFACE|ST_POINTS|ST_POLYFROMTEXT|ST_POLYFROMWKB|ST_POLYGON|ST_POLYGONIZE|ST_PROJECT|ST_RELATE|ST_RELATEMATCH|ST_REMOVEPOINT|ST_REMOVEREPEATEDPOINTS|ST_REVERSE|ST_ROTATE|ST_ROTATEX|ST_ROTATEY|ST_ROTATEZ|ST_SCALE|ST_SEGMENTIZE|ST_SETPOINT|ST_SETSRID|ST_SHAREDPATHS|ST_SHORTESTLINE|ST_SIMPLIFY|ST_SIMPLIFYPRESERVETOPOLOGY|ST_SIMPLIFYVW|ST_SNAP|ST_SNAPTOGRID|ST_SPLIT|ST_SRID|ST_STARTPOINT|ST_SUBDIVIDE|ST_SUMMARY|ST_SWAPORDINATES|ST_SYMDIFFERENCE|ST_TOUCHES|ST_TRANSFORM|ST_TRANSLATE|ST_TRANSSCALE|ST_UNION|ST_VORONOILINES|ST_VORONOIPOLYGONS|ST_WITHIN|ST_WKBTOSQL|ST_WKTTOSQL|ST_X|ST_XMAX|ST_XMIN|ST_Y|ST_YMAX|ST_YMIN|ST_Z|ST_ZMAX|ST_ZMIN|ST_ZMFLAG)\\b"
+ }
+ ]
+ },
+ "types": {
+ "patterns": [
+ {
+ "name": "storage.type.sql",
+ "match": "(?i)\\b(SMALLINT|INTEGER|INT|INT2|INT4|INT8|BIGINT|TINYINT|MEDIUMINT|DECIMAL|NUMERIC|DEC|NUMBER|REAL|FLOAT|FLOAT4|FLOAT8|DOUBLE|PRECISION|SMALLSERIAL|SERIAL|BIGSERIAL|SERIAL2|SERIAL4|SERIAL8|MONEY|SMALLMONEY|CHARACTER|CHAR|NCHAR|VARCHAR|VARCHAR2|NVARCHAR|NVARCHAR2|CHARACTER|VARYING|TEXT|NTEXT|CLOB|NCLOB|LONG|BYTEA|BINARY|VARBINARY|BLOB|IMAGE|RAW|LONG|RAW|BIT|VARBIT|BOOLEAN|BOOL|DATE|TIME|TIMETZ|DATETIME|DATETIME2|SMALLDATETIME|TIMESTAMP|TIMESTAMPTZ|DATETIMEOFFSET|INTERVAL|YEAR|POINT|LINE|LSEG|BOX|PATH|POLYGON|CIRCLE|GEOMETRY|GEOGRAPHY|CIDR|INET|MACADDR|MACADDR8|UUID|UNIQUEIDENTIFIER|ROWVERSION|HIERARCHYID|XML|JSON|JSONB|ARRAY|INT4RANGE|INT8RANGE|NUMRANGE|TSRANGE|TSTZRANGE|DATERANGE|TSVECTOR|TSQUERY|ENUM|SET|OID|REGCLASS|REGTYPE|REGPROC|REGPROCEDURE|REGOPER|REGOPERATOR|REGNAMESPACE|REGROLE|REGCONFIG|REGDICTIONARY|CURSOR|SQL_VARIANT|TABLE|RECORD|REFCURSOR|VOID|TRIGGER|EVENT_TRIGGER|LANGUAGE_HANDLER|FDW_HANDLER|INDEX_AM_HANDLER|TSM_HANDLER)\\b"
+ },
+ {
+ "name": "storage.type.modifier.sql",
+ "match": "(?i)\\b(VARYING|ZONE|WITHOUT|WITH|PRECISION|UNSIGNED|SIGNED|ZEROFILL|NATIONAL|LARGE|OBJECT)\\b"
+ },
+ {
+ "name": "storage.type.constraint.sql",
+ "match": "(?i)\\b(NOT|NULL|CONSTRAINT|PRIMARY|KEY|UNIQUE|CHECK|FOREIGN|REFERENCES|DEFAULT|AUTO_INCREMENT|IDENTITY|GENERATED|ALWAYS|AS|STORED|VIRTUAL|INVISIBLE|VISIBLE)\\b"
+ }
+ ]
+ },
+ "identifiers": {
+ "patterns": [
+ {
+ "name": "variable.parameter.sql",
+ "comment": "Positional parameters ($1, $2, etc.)",
+ "match": "\\$\\d+"
+ },
+ {
+ "name": "variable.parameter.named.sql",
+ "comment": "Named parameters (:param, @param)",
+ "match": "[:@][a-zA-Z_][a-zA-Z0-9_]*"
+ },
+ {
+ "name": "variable.other.sqlserver.sql",
+ "comment": "SQL Server local variables (@@var)",
+ "match": "@@[a-zA-Z_][a-zA-Z0-9_]*"
+ },
+ {
+ "name": "variable.other.mysql.sql",
+ "comment": "MySQL user-defined variables (@var)",
+ "match": "@[a-zA-Z_][a-zA-Z0-9_]*"
+ },
+ {
+ "name": "entity.name.function.sql",
+ "comment": "Function calls",
+ "match": "\\b([a-zA-Z_][a-zA-Z0-9_]*)\\s*(?=\\()"
+ },
+ {
+ "name": "entity.name.sql",
+ "match": "\\b[a-zA-Z_][a-zA-Z0-9_]*\\b"
+ }
+ ]
+ }
+ }
+}
diff --git a/vscode-extension/tsconfig.json b/vscode-extension/tsconfig.json
new file mode 100644
index 0000000..51b9691
--- /dev/null
+++ b/vscode-extension/tsconfig.json
@@ -0,0 +1,16 @@
+{
+ "compilerOptions": {
+ "module": "commonjs",
+ "target": "ES2022",
+ "outDir": "out",
+ "lib": ["ES2022"],
+ "sourceMap": true,
+ "rootDir": "src",
+ "strict": true,
+ "esModuleInterop": true,
+ "skipLibCheck": true,
+ "forceConsistentCasingInFileNames": true,
+ "resolveJsonModule": true
+ },
+ "exclude": ["node_modules", ".vscode-test"]
+}