diff --git a/.eslintignore b/.eslintignore index d0fe371..e0fa9f1 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,5 +1,6 @@ node_modules dist coverage +./data requirements .vscode \ No newline at end of file diff --git a/.gitignore b/.gitignore index 404778a..a25958a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,8 @@ node_modules dist coverage +data +!src/data +!tests/data .vscode globalConfig.json \ No newline at end of file diff --git a/.husky/pre-commit b/.husky/pre-commit index d24fdfc..36af219 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,4 +1,4 @@ -#!/usr/bin/env sh -. "$(dirname -- "$0")/_/husky.sh" +#!/bin/sh +. "$(dirname "$0")/_/husky.sh" npx lint-staged diff --git a/.husky/pre-push b/.husky/pre-push index 1525982..1dc4645 100755 --- a/.husky/pre-push +++ b/.husky/pre-push @@ -1,2 +1,4 @@ -#!/usr/bin/env sh -. "$(dirname -- "$0")/_/husky.sh" +#!/bin/sh +. "$(dirname "$0")/_/husky.sh" + +npm run test:ci diff --git a/.lintstagedrc.json b/.lintstagedrc.json index bade2fb..a759a64 100644 --- a/.lintstagedrc.json +++ b/.lintstagedrc.json @@ -1,5 +1,6 @@ { - "*.{ts,tsx}": [ - "eslint 'src/**' --fix" + "*.ts": [ + "eslint . --fix", + "npm run test:staged" ] } \ No newline at end of file diff --git a/jest-integration-config.js b/jest-integration-config.js index 5d655cc..1b77537 100644 --- a/jest-integration-config.js +++ b/jest-integration-config.js @@ -1,3 +1,3 @@ -const config = require('./jest.config.ts') +const config = require('./jest.config') config.testMatch = ['**/*.test.ts'] module.exports = config diff --git a/jest-unit-config.js b/jest-unit-config.js index 88fc7b6..56bc8f4 100644 --- a/jest-unit-config.js +++ b/jest-unit-config.js @@ -1,3 +1,3 @@ -const config = require('./jest.config.ts') +const config = require('./jest.config') config.testMatch = ['**/*.spec.ts'] module.exports = config diff --git a/jest.config.js b/jest.config.js index 4ccc730..14f1e98 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,20 +1,18 @@ module.exports = { - roots: ['/src'], - collectCoverage: true, + roots: ['/tests'], collectCoverageFrom: [ '/src/**/*.ts', - '!/src/main/**', - '!**/test/**' + '!/src/main/**' ], coverageDirectory: 'coverage', - coverageProvider: 'v8', + coverageProvider: 'babel', testEnvironment: 'node', preset: '@shelf/jest-mongodb', - watchPathIgnorePatterns: ['globalConfig'], transform: { '.+\\.ts$': 'ts-jest' }, moduleNameMapper: { + '@/tests/(.*)': '/tests/$1', '@/(.*)': '/src/$1' } } diff --git a/license b/license new file mode 100644 index 0000000..e72bfdd --- /dev/null +++ b/license @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 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 General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is 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. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + 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. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + 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 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. Use with the GNU Affero General Public License. + + 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 Affero 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 special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU 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 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 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 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 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + 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 GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 5e279ed..0ebb5a9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,53 +1,67 @@ { "name": "clean-api", - "version": "1.4.0", + "version": "2.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "clean-api", - "version": "1.4.0", - "license": "ISC", + "version": "2.0.0", + "license": "GPL-3.0-or-later", "dependencies": { + "@graphql-tools/schema": "^9.0.17", + "@graphql-tools/utils": "^9.2.1", + "apollo-server-express": "^3.12.0", "bcrypt": "^5.1.0", "express": "^4.18.2", + "graphql": "^16.6.0", + "graphql-scalars": "^1.20.4", "jsonwebtoken": "^9.0.0", "module-alias": "^2.2.2", + "mongo-round": "^1.0.0", "mongodb": "^5.1.0", + "nodemon": "^2.0.21", "swagger-ui-express": "^4.6.2", "validator": "^13.9.0" }, "devDependencies": { + "@faker-js/faker": "^7.6.0", "@shelf/jest-mongodb": "^4.1.7", "@types/bcrypt": "^5.0.0", "@types/express": "^4.17.17", - "@types/jest": "^29.4.0", + "@types/express-serve-static-core": "^4.17.33", + "@types/faker": "^6.6.9", + "@types/graphql": "^14.5.0", + "@types/graphql-iso-date": "^3.4.0", + "@types/jest": "^29.5.0", "@types/jsonwebtoken": "^9.0.1", "@types/mongodb": "^4.0.7", - "@types/node": "^18.15.0", + "@types/node": "^18.15.5", "@types/supertest": "^2.0.12", "@types/swagger-ui-express": "^4.1.3", - "@types/validator": "^13.7.13", - "@typescript-eslint/eslint-plugin": "^5.54.0", - "eslint": "^8.35.0", - "eslint-config-standard-with-typescript": "^34.0.0", + "@types/validator": "^13.7.14", + "@typescript-eslint/eslint-plugin": "^5.56.0", + "bson-objectid": "^2.0.4", + "copyfiles": "^2.4.1", + "coveralls": "^3.1.1", + "eslint": "^8.36.0", + "eslint-config-standard-with-typescript": "^34.0.1", "eslint-plugin-import": "^2.27.5", - "eslint-plugin-n": "^15.6.1", + "eslint-plugin-node": "^11.1.0", "eslint-plugin-promise": "^6.1.1", + "eslint-plugin-standard": "^5.0.0", "git-commit-msg-linter": "^4.9.2", "husky": "^8.0.3", "jest": "^29.5.0", "lint-staged": "^13.2.0", "mockdate": "^3.0.5", - "mongodb-memory-server": "^8.12.0", - "mongodb-memory-server-global": "^8.12.0", "rimraf": "^4.4.0", - "sucrase": "^3.29.0", "supertest": "^6.3.3", "ts-jest": "^29.0.5", - "ts-node": "^10.9.1", - "tslib": "^2.5.0", - "typescript": "^4.9.5" + "typescript": "^5.0.2" + }, + "engines": { + "node": "18.x" } }, "node_modules/@ampproject/remapping": { @@ -63,6 +77,157 @@ "node": ">=6.0.0" } }, + "node_modules/@apollo/protobufjs": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@apollo/protobufjs/-/protobufjs-1.2.7.tgz", + "integrity": "sha512-Lahx5zntHPZia35myYDBRuF58tlwPskwHc5CWBZC/4bMKB6siTBWwtMrkqXcsNwQiFSzSx5hKdRPUmemrEp3Gg==", + "hasInstallScript": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.0", + "long": "^4.0.0" + }, + "bin": { + "apollo-pbjs": "bin/pbjs", + "apollo-pbts": "bin/pbts" + } + }, + "node_modules/@apollo/usage-reporting-protobuf": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@apollo/usage-reporting-protobuf/-/usage-reporting-protobuf-4.1.0.tgz", + "integrity": "sha512-hXouMuw5pQVkzi8dgMybmr6Y11+eRmMQVoB5TF0HyTwAg9SOq/v3OCuiYqcVUKdBcskU9Msp+XvjAk0GKpWCwQ==", + "dependencies": { + "@apollo/protobufjs": "1.2.7" + } + }, + "node_modules/@apollo/utils.dropunuseddefinitions": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@apollo/utils.dropunuseddefinitions/-/utils.dropunuseddefinitions-1.1.0.tgz", + "integrity": "sha512-jU1XjMr6ec9pPoL+BFWzEPW7VHHulVdGKMkPAMiCigpVIT11VmCbnij0bWob8uS3ODJ65tZLYKAh/55vLw2rbg==", + "engines": { + "node": ">=12.13.0" + }, + "peerDependencies": { + "graphql": "14.x || 15.x || 16.x" + } + }, + "node_modules/@apollo/utils.keyvaluecache": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@apollo/utils.keyvaluecache/-/utils.keyvaluecache-1.0.2.tgz", + "integrity": "sha512-p7PVdLPMnPzmXSQVEsy27cYEjVON+SH/Wb7COyW3rQN8+wJgT1nv9jZouYtztWW8ZgTkii5T6tC9qfoDREd4mg==", + "dependencies": { + "@apollo/utils.logger": "^1.0.0", + "lru-cache": "7.10.1 - 7.13.1" + } + }, + "node_modules/@apollo/utils.keyvaluecache/node_modules/lru-cache": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.13.1.tgz", + "integrity": "sha512-CHqbAq7NFlW3RSnoWXLJBxCWaZVBrfa9UEHId2M3AW8iEBurbqduNexEUCGc3SHc6iCYXNJCDi903LajSVAEPQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/@apollo/utils.logger": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.logger/-/utils.logger-1.0.1.tgz", + "integrity": "sha512-XdlzoY7fYNK4OIcvMD2G94RoFZbzTQaNP0jozmqqMudmaGo2I/2Jx71xlDJ801mWA/mbYRihyaw6KJii7k5RVA==" + }, + "node_modules/@apollo/utils.printwithreducedwhitespace": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@apollo/utils.printwithreducedwhitespace/-/utils.printwithreducedwhitespace-1.1.0.tgz", + "integrity": "sha512-GfFSkAv3n1toDZ4V6u2d7L4xMwLA+lv+6hqXicMN9KELSJ9yy9RzuEXaX73c/Ry+GzRsBy/fdSUGayGqdHfT2Q==", + "engines": { + "node": ">=12.13.0" + }, + "peerDependencies": { + "graphql": "14.x || 15.x || 16.x" + } + }, + "node_modules/@apollo/utils.removealiases": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@apollo/utils.removealiases/-/utils.removealiases-1.0.0.tgz", + "integrity": "sha512-6cM8sEOJW2LaGjL/0vHV0GtRaSekrPQR4DiywaApQlL9EdROASZU5PsQibe2MWeZCOhNrPRuHh4wDMwPsWTn8A==", + "engines": { + "node": ">=12.13.0" + }, + "peerDependencies": { + "graphql": "14.x || 15.x || 16.x" + } + }, + "node_modules/@apollo/utils.sortast": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@apollo/utils.sortast/-/utils.sortast-1.1.0.tgz", + "integrity": "sha512-VPlTsmUnOwzPK5yGZENN069y6uUHgeiSlpEhRnLFYwYNoJHsuJq2vXVwIaSmts015WTPa2fpz1inkLYByeuRQA==", + "dependencies": { + "lodash.sortby": "^4.7.0" + }, + "engines": { + "node": ">=12.13.0" + }, + "peerDependencies": { + "graphql": "14.x || 15.x || 16.x" + } + }, + "node_modules/@apollo/utils.stripsensitiveliterals": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@apollo/utils.stripsensitiveliterals/-/utils.stripsensitiveliterals-1.2.0.tgz", + "integrity": "sha512-E41rDUzkz/cdikM5147d8nfCFVKovXxKBcjvLEQ7bjZm/cg9zEcXvS6vFY8ugTubI3fn6zoqo0CyU8zT+BGP9w==", + "engines": { + "node": ">=12.13.0" + }, + "peerDependencies": { + "graphql": "14.x || 15.x || 16.x" + } + }, + "node_modules/@apollo/utils.usagereporting": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.usagereporting/-/utils.usagereporting-1.0.1.tgz", + "integrity": "sha512-6dk+0hZlnDbahDBB2mP/PZ5ybrtCJdLMbeNJD+TJpKyZmSY6bA3SjI8Cr2EM9QA+AdziywuWg+SgbWUF3/zQqQ==", + "dependencies": { + "@apollo/usage-reporting-protobuf": "^4.0.0", + "@apollo/utils.dropunuseddefinitions": "^1.1.0", + "@apollo/utils.printwithreducedwhitespace": "^1.1.0", + "@apollo/utils.removealiases": "1.0.0", + "@apollo/utils.sortast": "^1.1.0", + "@apollo/utils.stripsensitiveliterals": "^1.2.0" + }, + "engines": { + "node": ">=12.13.0" + }, + "peerDependencies": { + "graphql": "14.x || 15.x || 16.x" + } + }, + "node_modules/@apollographql/apollo-tools": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/@apollographql/apollo-tools/-/apollo-tools-0.5.4.tgz", + "integrity": "sha512-shM3q7rUbNyXVVRkQJQseXv6bnYM3BUma/eZhwXR4xsuM+bqWnJKvW7SAfRjP7LuSCocrexa5AXhjjawNHrIlw==", + "engines": { + "node": ">=8", + "npm": ">=6" + }, + "peerDependencies": { + "graphql": "^14.2.1 || ^15.0.0 || ^16.0.0" + } + }, + "node_modules/@apollographql/graphql-playground-html": { + "version": "1.6.29", + "resolved": "https://registry.npmjs.org/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.29.tgz", + "integrity": "sha512-xCcXpoz52rI4ksJSdOCxeOCn2DLocxwHf9dVT/Q90Pte1LX+LY+91SFtJF3KXVHH8kEin+g1KKCQPKBjZJfWNA==", + "dependencies": { + "xss": "^1.0.8" + } + }, "node_modules/@aws-crypto/ie11-detection": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@aws-crypto/ie11-detection/-/ie11-detection-3.0.0.tgz", @@ -150,507 +315,507 @@ "optional": true }, "node_modules/@aws-sdk/abort-controller": { - "version": "3.272.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/abort-controller/-/abort-controller-3.272.0.tgz", - "integrity": "sha512-s2TV3phapcTwZNr4qLxbfuQuE9ZMP4RoJdkvRRCkKdm6jslsWLJf2Zlcxti/23hOlINUMYv2iXE2pftIgWGdpg==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/abort-controller/-/abort-controller-3.295.0.tgz", + "integrity": "sha512-uohsGotvQ8RTgVZ9sQt0y3L60jBEYgN8MOn3Seaku8HpIIo9c6iIfkF0bMXZeFI2sCxqbrBDbsPKYWxr7rd8LA==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/client-cognito-identity": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.282.0.tgz", - "integrity": "sha512-OU9Wy50u31Mog4xmj9o+lLOb/y+yuQBTFwEVYApJtCkPsI2e3DtZFt36IcAy04fcjNUaSD3u6SGgfYo2vDQ2zA==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.295.0.tgz", + "integrity": "sha512-W17vm7epIEHT7Lr12T0xTAipze4dyS5u6onLV7Sx+5tEiMObmkfkXQsjCheMqHD7pGEJNZqAvY43GeirtzOlSw==", "optional": true, "dependencies": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/client-sts": "3.282.0", - "@aws-sdk/config-resolver": "3.282.0", - "@aws-sdk/credential-provider-node": "3.282.0", - "@aws-sdk/fetch-http-handler": "3.282.0", - "@aws-sdk/hash-node": "3.272.0", - "@aws-sdk/invalid-dependency": "3.272.0", - "@aws-sdk/middleware-content-length": "3.282.0", - "@aws-sdk/middleware-endpoint": "3.282.0", - "@aws-sdk/middleware-host-header": "3.282.0", - "@aws-sdk/middleware-logger": "3.272.0", - "@aws-sdk/middleware-recursion-detection": "3.282.0", - "@aws-sdk/middleware-retry": "3.282.0", - "@aws-sdk/middleware-serde": "3.272.0", - "@aws-sdk/middleware-signing": "3.282.0", - "@aws-sdk/middleware-stack": "3.272.0", - "@aws-sdk/middleware-user-agent": "3.282.0", - "@aws-sdk/node-config-provider": "3.272.0", - "@aws-sdk/node-http-handler": "3.282.0", - "@aws-sdk/protocol-http": "3.282.0", - "@aws-sdk/smithy-client": "3.279.0", - "@aws-sdk/types": "3.272.0", - "@aws-sdk/url-parser": "3.272.0", - "@aws-sdk/util-base64": "3.208.0", - "@aws-sdk/util-body-length-browser": "3.188.0", - "@aws-sdk/util-body-length-node": "3.208.0", - "@aws-sdk/util-defaults-mode-browser": "3.279.0", - "@aws-sdk/util-defaults-mode-node": "3.282.0", - "@aws-sdk/util-endpoints": "3.272.0", - "@aws-sdk/util-retry": "3.272.0", - "@aws-sdk/util-user-agent-browser": "3.282.0", - "@aws-sdk/util-user-agent-node": "3.282.0", - "@aws-sdk/util-utf8": "3.254.0", - "tslib": "^2.3.1" + "@aws-sdk/client-sts": "3.295.0", + "@aws-sdk/config-resolver": "3.295.0", + "@aws-sdk/credential-provider-node": "3.295.0", + "@aws-sdk/fetch-http-handler": "3.295.0", + "@aws-sdk/hash-node": "3.295.0", + "@aws-sdk/invalid-dependency": "3.295.0", + "@aws-sdk/middleware-content-length": "3.295.0", + "@aws-sdk/middleware-endpoint": "3.295.0", + "@aws-sdk/middleware-host-header": "3.295.0", + "@aws-sdk/middleware-logger": "3.295.0", + "@aws-sdk/middleware-recursion-detection": "3.295.0", + "@aws-sdk/middleware-retry": "3.295.0", + "@aws-sdk/middleware-serde": "3.295.0", + "@aws-sdk/middleware-signing": "3.295.0", + "@aws-sdk/middleware-stack": "3.295.0", + "@aws-sdk/middleware-user-agent": "3.295.0", + "@aws-sdk/node-config-provider": "3.295.0", + "@aws-sdk/node-http-handler": "3.295.0", + "@aws-sdk/protocol-http": "3.295.0", + "@aws-sdk/smithy-client": "3.295.0", + "@aws-sdk/types": "3.295.0", + "@aws-sdk/url-parser": "3.295.0", + "@aws-sdk/util-base64": "3.295.0", + "@aws-sdk/util-body-length-browser": "3.295.0", + "@aws-sdk/util-body-length-node": "3.295.0", + "@aws-sdk/util-defaults-mode-browser": "3.295.0", + "@aws-sdk/util-defaults-mode-node": "3.295.0", + "@aws-sdk/util-endpoints": "3.295.0", + "@aws-sdk/util-retry": "3.295.0", + "@aws-sdk/util-user-agent-browser": "3.295.0", + "@aws-sdk/util-user-agent-node": "3.295.0", + "@aws-sdk/util-utf8": "3.295.0", + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/client-sso": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.282.0.tgz", - "integrity": "sha512-VzdCCaxlDyU+7wvLDWh+uACQ6RPfaKLQ3yJ2UY0B0SkH4R0E4GLDJ2OJzqS5eyyOsnq1rxfY75S4WYzj8E2cvg==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.295.0.tgz", + "integrity": "sha512-uNEchm1LAQHP2/S21jz0NxCe8yqUe3J1jZG3N/dwx7uKVndHomTmjBsClGxT8IL9hC/Xl57G+fEpTCrFMjUR2g==", "optional": true, "dependencies": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/config-resolver": "3.282.0", - "@aws-sdk/fetch-http-handler": "3.282.0", - "@aws-sdk/hash-node": "3.272.0", - "@aws-sdk/invalid-dependency": "3.272.0", - "@aws-sdk/middleware-content-length": "3.282.0", - "@aws-sdk/middleware-endpoint": "3.282.0", - "@aws-sdk/middleware-host-header": "3.282.0", - "@aws-sdk/middleware-logger": "3.272.0", - "@aws-sdk/middleware-recursion-detection": "3.282.0", - "@aws-sdk/middleware-retry": "3.282.0", - "@aws-sdk/middleware-serde": "3.272.0", - "@aws-sdk/middleware-stack": "3.272.0", - "@aws-sdk/middleware-user-agent": "3.282.0", - "@aws-sdk/node-config-provider": "3.272.0", - "@aws-sdk/node-http-handler": "3.282.0", - "@aws-sdk/protocol-http": "3.282.0", - "@aws-sdk/smithy-client": "3.279.0", - "@aws-sdk/types": "3.272.0", - "@aws-sdk/url-parser": "3.272.0", - "@aws-sdk/util-base64": "3.208.0", - "@aws-sdk/util-body-length-browser": "3.188.0", - "@aws-sdk/util-body-length-node": "3.208.0", - "@aws-sdk/util-defaults-mode-browser": "3.279.0", - "@aws-sdk/util-defaults-mode-node": "3.282.0", - "@aws-sdk/util-endpoints": "3.272.0", - "@aws-sdk/util-retry": "3.272.0", - "@aws-sdk/util-user-agent-browser": "3.282.0", - "@aws-sdk/util-user-agent-node": "3.282.0", - "@aws-sdk/util-utf8": "3.254.0", - "tslib": "^2.3.1" + "@aws-sdk/config-resolver": "3.295.0", + "@aws-sdk/fetch-http-handler": "3.295.0", + "@aws-sdk/hash-node": "3.295.0", + "@aws-sdk/invalid-dependency": "3.295.0", + "@aws-sdk/middleware-content-length": "3.295.0", + "@aws-sdk/middleware-endpoint": "3.295.0", + "@aws-sdk/middleware-host-header": "3.295.0", + "@aws-sdk/middleware-logger": "3.295.0", + "@aws-sdk/middleware-recursion-detection": "3.295.0", + "@aws-sdk/middleware-retry": "3.295.0", + "@aws-sdk/middleware-serde": "3.295.0", + "@aws-sdk/middleware-stack": "3.295.0", + "@aws-sdk/middleware-user-agent": "3.295.0", + "@aws-sdk/node-config-provider": "3.295.0", + "@aws-sdk/node-http-handler": "3.295.0", + "@aws-sdk/protocol-http": "3.295.0", + "@aws-sdk/smithy-client": "3.295.0", + "@aws-sdk/types": "3.295.0", + "@aws-sdk/url-parser": "3.295.0", + "@aws-sdk/util-base64": "3.295.0", + "@aws-sdk/util-body-length-browser": "3.295.0", + "@aws-sdk/util-body-length-node": "3.295.0", + "@aws-sdk/util-defaults-mode-browser": "3.295.0", + "@aws-sdk/util-defaults-mode-node": "3.295.0", + "@aws-sdk/util-endpoints": "3.295.0", + "@aws-sdk/util-retry": "3.295.0", + "@aws-sdk/util-user-agent-browser": "3.295.0", + "@aws-sdk/util-user-agent-node": "3.295.0", + "@aws-sdk/util-utf8": "3.295.0", + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/client-sso-oidc": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.282.0.tgz", - "integrity": "sha512-upC4yBZllAXg5OVIuS8Lu9MI1aqfAObl2BBixj9fIYbDanQ02s0b1IwfZqlOqNNkGzMko1AWyiOSyOdVgyJ+xg==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.295.0.tgz", + "integrity": "sha512-HijuG2OAmTy0Wa3JHgIMBrBlsWC6GjWkH8KcRIGbFUH2nW8LFh3gBKuB1oubZ4wAdOIBFNECWA6FKFayFlKmew==", "optional": true, "dependencies": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/config-resolver": "3.282.0", - "@aws-sdk/fetch-http-handler": "3.282.0", - "@aws-sdk/hash-node": "3.272.0", - "@aws-sdk/invalid-dependency": "3.272.0", - "@aws-sdk/middleware-content-length": "3.282.0", - "@aws-sdk/middleware-endpoint": "3.282.0", - "@aws-sdk/middleware-host-header": "3.282.0", - "@aws-sdk/middleware-logger": "3.272.0", - "@aws-sdk/middleware-recursion-detection": "3.282.0", - "@aws-sdk/middleware-retry": "3.282.0", - "@aws-sdk/middleware-serde": "3.272.0", - "@aws-sdk/middleware-stack": "3.272.0", - "@aws-sdk/middleware-user-agent": "3.282.0", - "@aws-sdk/node-config-provider": "3.272.0", - "@aws-sdk/node-http-handler": "3.282.0", - "@aws-sdk/protocol-http": "3.282.0", - "@aws-sdk/smithy-client": "3.279.0", - "@aws-sdk/types": "3.272.0", - "@aws-sdk/url-parser": "3.272.0", - "@aws-sdk/util-base64": "3.208.0", - "@aws-sdk/util-body-length-browser": "3.188.0", - "@aws-sdk/util-body-length-node": "3.208.0", - "@aws-sdk/util-defaults-mode-browser": "3.279.0", - "@aws-sdk/util-defaults-mode-node": "3.282.0", - "@aws-sdk/util-endpoints": "3.272.0", - "@aws-sdk/util-retry": "3.272.0", - "@aws-sdk/util-user-agent-browser": "3.282.0", - "@aws-sdk/util-user-agent-node": "3.282.0", - "@aws-sdk/util-utf8": "3.254.0", - "tslib": "^2.3.1" + "@aws-sdk/config-resolver": "3.295.0", + "@aws-sdk/fetch-http-handler": "3.295.0", + "@aws-sdk/hash-node": "3.295.0", + "@aws-sdk/invalid-dependency": "3.295.0", + "@aws-sdk/middleware-content-length": "3.295.0", + "@aws-sdk/middleware-endpoint": "3.295.0", + "@aws-sdk/middleware-host-header": "3.295.0", + "@aws-sdk/middleware-logger": "3.295.0", + "@aws-sdk/middleware-recursion-detection": "3.295.0", + "@aws-sdk/middleware-retry": "3.295.0", + "@aws-sdk/middleware-serde": "3.295.0", + "@aws-sdk/middleware-stack": "3.295.0", + "@aws-sdk/middleware-user-agent": "3.295.0", + "@aws-sdk/node-config-provider": "3.295.0", + "@aws-sdk/node-http-handler": "3.295.0", + "@aws-sdk/protocol-http": "3.295.0", + "@aws-sdk/smithy-client": "3.295.0", + "@aws-sdk/types": "3.295.0", + "@aws-sdk/url-parser": "3.295.0", + "@aws-sdk/util-base64": "3.295.0", + "@aws-sdk/util-body-length-browser": "3.295.0", + "@aws-sdk/util-body-length-node": "3.295.0", + "@aws-sdk/util-defaults-mode-browser": "3.295.0", + "@aws-sdk/util-defaults-mode-node": "3.295.0", + "@aws-sdk/util-endpoints": "3.295.0", + "@aws-sdk/util-retry": "3.295.0", + "@aws-sdk/util-user-agent-browser": "3.295.0", + "@aws-sdk/util-user-agent-node": "3.295.0", + "@aws-sdk/util-utf8": "3.295.0", + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/client-sts": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.282.0.tgz", - "integrity": "sha512-JZybEaST0rloS9drlX/0yJAnKHuV7DlS1n1WZxgaM2DY704ydlGiviiPQvC/q/dItsX4017gscC0blGJcUjK1g==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.295.0.tgz", + "integrity": "sha512-KrLnG5EcXvry9tmsTAONhlj60F0+Z7P2PtT0XDsS8pLayHAtd9lKXsf14DOSQa9+LbPLMFbfLbuSwvPYvgxMzg==", "optional": true, "dependencies": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/config-resolver": "3.282.0", - "@aws-sdk/credential-provider-node": "3.282.0", - "@aws-sdk/fetch-http-handler": "3.282.0", - "@aws-sdk/hash-node": "3.272.0", - "@aws-sdk/invalid-dependency": "3.272.0", - "@aws-sdk/middleware-content-length": "3.282.0", - "@aws-sdk/middleware-endpoint": "3.282.0", - "@aws-sdk/middleware-host-header": "3.282.0", - "@aws-sdk/middleware-logger": "3.272.0", - "@aws-sdk/middleware-recursion-detection": "3.282.0", - "@aws-sdk/middleware-retry": "3.282.0", - "@aws-sdk/middleware-sdk-sts": "3.282.0", - "@aws-sdk/middleware-serde": "3.272.0", - "@aws-sdk/middleware-signing": "3.282.0", - "@aws-sdk/middleware-stack": "3.272.0", - "@aws-sdk/middleware-user-agent": "3.282.0", - "@aws-sdk/node-config-provider": "3.272.0", - "@aws-sdk/node-http-handler": "3.282.0", - "@aws-sdk/protocol-http": "3.282.0", - "@aws-sdk/smithy-client": "3.279.0", - "@aws-sdk/types": "3.272.0", - "@aws-sdk/url-parser": "3.272.0", - "@aws-sdk/util-base64": "3.208.0", - "@aws-sdk/util-body-length-browser": "3.188.0", - "@aws-sdk/util-body-length-node": "3.208.0", - "@aws-sdk/util-defaults-mode-browser": "3.279.0", - "@aws-sdk/util-defaults-mode-node": "3.282.0", - "@aws-sdk/util-endpoints": "3.272.0", - "@aws-sdk/util-retry": "3.272.0", - "@aws-sdk/util-user-agent-browser": "3.282.0", - "@aws-sdk/util-user-agent-node": "3.282.0", - "@aws-sdk/util-utf8": "3.254.0", + "@aws-sdk/config-resolver": "3.295.0", + "@aws-sdk/credential-provider-node": "3.295.0", + "@aws-sdk/fetch-http-handler": "3.295.0", + "@aws-sdk/hash-node": "3.295.0", + "@aws-sdk/invalid-dependency": "3.295.0", + "@aws-sdk/middleware-content-length": "3.295.0", + "@aws-sdk/middleware-endpoint": "3.295.0", + "@aws-sdk/middleware-host-header": "3.295.0", + "@aws-sdk/middleware-logger": "3.295.0", + "@aws-sdk/middleware-recursion-detection": "3.295.0", + "@aws-sdk/middleware-retry": "3.295.0", + "@aws-sdk/middleware-sdk-sts": "3.295.0", + "@aws-sdk/middleware-serde": "3.295.0", + "@aws-sdk/middleware-signing": "3.295.0", + "@aws-sdk/middleware-stack": "3.295.0", + "@aws-sdk/middleware-user-agent": "3.295.0", + "@aws-sdk/node-config-provider": "3.295.0", + "@aws-sdk/node-http-handler": "3.295.0", + "@aws-sdk/protocol-http": "3.295.0", + "@aws-sdk/smithy-client": "3.295.0", + "@aws-sdk/types": "3.295.0", + "@aws-sdk/url-parser": "3.295.0", + "@aws-sdk/util-base64": "3.295.0", + "@aws-sdk/util-body-length-browser": "3.295.0", + "@aws-sdk/util-body-length-node": "3.295.0", + "@aws-sdk/util-defaults-mode-browser": "3.295.0", + "@aws-sdk/util-defaults-mode-node": "3.295.0", + "@aws-sdk/util-endpoints": "3.295.0", + "@aws-sdk/util-retry": "3.295.0", + "@aws-sdk/util-user-agent-browser": "3.295.0", + "@aws-sdk/util-user-agent-node": "3.295.0", + "@aws-sdk/util-utf8": "3.295.0", "fast-xml-parser": "4.1.2", - "tslib": "^2.3.1" + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/config-resolver": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/config-resolver/-/config-resolver-3.282.0.tgz", - "integrity": "sha512-30qFLh2N4NXQ2EAook7NIFeu1K/nlrRLrdVb2BtGFi/F3cZnz+sy9o0XmL6x+sO9TznWjdNxD1RKQdqoAwGnCQ==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/config-resolver/-/config-resolver-3.295.0.tgz", + "integrity": "sha512-oSGdGAjmOesxGAT/Ce8P7Gdvf4KVQjasKqmlAMTXsUBxh8Mx8BQH9V3UCiCdfJ2Vx7H4pqN4Y8WcAQkje4uvbQ==", "optional": true, "dependencies": { - "@aws-sdk/signature-v4": "3.282.0", - "@aws-sdk/types": "3.272.0", - "@aws-sdk/util-config-provider": "3.208.0", - "@aws-sdk/util-middleware": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/signature-v4": "3.295.0", + "@aws-sdk/types": "3.295.0", + "@aws-sdk/util-config-provider": "3.295.0", + "@aws-sdk/util-middleware": "3.295.0", + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/credential-provider-cognito-identity": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.282.0.tgz", - "integrity": "sha512-GsLOt6GzckLQbMzgXOblKcRtXyMu3NcP0vFkYpy4r9oEzoxqPhy1yUpRNLeDv7r2qoa8naN81F5FwPwd17PrKg==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.295.0.tgz", + "integrity": "sha512-1cqqctA2UdzeV+jCg3vk5yIbkT9JX0M+xtyPcsIcKqwBHEl48SCmLUTs6C7ZpcRS61vlkvE0bTEq+EfMCxuaDw==", "optional": true, "dependencies": { - "@aws-sdk/client-cognito-identity": "3.282.0", - "@aws-sdk/property-provider": "3.272.0", - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/client-cognito-identity": "3.295.0", + "@aws-sdk/property-provider": "3.295.0", + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/credential-provider-env": { - "version": "3.272.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.272.0.tgz", - "integrity": "sha512-QI65NbLnKLYHyTYhXaaUrq6eVsCCrMUb05WDA7+TJkWkjXesovpjc8vUKgFiLSxmgKmb2uOhHNcDyObKMrYQFw==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.295.0.tgz", + "integrity": "sha512-YjUDJwhgwUgFYT4fJQVCMA1Abw2Jw1xC3EeNxeV2L54CvM9PlbFuRa5qJehePKoTLyva4bjLsMXsensXrEEIGQ==", "optional": true, "dependencies": { - "@aws-sdk/property-provider": "3.272.0", - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/property-provider": "3.295.0", + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/credential-provider-imds": { - "version": "3.272.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-imds/-/credential-provider-imds-3.272.0.tgz", - "integrity": "sha512-wwAfVY1jTFQEfxVfdYD5r5ieYGl+0g4nhekVxNMqE8E1JeRDd18OqiwAflzpgBIqxfqvCUkf+vl5JYyacMkNAQ==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-imds/-/credential-provider-imds-3.295.0.tgz", + "integrity": "sha512-+tOVCZi7LUG2pvjK9P35hhXL1cZTJsbGtrMsIxrlUODjKEhht4RSiQH7zT324x6MkYby9iLjU4SUejyKBKDhYQ==", "optional": true, "dependencies": { - "@aws-sdk/node-config-provider": "3.272.0", - "@aws-sdk/property-provider": "3.272.0", - "@aws-sdk/types": "3.272.0", - "@aws-sdk/url-parser": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/node-config-provider": "3.295.0", + "@aws-sdk/property-provider": "3.295.0", + "@aws-sdk/types": "3.295.0", + "@aws-sdk/url-parser": "3.295.0", + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.282.0.tgz", - "integrity": "sha512-2GKduXORcUgOigF1jZF7A1Wh4W/aJt3ynh7xb1vfx020nHx6YDljrEGpzgH6pOVzl7ZhgthpojicCuy2UumkMA==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.295.0.tgz", + "integrity": "sha512-XU3UqVVxxjyXcZ2Wkx3CM+/eLUM/EDlqJkLU6nl3FDGzPZeXC3G9Z9ZywGBo7dpRbBpDfpzSSukJisiGLTwg2w==", "optional": true, "dependencies": { - "@aws-sdk/credential-provider-env": "3.272.0", - "@aws-sdk/credential-provider-imds": "3.272.0", - "@aws-sdk/credential-provider-process": "3.272.0", - "@aws-sdk/credential-provider-sso": "3.282.0", - "@aws-sdk/credential-provider-web-identity": "3.272.0", - "@aws-sdk/property-provider": "3.272.0", - "@aws-sdk/shared-ini-file-loader": "3.272.0", - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/credential-provider-env": "3.295.0", + "@aws-sdk/credential-provider-imds": "3.295.0", + "@aws-sdk/credential-provider-process": "3.295.0", + "@aws-sdk/credential-provider-sso": "3.295.0", + "@aws-sdk/credential-provider-web-identity": "3.295.0", + "@aws-sdk/property-provider": "3.295.0", + "@aws-sdk/shared-ini-file-loader": "3.295.0", + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.282.0.tgz", - "integrity": "sha512-qyHipZW0ep8STY+SO+Me8ObQ1Ee/aaZTmAK0Os/gB+EsiZhIE+mi6zRcScwdnpgJPLRYMEe4p/Cr6DOrA0G0GQ==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.295.0.tgz", + "integrity": "sha512-dU+nDJJKCyx/YBKeGgSuFM1okdoNVGWLTzrkPohPGy5+KnPaFCscrqRe2ni0ihQscguwSFXygV5SQoYNp1FGwA==", "optional": true, "dependencies": { - "@aws-sdk/credential-provider-env": "3.272.0", - "@aws-sdk/credential-provider-imds": "3.272.0", - "@aws-sdk/credential-provider-ini": "3.282.0", - "@aws-sdk/credential-provider-process": "3.272.0", - "@aws-sdk/credential-provider-sso": "3.282.0", - "@aws-sdk/credential-provider-web-identity": "3.272.0", - "@aws-sdk/property-provider": "3.272.0", - "@aws-sdk/shared-ini-file-loader": "3.272.0", - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/credential-provider-env": "3.295.0", + "@aws-sdk/credential-provider-imds": "3.295.0", + "@aws-sdk/credential-provider-ini": "3.295.0", + "@aws-sdk/credential-provider-process": "3.295.0", + "@aws-sdk/credential-provider-sso": "3.295.0", + "@aws-sdk/credential-provider-web-identity": "3.295.0", + "@aws-sdk/property-provider": "3.295.0", + "@aws-sdk/shared-ini-file-loader": "3.295.0", + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/credential-provider-process": { - "version": "3.272.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.272.0.tgz", - "integrity": "sha512-hiCAjWWm2PeBFp5cjkxqyam/XADjiS+e7GzwC34TbZn3LisS0uoweLojj9tD11NnnUhyhbLteUvu5+rotOLwrg==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.295.0.tgz", + "integrity": "sha512-efA41QAcKlb/hbDZVXnUApMPjOnu8Zj58o0WqHAdcpu7qSDzZdsmJ6dqknAbj14cyDjzXaexuN+wubGUAL9IoQ==", "optional": true, "dependencies": { - "@aws-sdk/property-provider": "3.272.0", - "@aws-sdk/shared-ini-file-loader": "3.272.0", - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/property-provider": "3.295.0", + "@aws-sdk/shared-ini-file-loader": "3.295.0", + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.282.0.tgz", - "integrity": "sha512-c4nibry7u0hkYRMi7+cWzdwYXfDDG+j3VYFxk2oOvU1VIJRyE6oeJqVaz3jgYLX9brHyrLJjuFCIJCUV/WXgIA==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.295.0.tgz", + "integrity": "sha512-cJoCLbg3ud3/NK7otcBHkRaPvdsVEyX9tryLIPuj8rgagFWneexVh4Kzs9k+PtRN764TjVFzITw99LxBf0fe1w==", "optional": true, "dependencies": { - "@aws-sdk/client-sso": "3.282.0", - "@aws-sdk/property-provider": "3.272.0", - "@aws-sdk/shared-ini-file-loader": "3.272.0", - "@aws-sdk/token-providers": "3.282.0", - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/client-sso": "3.295.0", + "@aws-sdk/property-provider": "3.295.0", + "@aws-sdk/shared-ini-file-loader": "3.295.0", + "@aws-sdk/token-providers": "3.295.0", + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.272.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.272.0.tgz", - "integrity": "sha512-ImrHMkcgneGa/HadHAQXPwOrX26sAKuB8qlMxZF/ZCM2B55u8deY+ZVkVuraeKb7YsahMGehPFOfRAF6mvFI5Q==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.295.0.tgz", + "integrity": "sha512-rBDhRYh4PiOnvz0M7AbYZZCiaPm5JDkM0xzGHEKKiW/A1wS2Gd2qbyEIK4APQ7vZMX+IJaSBBabfqm+vX5Y1kw==", "optional": true, "dependencies": { - "@aws-sdk/property-provider": "3.272.0", - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/property-provider": "3.295.0", + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/credential-providers": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.282.0.tgz", - "integrity": "sha512-/Pau2Ht15j26ibTSTaJHbx6wA3suNT0Qgu+++6ZUoVCeHL5ZN/otcoebsR/lOZTw8Fji7K5kl8TW41UNAE8s2w==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.295.0.tgz", + "integrity": "sha512-2SV5UFD0pyCkSP74z4MtPq1AT71uaQ/ERhLMms/kpwcyfWWI/e6m8rfSzSRsVjJOU3t08t8WGHOgaUiJrBh/DA==", "optional": true, "dependencies": { - "@aws-sdk/client-cognito-identity": "3.282.0", - "@aws-sdk/client-sso": "3.282.0", - "@aws-sdk/client-sts": "3.282.0", - "@aws-sdk/credential-provider-cognito-identity": "3.282.0", - "@aws-sdk/credential-provider-env": "3.272.0", - "@aws-sdk/credential-provider-imds": "3.272.0", - "@aws-sdk/credential-provider-ini": "3.282.0", - "@aws-sdk/credential-provider-node": "3.282.0", - "@aws-sdk/credential-provider-process": "3.272.0", - "@aws-sdk/credential-provider-sso": "3.282.0", - "@aws-sdk/credential-provider-web-identity": "3.272.0", - "@aws-sdk/property-provider": "3.272.0", - "@aws-sdk/shared-ini-file-loader": "3.272.0", - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/client-cognito-identity": "3.295.0", + "@aws-sdk/client-sso": "3.295.0", + "@aws-sdk/client-sts": "3.295.0", + "@aws-sdk/credential-provider-cognito-identity": "3.295.0", + "@aws-sdk/credential-provider-env": "3.295.0", + "@aws-sdk/credential-provider-imds": "3.295.0", + "@aws-sdk/credential-provider-ini": "3.295.0", + "@aws-sdk/credential-provider-node": "3.295.0", + "@aws-sdk/credential-provider-process": "3.295.0", + "@aws-sdk/credential-provider-sso": "3.295.0", + "@aws-sdk/credential-provider-web-identity": "3.295.0", + "@aws-sdk/property-provider": "3.295.0", + "@aws-sdk/shared-ini-file-loader": "3.295.0", + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/fetch-http-handler": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/fetch-http-handler/-/fetch-http-handler-3.282.0.tgz", - "integrity": "sha512-RTd53UzKtUucIEdVLGGgtlbVwp0QkOt3ZfHuA/A1lOH7meChSh1kz7B5z3p4HQDpXO+MQ1Y6Ble9Vg2fh1zwJQ==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/fetch-http-handler/-/fetch-http-handler-3.295.0.tgz", + "integrity": "sha512-xs274LSLeF2313dAaq7gvm/m0e0tb0/Bt2vew4Lj2zP6YNRtuNlStfSNhYHHuIkOqjTwLeAmKdK+cWFnXKQPTA==", "optional": true, "dependencies": { - "@aws-sdk/protocol-http": "3.282.0", - "@aws-sdk/querystring-builder": "3.272.0", - "@aws-sdk/types": "3.272.0", - "@aws-sdk/util-base64": "3.208.0", - "tslib": "^2.3.1" + "@aws-sdk/protocol-http": "3.295.0", + "@aws-sdk/querystring-builder": "3.295.0", + "@aws-sdk/types": "3.295.0", + "@aws-sdk/util-base64": "3.295.0", + "tslib": "^2.5.0" } }, "node_modules/@aws-sdk/hash-node": { - "version": "3.272.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/hash-node/-/hash-node-3.272.0.tgz", - "integrity": "sha512-40dwND+iAm3VtPHPZu7/+CIdVJFk2s0cWZt1lOiMPMSXycSYJ45wMk7Lly3uoqRx0uWfFK5iT2OCv+fJi5jTng==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/hash-node/-/hash-node-3.295.0.tgz", + "integrity": "sha512-jLq6QXUpvtYYu9+K8BECXpw7U52RBrewj/t/ALUVJsEhtwpx16K1WzMqwcVhkQ8mc/xQiki/T4eFSThODZAlcw==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.272.0", - "@aws-sdk/util-buffer-from": "3.208.0", - "@aws-sdk/util-utf8": "3.254.0", - "tslib": "^2.3.1" + "@aws-sdk/types": "3.295.0", + "@aws-sdk/util-buffer-from": "3.295.0", + "@aws-sdk/util-utf8": "3.295.0", + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/invalid-dependency": { - "version": "3.272.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/invalid-dependency/-/invalid-dependency-3.272.0.tgz", - "integrity": "sha512-ysW6wbjl1Y78txHUQ/Tldj2Rg1BI7rpMO9B9xAF6yAX3mQ7t6SUPQG/ewOGvH2208NBIl3qP5e/hDf0Q6r/1iw==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/invalid-dependency/-/invalid-dependency-3.295.0.tgz", + "integrity": "sha512-ctXFKW4qnhLqZ0+qyEK1l0TOYQYwd2+vjj6wdjAiHuKoH6yIMqJ97LOT7oq3drvMQbnXa4I2jCOSFVuNSnzJ7Q==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" } }, "node_modules/@aws-sdk/is-array-buffer": { - "version": "3.201.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/is-array-buffer/-/is-array-buffer-3.201.0.tgz", - "integrity": "sha512-UPez5qLh3dNgt0DYnPD/q0mVJY84rA17QE26hVNOW3fAji8W2wrwrxdacWOxyXvlxWsVRcKmr+lay1MDqpAMfg==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/is-array-buffer/-/is-array-buffer-3.295.0.tgz", + "integrity": "sha512-SCIt10cr5dud7hvwveU4wkLjvkGssJ3GrcbHCds2NwI+JHmpcaaNYLAqi305JAuT29T36U5ssTFDSmrrEOcfag==", "optional": true, "dependencies": { - "tslib": "^2.3.1" + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/middleware-content-length": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-content-length/-/middleware-content-length-3.282.0.tgz", - "integrity": "sha512-SDgMLRRTMr9LlHSNk4bXUXynYnkT4oNMqE+FxhjsdbT8hK36eS4AadM58R7nPwgjR3EuWRW4ZRRawLWatpWspA==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-content-length/-/middleware-content-length-3.295.0.tgz", + "integrity": "sha512-XzrVPuO1JwxJx5PFHP9eMZLP9zyQxPZ8PM9gTWdOgoc1BMtxCkDZ3HLOnJtcfmfbz8nwSt2/H+wlBEXaRrf7Fg==", "optional": true, "dependencies": { - "@aws-sdk/protocol-http": "3.282.0", - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/protocol-http": "3.295.0", + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/middleware-endpoint": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-endpoint/-/middleware-endpoint-3.282.0.tgz", - "integrity": "sha512-8U9Mv/Sbdo1KI6/ip7IIUdBl5pgmalFbfkYAyO+AtmkEvawI9ipdWFs5HB0Dwd1BGVup5choY72Ik/7sCAAFTQ==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-endpoint/-/middleware-endpoint-3.295.0.tgz", + "integrity": "sha512-MFRW6XyZABAOeFPu2CC37h+ol6ADaKs8fqqJrv9gtNb13r6c0UeztQFwI6V3tLlZwX7zzH7HcwYFKyks5VO6Xw==", "optional": true, "dependencies": { - "@aws-sdk/middleware-serde": "3.272.0", - "@aws-sdk/protocol-http": "3.282.0", - "@aws-sdk/signature-v4": "3.282.0", - "@aws-sdk/types": "3.272.0", - "@aws-sdk/url-parser": "3.272.0", - "@aws-sdk/util-config-provider": "3.208.0", - "@aws-sdk/util-middleware": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/middleware-serde": "3.295.0", + "@aws-sdk/protocol-http": "3.295.0", + "@aws-sdk/signature-v4": "3.295.0", + "@aws-sdk/types": "3.295.0", + "@aws-sdk/url-parser": "3.295.0", + "@aws-sdk/util-config-provider": "3.295.0", + "@aws-sdk/util-middleware": "3.295.0", + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/middleware-host-header": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.282.0.tgz", - "integrity": "sha512-90dfYow4zh4tCatTOnqB3nE/dIAucQLZnMqwN/WBPu0fUqjymzpsNkPchqWBPnSWdNE8w3PiKMqqD9rjYwqw4Q==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.295.0.tgz", + "integrity": "sha512-CjdC8eCILSuNHTF2AZOtFta5lMvLMM3bXBTto0LKYeHQixgBHmRSgcShfBTiWEPgIgeNSFEjMbKX6bLnHSnODg==", "optional": true, "dependencies": { - "@aws-sdk/protocol-http": "3.282.0", - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/protocol-http": "3.295.0", + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/middleware-logger": { - "version": "3.272.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.272.0.tgz", - "integrity": "sha512-u2SQ0hWrFwxbxxYMG5uMEgf01pQY5jauK/LYWgGIvuCmFgiyRQQP3oN7kkmsxnS9MWmNmhbyQguX2NY02s5e9w==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.295.0.tgz", + "integrity": "sha512-dbv0VTA7Dh6ZCkmCs0U7/ssZiDtHDI7Bq3zab+RxEyLEE4wr73bW6occq579U/QQJHOZQ6EBdvYig8ntRNlzVg==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/middleware-recursion-detection": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.282.0.tgz", - "integrity": "sha512-cSLq/daEaTEucbP/TgAXIOcpwLu7Bfw3VGzH1U56ngDjI4KWvUheF16JiB6OqKQXduPBPsdZ9dVmkDVKddmCRw==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.295.0.tgz", + "integrity": "sha512-9Wjb8Y7H0ctL8gIKtGFwXhpHb3c2UGGi2P9I+p2PJwW08rDnMlOpUItY0v49SbZ+6uct1VNBs6iJ+jkv0h5MEQ==", "optional": true, "dependencies": { - "@aws-sdk/protocol-http": "3.282.0", - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/protocol-http": "3.295.0", + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/middleware-retry": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-retry/-/middleware-retry-3.282.0.tgz", - "integrity": "sha512-3+0M1GP9o480IdqHVZbkhTgge63uKhDFlS6cQznpNGj0eIuQPhXRnlEz2/rma0INUqFm6+7qJ5yzHR4WQbfHpw==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-retry/-/middleware-retry-3.295.0.tgz", + "integrity": "sha512-IdVX86VaDSSPcGI1JJM8lffabOMmGC9TUpskKkKdFnLW6eKtFohye+hlf2h6Y/2wdvoqCdi6XZyQX9WPJHiHtw==", "optional": true, "dependencies": { - "@aws-sdk/protocol-http": "3.282.0", - "@aws-sdk/service-error-classification": "3.272.0", - "@aws-sdk/types": "3.272.0", - "@aws-sdk/util-middleware": "3.272.0", - "@aws-sdk/util-retry": "3.272.0", - "tslib": "^2.3.1", + "@aws-sdk/protocol-http": "3.295.0", + "@aws-sdk/service-error-classification": "3.295.0", + "@aws-sdk/types": "3.295.0", + "@aws-sdk/util-middleware": "3.295.0", + "@aws-sdk/util-retry": "3.295.0", + "tslib": "^2.5.0", "uuid": "^8.3.2" }, "engines": { @@ -667,440 +832,441 @@ } }, "node_modules/@aws-sdk/middleware-sdk-sts": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.282.0.tgz", - "integrity": "sha512-Qe20mtJcF6lxt7280FhTFD2IpBDn39MEXmbm/zIkXR2/cAmvji8YhcxhNrq1l7XiuMM6SokBDC/f3dlF1oOC6g==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.295.0.tgz", + "integrity": "sha512-QTHR+ZXAmii8XsbdRrqJWn6LVeGiRcFfGlniIb1YEjw1p2FU5kpayq8N1SLLtj3JWmE61Bpn0J+LAQmfjbCqFA==", "optional": true, "dependencies": { - "@aws-sdk/middleware-signing": "3.282.0", - "@aws-sdk/property-provider": "3.272.0", - "@aws-sdk/protocol-http": "3.282.0", - "@aws-sdk/signature-v4": "3.282.0", - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/middleware-signing": "3.295.0", + "@aws-sdk/property-provider": "3.295.0", + "@aws-sdk/protocol-http": "3.295.0", + "@aws-sdk/signature-v4": "3.295.0", + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/middleware-serde": { - "version": "3.272.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-serde/-/middleware-serde-3.272.0.tgz", - "integrity": "sha512-kW1uOxgPSwtXPB5rm3QLdWomu42lkYpQL94tM1BjyFOWmBLO2lQhk5a7Dw6HkTozT9a+vxtscLChRa6KZe61Hw==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-serde/-/middleware-serde-3.295.0.tgz", + "integrity": "sha512-LAKtKNKdu6Si7rmLatAq87LSa27mR6HUZ7tZHD2E4SQWOoNpS4ikKfUfATkbjC2GOfbrBYmFmQgBvpghYYZ3jw==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/middleware-signing": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.282.0.tgz", - "integrity": "sha512-eE5qMDcqqxZPdSwybUEph/knrA2j2cHjW+B2ddROw3Ojg0XLjep5hOhithAudgBREQhYF9pdsBr6mUMynUIrKw==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.295.0.tgz", + "integrity": "sha512-LcNzGqtpo9sdWJ9mKtgjragncbin/Ynbz/pklH/HcIIi45w8ZVrhLBpW1iQZ0MBKyDacAAeWtXxKHy55DkHlvg==", "optional": true, "dependencies": { - "@aws-sdk/property-provider": "3.272.0", - "@aws-sdk/protocol-http": "3.282.0", - "@aws-sdk/signature-v4": "3.282.0", - "@aws-sdk/types": "3.272.0", - "@aws-sdk/util-middleware": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/property-provider": "3.295.0", + "@aws-sdk/protocol-http": "3.295.0", + "@aws-sdk/signature-v4": "3.295.0", + "@aws-sdk/types": "3.295.0", + "@aws-sdk/util-middleware": "3.295.0", + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/middleware-stack": { - "version": "3.272.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-stack/-/middleware-stack-3.272.0.tgz", - "integrity": "sha512-jhwhknnPBGhfXAGV5GXUWfEhDFoP/DN8MPCO2yC5OAxyp6oVJ8lTPLkZYMTW5VL0c0eG44dXpF4Ib01V+PlDrQ==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-stack/-/middleware-stack-3.295.0.tgz", + "integrity": "sha512-65HahosleRbpNgu6/XkABcrBmZHudRYTNpyKRfSY18QPKVQv3PRgRqv/goHrc6DHo8cxAliBoMciN88Ali1ufQ==", "optional": true, "dependencies": { - "tslib": "^2.3.1" + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.282.0.tgz", - "integrity": "sha512-P1ealsSrUALo0w0Qu5nBKsNQwsmqIfsoNtFWpaznjIcXE5rRMlZL69zb0KnGbQCBfEXsgaMOWjeGT8I3/XbOHQ==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.295.0.tgz", + "integrity": "sha512-11MGXHFxmXgQx6aAFshLqHm3US7awXMP1Hq3IAu6j+GXSdkpkIojh/LlzRbSUftAhh23C5oQpgOkqs6fox4xCw==", "optional": true, "dependencies": { - "@aws-sdk/protocol-http": "3.282.0", - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/protocol-http": "3.295.0", + "@aws-sdk/types": "3.295.0", + "@aws-sdk/util-endpoints": "3.295.0", + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/node-config-provider": { - "version": "3.272.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/node-config-provider/-/node-config-provider-3.272.0.tgz", - "integrity": "sha512-YYCIBh9g1EQo7hm2l22HX5Yr9RoPQ2RCvhzKvF1n1e8t1QH4iObQrYUtqHG4khcm64Cft8C5MwZmgzHbya5Z6Q==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/node-config-provider/-/node-config-provider-3.295.0.tgz", + "integrity": "sha512-6lkCmPMmXn6CF1qQHkE/Ii88ge/Mz9MWX+Krj3ICdBRwdMqm4LGzc9qG+bJeqbVI3tPO3djmL+b4SW4a3pvKsw==", "optional": true, "dependencies": { - "@aws-sdk/property-provider": "3.272.0", - "@aws-sdk/shared-ini-file-loader": "3.272.0", - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/property-provider": "3.295.0", + "@aws-sdk/shared-ini-file-loader": "3.295.0", + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/node-http-handler": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/node-http-handler/-/node-http-handler-3.282.0.tgz", - "integrity": "sha512-LIA4lsSKA/l1kTR5ERkJG2gARveB7Y40MR6yDwtIuhXeVu7Xo9m4BJFanCYIbyc093W0T53x438bwoBR+R+/fw==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/node-http-handler/-/node-http-handler-3.295.0.tgz", + "integrity": "sha512-Ga3vp/IY3LgzTdlSTAcxncYebE0lpQAdgxnko+z1i67OaI8DqNlTL8vdYBoHDaFOb9E6ErShLytVoHAEuJ5TpA==", "optional": true, "dependencies": { - "@aws-sdk/abort-controller": "3.272.0", - "@aws-sdk/protocol-http": "3.282.0", - "@aws-sdk/querystring-builder": "3.272.0", - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/abort-controller": "3.295.0", + "@aws-sdk/protocol-http": "3.295.0", + "@aws-sdk/querystring-builder": "3.295.0", + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/property-provider": { - "version": "3.272.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/property-provider/-/property-provider-3.272.0.tgz", - "integrity": "sha512-V1pZTaH5eqpAt8O8CzbItHhOtzIfFuWymvwZFkAtwKuaHpnl7jjrTouV482zoq8AD/fF+VVSshwBKYA7bhidIw==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/property-provider/-/property-provider-3.295.0.tgz", + "integrity": "sha512-5hxI1W36JWugYaBng7hKH2IxDtNohk0KMsz6wgyHVxTcsrO9VohlYa+5rHntmt3SbQAyy7n5ft9/vb1Nb5TGCw==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/protocol-http": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/protocol-http/-/protocol-http-3.282.0.tgz", - "integrity": "sha512-aOPv5DhsbG06WKfeh2g0H8RGnaeI8pLhaA+Mq1BvzXcghhlDu+FM9K/GjC/f1lWk1UNryfevOR7SdQm95ciHQg==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/protocol-http/-/protocol-http-3.295.0.tgz", + "integrity": "sha512-mDl1jfNDtOFXKQrkiTY0dbTwC9LLjmmAmE8TpxXC1v6JbOihVrARiyPdumZWP4J/71YAim1ASS6JlQHw/GuAqg==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/querystring-builder": { - "version": "3.272.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-builder/-/querystring-builder-3.272.0.tgz", - "integrity": "sha512-ndo++7GkdCj5tBXE6rGcITpSpZS4PfyV38wntGYAlj9liL1omk3bLZRY6uzqqkJpVHqbg2fD7O2qHNItzZgqhw==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-builder/-/querystring-builder-3.295.0.tgz", + "integrity": "sha512-zgFb2pSkxOCHVusZpPjQVIwmQZf59MQEYJETk42OKaigItGTHjap9DrFzKo6+SrHeyEpJLxlZKSz5up4Hulwdw==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.272.0", - "@aws-sdk/util-uri-escape": "3.201.0", - "tslib": "^2.3.1" + "@aws-sdk/types": "3.295.0", + "@aws-sdk/util-uri-escape": "3.295.0", + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/querystring-parser": { - "version": "3.272.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-parser/-/querystring-parser-3.272.0.tgz", - "integrity": "sha512-5oS4/9n6N1LZW9tI3qq/0GnCuWoOXRgcHVB+AJLRBvDbEe+GI+C/xK1tKLsfpDNgsQJHc4IPQoIt4megyZ/1+A==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-parser/-/querystring-parser-3.295.0.tgz", + "integrity": "sha512-bcm8IBHmflH1e6EHznScJbfvAmNZqwZtC6QaynNk6no/YYKr5Swm+GHqxurKBm86qCYIOoSvdoq8tyhUjXnh4Q==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/service-error-classification": { - "version": "3.272.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/service-error-classification/-/service-error-classification-3.272.0.tgz", - "integrity": "sha512-REoltM1LK9byyIufLqx9znhSolPcHQgVHIA2S0zu5sdt5qER4OubkLAXuo4MBbisUTmh8VOOvIyUb5ijZCXq1w==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/service-error-classification/-/service-error-classification-3.295.0.tgz", + "integrity": "sha512-zqGxXkZUxPD7E0FJXKHZLuJwr02zg/Ux4d+elT/MUTYT9eKupmG2S5586/hZdjUxGGA7gmMMJr92mjrLVJUAkQ==", "optional": true, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/shared-ini-file-loader": { - "version": "3.272.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/shared-ini-file-loader/-/shared-ini-file-loader-3.272.0.tgz", - "integrity": "sha512-lzFPohp5sy2XvwFjZIzLVCRpC0i5cwBiaXmFzXYQZJm6FSCszHO4ax+m9yrtlyVFF/2YPWl+/bzNthy4aJtseA==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/shared-ini-file-loader/-/shared-ini-file-loader-3.295.0.tgz", + "integrity": "sha512-LF9+jk37/VPoIyadeb+Ls0Tqda6dauo3uG7FDfg7qdiOpdyNRuFaIZE//MTSG5mk4ExAwjkFsnslZaw31hbbUw==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/signature-v4": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4/-/signature-v4-3.282.0.tgz", - "integrity": "sha512-rnSL3UyF/No7+O2EMtN1sTCiqL1a+odbfnfo3wCSl8DH5PEYINt2kZgVEvT1Fgaffk1pUggBBOZoR+arPIIDJA==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4/-/signature-v4-3.295.0.tgz", + "integrity": "sha512-yS00sIwWEnPB4aHZWJZpXVL2/wbwrymxbPZw/Xq0JXbR9+RXhzENBqw7C3d7E11K1xLnoTYlVqcJhNuNXgyeZg==", "optional": true, "dependencies": { - "@aws-sdk/is-array-buffer": "3.201.0", - "@aws-sdk/types": "3.272.0", - "@aws-sdk/util-hex-encoding": "3.201.0", - "@aws-sdk/util-middleware": "3.272.0", - "@aws-sdk/util-uri-escape": "3.201.0", - "@aws-sdk/util-utf8": "3.254.0", - "tslib": "^2.3.1" + "@aws-sdk/is-array-buffer": "3.295.0", + "@aws-sdk/types": "3.295.0", + "@aws-sdk/util-hex-encoding": "3.295.0", + "@aws-sdk/util-middleware": "3.295.0", + "@aws-sdk/util-uri-escape": "3.295.0", + "@aws-sdk/util-utf8": "3.295.0", + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/smithy-client": { - "version": "3.279.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/smithy-client/-/smithy-client-3.279.0.tgz", - "integrity": "sha512-ZcYWUQDGAYN6NXRpJuSn46PetrpPCA6TrDVwP9+3pERzTXZ66npXoG2XhHjNrOXy/Ted5A3OxKrM4/zLu9tK3A==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/smithy-client/-/smithy-client-3.295.0.tgz", + "integrity": "sha512-6Ifq+szMeX6MjWkEEiXvQGm7moY5Wt6WfFi+dMLkZmPdOEWYB0Cr0EBpY605WHWGz702CpFLvM/z6rUkvtak5g==", "optional": true, "dependencies": { - "@aws-sdk/middleware-stack": "3.272.0", - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/middleware-stack": "3.295.0", + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/token-providers": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.282.0.tgz", - "integrity": "sha512-Qk/D6i+Hpc0fp/2SRHbfJeKPgUIugzsmye3NL0OV1bqd1Y40dW5LT4u67VcZHwqxzYDKe6Eo+7NHJu7qfvwhog==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.295.0.tgz", + "integrity": "sha512-/6PsplDacgBoQxFBbKYMW9ZlEeTHHdAm+xE6V+qjEsc0YXy32LwuFllfihryXLjWftrC3kr8EiehLU6d+9JaKA==", "optional": true, "dependencies": { - "@aws-sdk/client-sso-oidc": "3.282.0", - "@aws-sdk/property-provider": "3.272.0", - "@aws-sdk/shared-ini-file-loader": "3.272.0", - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/client-sso-oidc": "3.295.0", + "@aws-sdk/property-provider": "3.295.0", + "@aws-sdk/shared-ini-file-loader": "3.295.0", + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/types": { - "version": "3.272.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.272.0.tgz", - "integrity": "sha512-MmmL6vxMGP5Bsi+4wRx4mxYlU/LX6M0noOXrDh/x5FfG7/4ZOar/nDxqDadhJtNM88cuWVHZWY59P54JzkGWmA==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.295.0.tgz", + "integrity": "sha512-flwibucy5+PshdFLeMCClMqV3eFmjUDhcLkEUeQvVgyhGxJPIrU3ntGAfqz27bvk47ZVX5TUdCG5JdxuUaRO+A==", "optional": true, "dependencies": { - "tslib": "^2.3.1" + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/url-parser": { - "version": "3.272.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/url-parser/-/url-parser-3.272.0.tgz", - "integrity": "sha512-vX/Tx02PlnQ/Kgtf5TnrNDHPNbY+amLZjW0Z1d9vzAvSZhQ4i9Y18yxoRDIaDTCNVRDjdhV8iuctW+05PB5JtQ==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/url-parser/-/url-parser-3.295.0.tgz", + "integrity": "sha512-hev5gbi+EWHLaFNgVpoNeNTaJpqfa9ev0SvqgvCPqGlIdUnt3cP9t1Mc8jvx2kUk8ebPtrrq6cp8ZslfxoFeVA==", "optional": true, "dependencies": { - "@aws-sdk/querystring-parser": "3.272.0", - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/querystring-parser": "3.295.0", + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" } }, "node_modules/@aws-sdk/util-base64": { - "version": "3.208.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-base64/-/util-base64-3.208.0.tgz", - "integrity": "sha512-PQniZph5A6N7uuEOQi+1hnMz/FSOK/8kMFyFO+4DgA1dZ5pcKcn5wiFwHkcTb/BsgVqQa3Jx0VHNnvhlS8JyTg==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-base64/-/util-base64-3.295.0.tgz", + "integrity": "sha512-z1r40BsBiOTALnzASvLb4qutGwPpL+jH2UKTCV5WJLXZFMzRnpZaRfeZGE8lMJ/i0+jv9H9G1FmVzE8UgB4rhw==", "optional": true, "dependencies": { - "@aws-sdk/util-buffer-from": "3.208.0", - "tslib": "^2.3.1" + "@aws-sdk/util-buffer-from": "3.295.0", + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/util-body-length-browser": { - "version": "3.188.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-body-length-browser/-/util-body-length-browser-3.188.0.tgz", - "integrity": "sha512-8VpnwFWXhnZ/iRSl9mTf+VKOX9wDE8QtN4bj9pBfxwf90H1X7E8T6NkiZD3k+HubYf2J94e7DbeHs7fuCPW5Qg==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-body-length-browser/-/util-body-length-browser-3.295.0.tgz", + "integrity": "sha512-NbG4/RSHV1VueStPRclSo5zRjNUmcDlNAs29sniZF+YaN0+Ad7hEdu/YgJw39shBfUaurz2Wv0pufU3cxE5Tng==", "optional": true, "dependencies": { - "tslib": "^2.3.1" + "tslib": "^2.5.0" } }, "node_modules/@aws-sdk/util-body-length-node": { - "version": "3.208.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-body-length-node/-/util-body-length-node-3.208.0.tgz", - "integrity": "sha512-3zj50e5g7t/MQf53SsuuSf0hEELzMtD8RX8C76f12OSRo2Bca4FLLYHe0TZbxcfQHom8/hOaeZEyTyMogMglqg==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-body-length-node/-/util-body-length-node-3.295.0.tgz", + "integrity": "sha512-dvGf8VBmrT66lM0n6P/h7wnlHS4Atafyivyl8f4TUCMvRdpqryvvrtnX6yYcq3T7VKQmas/2SOlgDvcrhGXaiw==", "optional": true, "dependencies": { - "tslib": "^2.3.1" + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/util-buffer-from": { - "version": "3.208.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-buffer-from/-/util-buffer-from-3.208.0.tgz", - "integrity": "sha512-7L0XUixNEFcLUGPeBF35enCvB9Xl+K6SQsmbrPk1P3mlV9mguWSDQqbOBwY1Ir0OVbD6H/ZOQU7hI/9RtRI0Zw==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-buffer-from/-/util-buffer-from-3.295.0.tgz", + "integrity": "sha512-5ezVEITQnrQKn+CU9qfZHgRp2nrrbX0Clmlm9aiNjAEQEPHY33tWl0t6n8h8yU+IpGiNRMWBVC4aSJaE5NA1mA==", "optional": true, "dependencies": { - "@aws-sdk/is-array-buffer": "3.201.0", - "tslib": "^2.3.1" + "@aws-sdk/is-array-buffer": "3.295.0", + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/util-config-provider": { - "version": "3.208.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-config-provider/-/util-config-provider-3.208.0.tgz", - "integrity": "sha512-DSRqwrERUsT34ug+anlMBIFooBEGwM8GejC7q00Y/9IPrQy50KnG5PW2NiTjuLKNi7pdEOlwTSEocJE15eDZIg==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-config-provider/-/util-config-provider-3.295.0.tgz", + "integrity": "sha512-/5Dl1aV2yI8YQjqwmg4RTnl/E9NmNsx7HIwBZt+dTcOrM0LMUwczQBFFcLyqCj/qv5y+VsvLoAAA/OiBT7hb3w==", "optional": true, "dependencies": { - "tslib": "^2.3.1" + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/util-defaults-mode-browser": { - "version": "3.279.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-defaults-mode-browser/-/util-defaults-mode-browser-3.279.0.tgz", - "integrity": "sha512-RnchYRrpapTT5Hu23LOfk6e8RMVq0kUzho6xA6TJj1a4uGxkcRMvgzPipCq1P5uHu0mrkQBg9pGPEVNOUs38/Q==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-defaults-mode-browser/-/util-defaults-mode-browser-3.295.0.tgz", + "integrity": "sha512-QqVyl4Sxi9Umn2+TdhZR8fHQRWWs2361JCylig1GzH+ud+8jinDS6tLtWxhzrea2XdKGb4xqjTC4AhCuBqgSmA==", "optional": true, "dependencies": { - "@aws-sdk/property-provider": "3.272.0", - "@aws-sdk/types": "3.272.0", + "@aws-sdk/property-provider": "3.295.0", + "@aws-sdk/types": "3.295.0", "bowser": "^2.11.0", - "tslib": "^2.3.1" + "tslib": "^2.5.0" }, "engines": { "node": ">= 10.0.0" } }, "node_modules/@aws-sdk/util-defaults-mode-node": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-defaults-mode-node/-/util-defaults-mode-node-3.282.0.tgz", - "integrity": "sha512-D1BlFoA7ZMeK2diDUWFx1xBFrSaJuBZMRBuWbnbT9AnRYNCsASZ8DRU1KkZ8LuFQIwmZz94P9q683emYnZBhiw==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-defaults-mode-node/-/util-defaults-mode-node-3.295.0.tgz", + "integrity": "sha512-R1e94v6HMsUec8/P2tJmab5fYsT9X3+Kh1rMzCEA27V+kAD88eKStzE26Yb1kQDAC+Fg3Fe1KS1bg4dmQKUSVg==", "optional": true, "dependencies": { - "@aws-sdk/config-resolver": "3.282.0", - "@aws-sdk/credential-provider-imds": "3.272.0", - "@aws-sdk/node-config-provider": "3.272.0", - "@aws-sdk/property-provider": "3.272.0", - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/config-resolver": "3.295.0", + "@aws-sdk/credential-provider-imds": "3.295.0", + "@aws-sdk/node-config-provider": "3.295.0", + "@aws-sdk/property-provider": "3.295.0", + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" }, "engines": { "node": ">= 10.0.0" } }, "node_modules/@aws-sdk/util-endpoints": { - "version": "3.272.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.272.0.tgz", - "integrity": "sha512-c4MPUaJt2G6gGpoiwIOqDfUa98c1J63RpYvf/spQEKOtC/tF5Gfqlxuq8FnAl5lHnrqj1B9ZXLLxFhHtDR0IiQ==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.295.0.tgz", + "integrity": "sha512-WZR6jAD++7Wb6ER1SM/U82xU+OVWihcc8V90AzTWyDb0JPeKuogwWokV1aHXiGaQGbWULr1wY1R3wthhvEs3Bg==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/util-hex-encoding": { - "version": "3.201.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-hex-encoding/-/util-hex-encoding-3.201.0.tgz", - "integrity": "sha512-7t1vR1pVxKx0motd3X9rI3m/xNp78p3sHtP5yo4NP4ARpxyJ0fokBomY8ScaH2D/B+U5o9ARxldJUdMqyBlJcA==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-hex-encoding/-/util-hex-encoding-3.295.0.tgz", + "integrity": "sha512-XJcoVo41kHzhe28PBm/rqt5mdCp8R6abwiW9ug1dA6FOoPUO8kBUxDv6xaOmA2hfRvd2ocFfBXaUCBqUowkGcQ==", "optional": true, "dependencies": { - "tslib": "^2.3.1" + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/util-locate-window": { - "version": "3.208.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.208.0.tgz", - "integrity": "sha512-iua1A2+P7JJEDHVgvXrRJSvsnzG7stYSGQnBVphIUlemwl6nN5D+QrgbjECtrbxRz8asYFHSzhdhECqN+tFiBg==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.295.0.tgz", + "integrity": "sha512-d/s+zhUx5Kh4l/ecMP/TBjzp1GR/g89Q4nWH6+wH5WgdHsK+LG+vmsk6mVNuP/8wsCofYG4NBqp5Ulbztbm9QA==", "optional": true, "dependencies": { - "tslib": "^2.3.1" + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/util-middleware": { - "version": "3.272.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-middleware/-/util-middleware-3.272.0.tgz", - "integrity": "sha512-Abw8m30arbwxqmeMMha5J11ESpHUNmCeSqSzE8/C4B8jZQtHY4kq7f+upzcNIQ11lsd+uzBEzNG3+dDRi0XOJQ==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-middleware/-/util-middleware-3.295.0.tgz", + "integrity": "sha512-t6UdduLHV97IRZmd1YA0v5HCwerz+OXxDF8lLK0G7qihde0jv6tq5w8fTTjgehDFKM0UGUiaahOtjEcRK7F2Aw==", "optional": true, "dependencies": { - "tslib": "^2.3.1" + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/util-retry": { - "version": "3.272.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-retry/-/util-retry-3.272.0.tgz", - "integrity": "sha512-Ngha5414LR4gRHURVKC9ZYXsEJhMkm+SJ+44wlzOhavglfdcKKPUsibz5cKY1jpUV7oKECwaxHWpBB8r6h+hOg==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-retry/-/util-retry-3.295.0.tgz", + "integrity": "sha512-3xp3A5XtPWGsN9aLuzM3mB4hpM3nZJ5JJiGFgUXu/CTP2ahipbVbMwtRpIUjYDh1kvdjoaDJatEVJ7JhJrXFew==", "optional": true, "dependencies": { - "@aws-sdk/service-error-classification": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/service-error-classification": "3.295.0", + "tslib": "^2.5.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@aws-sdk/util-uri-escape": { - "version": "3.201.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-uri-escape/-/util-uri-escape-3.201.0.tgz", - "integrity": "sha512-TeTWbGx4LU2c5rx0obHeDFeO9HvwYwQtMh1yniBz00pQb6Qt6YVOETVQikRZ+XRQwEyCg/dA375UplIpiy54mA==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-uri-escape/-/util-uri-escape-3.295.0.tgz", + "integrity": "sha512-1H5DcyIoXF8XcPBWf7wzHt0l+TW2EoR8Oq4gsVrPTQkHMTVclC2Yn8EF3gc4arwVBzwLulI9LMBE2L8fexGfTQ==", "optional": true, "dependencies": { - "tslib": "^2.3.1" + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@aws-sdk/util-user-agent-browser": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.282.0.tgz", - "integrity": "sha512-Z639oyTa5fZfyi4Xr64+eiAwBCxfpe9Op4Vhnr1z/RwonQM/qywydv6Ttpeq1q5uQ0nG4wTkOMpfh39g+VqIgw==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.295.0.tgz", + "integrity": "sha512-lSU80r6yMwSDLkBZ0900G/kHLz/QgXewPXz56Xnq7NHWu7YliY6fzT1zWHPRGwcfCctTGMTWw+10ZSu/0Xv9nw==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.272.0", + "@aws-sdk/types": "3.295.0", "bowser": "^2.11.0", - "tslib": "^2.3.1" + "tslib": "^2.5.0" } }, "node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.282.0.tgz", - "integrity": "sha512-GSOdWNmzEd554wR9HBrgeYptKBOybveVwUkd6ws+YTdCOz4xD5Gga+I5JomKkcMEUVdBrJnYVUtq7ZsJy2f11w==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.295.0.tgz", + "integrity": "sha512-EVt/4nWTYLbS6llhjE4sn2tn1mBlifyK6ezAse5kr6boNG3dJt6Y7gHAXXglkmblw2bflxqgOaKj5YCcZFUSyQ==", "optional": true, "dependencies": { - "@aws-sdk/node-config-provider": "3.272.0", - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/node-config-provider": "3.295.0", + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" @@ -1115,13 +1281,13 @@ } }, "node_modules/@aws-sdk/util-utf8": { - "version": "3.254.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8/-/util-utf8-3.254.0.tgz", - "integrity": "sha512-14Kso/eIt5/qfIBmhEL9L1IfyUqswjSTqO2mY7KOzUZ9SZbwn3rpxmtkhmATkRjD7XIlLKaxBkI7tU9Zjzj8Kw==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8/-/util-utf8-3.295.0.tgz", + "integrity": "sha512-ITN8v3F63ZkA4sdmCtSbS/mhav4F0MEAiXDAUXtMJLNqVtaVcyQST4i9vNmPpIVthAPAtP0QjyF2tq/Di8bxtQ==", "optional": true, "dependencies": { - "@aws-sdk/util-buffer-from": "3.208.0", - "tslib": "^2.3.1" + "@aws-sdk/util-buffer-from": "3.295.0", + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" @@ -1158,21 +1324,21 @@ } }, "node_modules/@babel/core": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.0.tgz", - "integrity": "sha512-PuxUbxcW6ZYe656yL3EAhpy7qXKq0DmYsrJLpbB8XrsCP9Nm+XCg9XFMb5vIDliPD7+U/+M+QJlH17XOcB7eXA==", + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.3.tgz", + "integrity": "sha512-qIJONzoa/qiHghnm0l1n4i/6IIziDpzqc36FBs4pzMhDUraHqponwJLiAKm1hGLP3OSB/TVNz6rMwVGpwxxySw==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.21.0", + "@babel/generator": "^7.21.3", "@babel/helper-compilation-targets": "^7.20.7", - "@babel/helper-module-transforms": "^7.21.0", + "@babel/helper-module-transforms": "^7.21.2", "@babel/helpers": "^7.21.0", - "@babel/parser": "^7.21.0", + "@babel/parser": "^7.21.3", "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.0", - "@babel/types": "^7.21.0", + "@babel/traverse": "^7.21.3", + "@babel/types": "^7.21.3", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -1203,12 +1369,12 @@ } }, "node_modules/@babel/generator": { - "version": "7.21.1", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.1.tgz", - "integrity": "sha512-1lT45bAYlQhFn/BHivJs43AiW2rg3/UbLyShGfF3C0KmHvO5fSghWd5kBJy30kpRRucGzXStvnnCFniCR2kXAA==", + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.3.tgz", + "integrity": "sha512-QS3iR1GYC/YGUnW7IdggFeN5c1poPUurnGttOV/bZgPGV+izC/D8HnD6DLwod0fsatNyVn1G3EVWMYIF0nHbeA==", "dev": true, "dependencies": { - "@babel/types": "^7.21.0", + "@babel/types": "^7.21.3", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -1250,6 +1416,15 @@ "@babel/core": "^7.0.0" } }, + "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, "node_modules/@babel/helper-compilation-targets/node_modules/semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -1259,6 +1434,12 @@ "semver": "bin/semver.js" } }, + "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, "node_modules/@babel/helper-environment-visitor": { "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", @@ -1484,9 +1665,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.21.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.2.tgz", - "integrity": "sha512-URpaIJQwEkEC2T9Kn+Ai6Xe/02iNaVCuT/PtoRz3GPVJVDpPd7mLo+VddTbhCRU9TXqW5mSrQfXZyi8kDKOVpQ==", + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.3.tgz", + "integrity": "sha512-lobG0d7aOfQRXh8AyklEAgZGvA4FShxo6xQbUrrT/cNBPUdIDojlokwJsQyCC/eKia7ifqM0yP+2DRZ4WKw2RQ==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -1687,19 +1868,19 @@ } }, "node_modules/@babel/traverse": { - "version": "7.21.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.2.tgz", - "integrity": "sha512-ts5FFU/dSUPS13tv8XiEObDu9K+iagEKME9kAbaP7r0Y9KtZJZ+NGndDvWoRAYNpeWafbpFeki3q9QoMD6gxyw==", + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.3.tgz", + "integrity": "sha512-XLyopNeaTancVitYZe2MlUEvgKb6YVVPXzofHgqHijCImG33b/uTurMS488ht/Hbsb2XK3U2BnSTxKVNGV3nGQ==", "dev": true, "dependencies": { "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.21.1", + "@babel/generator": "^7.21.3", "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-function-name": "^7.21.0", "@babel/helper-hoist-variables": "^7.18.6", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.21.2", - "@babel/types": "^7.21.2", + "@babel/parser": "^7.21.3", + "@babel/types": "^7.21.3", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -1717,9 +1898,9 @@ } }, "node_modules/@babel/types": { - "version": "7.21.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.2.tgz", - "integrity": "sha512-3wRZSs7jiFaB8AjxiiD+VqN5DTG2iRvJGQ+qYFrs/654lg6kGTQWIOFjlBo5RaXuAZjBmP3+OQH4dmhqiiyYxw==", + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.3.tgz", + "integrity": "sha512-sBGdETxC+/M4o/zKC0sl6sjWv62WFR/uzxrJ6uYyMLZOUlPnwzw0tKgVHOXxaAd5l2g8pEDM5RZ495GPQI77kg==", "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.19.4", @@ -1736,37 +1917,39 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "node_modules/@eslint-community/eslint-utils": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.3.0.tgz", + "integrity": "sha512-v3oplH6FYCULtFuCeqyuTd9D2WKO937Dxdq+GmHOLL72TTRriLxz2VLlNfkZRsvj6PKnOPAtuT6dwrs/pA5DvA==", "dev": true, "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" + "eslint-visitor-keys": "^3.3.0" }, "engines": { - "node": ">=12" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, - "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "node_modules/@eslint-community/regexpp": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.4.0.tgz", + "integrity": "sha512-A9983Q0LnDGdLPjxyXQ00sbV+K+O+ko2Dr+CZigbHWtX9pNfxlaBkMR8X1CztI73zuEyEBXTVjx7CE+/VSwDiQ==", "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/eslintrc": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.0.tgz", - "integrity": "sha512-fluIaaV+GyV24CCu/ggiHdV+j4RNh85yQnAYS/G2mZODZgGmmlrgCydjUcV3YvxCm9x8nMAfThsqTni4KiXT4A==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.1.tgz", + "integrity": "sha512-eFRmABvW2E5Ho6f5fHLqgena46rOj7r7OKHYfLElqcBfGFHHpjBhivyi5+jOEQuSpdc/1phIZJlbC2te+tZNIw==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.4.0", + "espree": "^9.5.0", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -1781,36 +1964,124 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@eslint/eslintrc/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 + }, + "node_modules/@eslint/eslintrc/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/@eslint/js": { - "version": "8.35.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.35.0.tgz", - "integrity": "sha512-JXdzbRiWclLVoD8sNUjR443VVlYqiYmDVT6rGUEIEHU5YJW0gaVZwV2xgM7D4arkvASqD0IlLUVjHiFuxaftRw==", + "version": "8.36.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.36.0.tgz", + "integrity": "sha512-lxJ9R5ygVm8ZWgYdUweoq5ownDlJ4upvoWmO4eLxBYHdMo+vZ/Rx0EN6MbKWDJOSUGrqJy2Gt+Dyv/VKml0fjg==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.8", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", - "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", + "node_modules/@faker-js/faker": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-7.6.0.tgz", + "integrity": "sha512-XK6BTq1NDMo9Xqw/YkYyGjSsg44fbNwYRx7QK2CuoQgyy+f1rrTDHoExVM5PsyXCtfl2vs2vVJ0MN0yN6LppRw==", "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.5" - }, "engines": { - "node": ">=10.10.0" + "node": ">=14.0.0", + "npm": ">=6.0.0" } }, - "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, - "engines": { - "node": ">=12.22" + "node_modules/@graphql-tools/merge": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-8.4.0.tgz", + "integrity": "sha512-3XYCWe0d3I4F1azNj1CdShlbHfTIfiDgj00R9uvFH8tHKh7i1IWN3F7QQYovcHKhayaR6zPok3YYMESYQcBoaA==", + "dependencies": { + "@graphql-tools/utils": "9.2.1", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-tools/mock": { + "version": "8.7.19", + "resolved": "https://registry.npmjs.org/@graphql-tools/mock/-/mock-8.7.19.tgz", + "integrity": "sha512-LT2boYM+Y1vGFEhzmC7xDFRL8RPG20FbNcuk2/hHGH0Kh8K1hkItvL89tul3Pl7N6xerOnDZ3c3fx7Ls5GuFxA==", + "dependencies": { + "@graphql-tools/schema": "9.0.17", + "@graphql-tools/utils": "9.2.1", + "fast-json-stable-stringify": "^2.1.0", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-tools/schema": { + "version": "9.0.17", + "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-9.0.17.tgz", + "integrity": "sha512-HVLq0ecbkuXhJlpZ50IHP5nlISqH2GbNgjBJhhRzHeXhfwlUOT4ISXGquWTmuq61K0xSaO0aCjMpxe4QYbKTng==", + "dependencies": { + "@graphql-tools/merge": "8.4.0", + "@graphql-tools/utils": "9.2.1", + "tslib": "^2.4.0", + "value-or-promise": "1.0.12" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-tools/utils": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz", + "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==", + "dependencies": { + "@graphql-typed-document-node/core": "^3.1.1", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-typed-document-node/core": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.2.0.tgz", + "integrity": "sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==", + "peerDependencies": { + "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "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, + "engines": { + "node": ">=12.22" }, "funding": { "type": "github", @@ -1839,15 +2110,6 @@ "node": ">=8" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -1861,19 +2123,6 @@ "node": ">=8" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -2209,6 +2458,11 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/@josephg/resolvable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@josephg/resolvable/-/resolvable-1.0.1.tgz", + "integrity": "sha512-CtzORUwWTTOTqfVtHaKRJ0I1kNQd1bpn3sUh8I3nJDVY+5/M/Oe1DnEWzPQvqq/xPIIkzzzIP7mfCoAjFRvDhg==" + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", @@ -2324,6 +2578,60 @@ "node": ">= 8" } }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" + }, "node_modules/@shelf/jest-mongodb": { "version": "4.1.7", "resolved": "https://registry.npmjs.org/@shelf/jest-mongodb/-/jest-mongodb-4.1.7.tgz", @@ -2341,20 +2649,6 @@ "mongodb": "3.x.x || 4.x || 5.x" } }, - "node_modules/@shelf/jest-mongodb/node_modules/mongodb-memory-server": { - "version": "8.11.5", - "resolved": "https://registry.npmjs.org/mongodb-memory-server/-/mongodb-memory-server-8.11.5.tgz", - "integrity": "sha512-/yiw3L2TIMpi9I6GXg379k6d+RG3k+9V9o24kK5h+NBTtYLNuWa5iEvtce/O3jqhg6yo31T5XG2e/Hm4UwBM1A==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "mongodb-memory-server-core": "8.11.5", - "tslib": "^2.4.1" - }, - "engines": { - "node": ">=12.22.0" - } - }, "node_modules/@sinclair/typebox": { "version": "0.25.24", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", @@ -2379,29 +2673,13 @@ "@sinonjs/commons": "^2.0.0" } }, - "node_modules/@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", - "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", - "dev": true + "node_modules/@types/accepts": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/accepts/-/accepts-1.3.5.tgz", + "integrity": "sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ==", + "dependencies": { + "@types/node": "*" + } }, "node_modules/@types/babel__core": { "version": "7.20.0", @@ -2457,7 +2735,6 @@ "version": "1.19.2", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", - "dev": true, "dependencies": { "@types/connect": "*", "@types/node": "*" @@ -2467,7 +2744,6 @@ "version": "3.4.35", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", - "dev": true, "dependencies": { "@types/node": "*" } @@ -2478,6 +2754,11 @@ "integrity": "sha512-t73xJJrvdTjXrn4jLS9VSGRbz0nUY3cl2DMGDU48lKl+HR9dbbjW2A9r3g40VA++mQpy6uuHg33gy7du2BKpog==", "dev": true }, + "node_modules/@types/cors": { + "version": "2.8.12", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz", + "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==" + }, "node_modules/@types/express": { "version": "4.17.17", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", @@ -2501,6 +2782,16 @@ "@types/range-parser": "*" } }, + "node_modules/@types/faker": { + "version": "6.6.9", + "resolved": "https://registry.npmjs.org/@types/faker/-/faker-6.6.9.tgz", + "integrity": "sha512-Y9YYm5L//8ooiiknO++4Gr539zzdI0j3aXnOBjo1Vk+kTvffY10GuE2wn78AFPECwZ5MYGTjiDVw1naLLdDimw==", + "deprecated": "This is a stub types definition. faker provides its own type definitions, so you do not need this installed.", + "dev": true, + "dependencies": { + "faker": "*" + } + }, "node_modules/@types/graceful-fs": { "version": "4.1.6", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz", @@ -2510,6 +2801,34 @@ "@types/node": "*" } }, + "node_modules/@types/graphql": { + "version": "14.5.0", + "resolved": "https://registry.npmjs.org/@types/graphql/-/graphql-14.5.0.tgz", + "integrity": "sha512-MOkzsEp1Jk5bXuAsHsUi6BVv0zCO+7/2PTiZMXWDSsMXvNU6w/PLMQT2vHn8hy2i0JqojPz1Sz6rsFjHtsU0lA==", + "deprecated": "This is a stub types definition. graphql provides its own type definitions, so you do not need this installed.", + "dev": true, + "dependencies": { + "graphql": "*" + } + }, + "node_modules/@types/graphql-iso-date": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@types/graphql-iso-date/-/graphql-iso-date-3.4.0.tgz", + "integrity": "sha512-V3jITHTsoI2E8TGt9+/HPDz6LWt3z9/HYnPJYWI6WwiLRexsngg7KzaQlCgQkA4jkEbGPROUD0hJFc9F02W9WA==", + "dev": true, + "dependencies": { + "graphql": "^15.1.0" + } + }, + "node_modules/@types/graphql-iso-date/node_modules/graphql": { + "version": "15.8.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-15.8.0.tgz", + "integrity": "sha512-5gghUc24tP9HRznNpV2+FIoq3xKkj5dTQqf4v0CpdPbFVwFkWoxOM+o+2OC9ZSvjEMTjfmG9QT+gcvggTwW1zw==", + "dev": true, + "engines": { + "node": ">= 10.x" + } + }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", @@ -2535,9 +2854,9 @@ } }, "node_modules/@types/jest": { - "version": "29.4.0", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.4.0.tgz", - "integrity": "sha512-VaywcGQ9tPorCX/Jkkni7RWGFfI11whqzs8dvxF41P17Z+z872thvEvlIbznjPJ02kl1HMX3LmLOonsj2n7HeQ==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.0.tgz", + "integrity": "sha512-3Emr5VOl/aoBwnWcH/EFQvlSAmjV+XtV9GGu5mwdYew5vhQh0IUZx/60x0TzHDu09Bi7HMx10t/namdJw5QIcg==", "dev": true, "dependencies": { "expect": "^29.0.0", @@ -2565,11 +2884,15 @@ "@types/node": "*" } }, + "node_modules/@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" + }, "node_modules/@types/mime": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz", - "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==", - "dev": true + "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==" }, "node_modules/@types/mongodb": { "version": "4.0.7", @@ -2582,9 +2905,9 @@ } }, "node_modules/@types/node": { - "version": "18.15.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.0.tgz", - "integrity": "sha512-z6nr0TTEOBGkzLGmbypWOGnpSpSIBorEhC4L+4HeQ2iezKCi4f77kyslRwvHeNitymGQ+oFyIWGP96l/DPSV9w==" + "version": "18.15.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.5.tgz", + "integrity": "sha512-Ark2WDjjZO7GmvsyFFf81MXuGTA/d6oP38anyxWOL6EREyBKAxKoFHwBhaZxCfLRLpO8JgVXwqOwSwa7jRcjew==" }, "node_modules/@types/prettier": { "version": "2.7.2", @@ -2595,14 +2918,12 @@ "node_modules/@types/qs": { "version": "6.9.7", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", - "dev": true + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" }, "node_modules/@types/range-parser": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", - "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", - "dev": true + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" }, "node_modules/@types/semver": { "version": "7.3.13", @@ -2614,7 +2935,6 @@ "version": "1.15.1", "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.1.tgz", "integrity": "sha512-NUo5XNiAdULrJENtJXZZ3fHtfMolzZwczzBbnAeBbqBwG+LaG6YaJtuwzwGSQZ2wsCrxjEhNNjAkKigy3n8teQ==", - "dev": true, "dependencies": { "@types/mime": "*", "@types/node": "*" @@ -2662,9 +2982,9 @@ "dev": true }, "node_modules/@types/validator": { - "version": "13.7.13", - "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.7.13.tgz", - "integrity": "sha512-EMfHccxNKXaSxTK6DN0En9WsXa7uR4w3LQtx31f6Z2JjG5hJQeVX5zUYMZoatjZgnoQmRcT94WnNWwi0BzQW6Q==", + "version": "13.7.14", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.7.14.tgz", + "integrity": "sha512-J6OAed6rhN6zyqL9Of6ZMamhlsOEU/poBVvbHr/dKOYKTeuYYMlDkMv+b6UUV0o2i0tw73cgyv/97WTWaUl0/g==", "dev": true }, "node_modules/@types/webidl-conversions": { @@ -2682,9 +3002,9 @@ } }, "node_modules/@types/yargs": { - "version": "17.0.22", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.22.tgz", - "integrity": "sha512-pet5WJ9U8yPVRhkwuEIp5ktAeAqRZOq4UdAyWLWzxbtpyXnzbtLdKiXAjJzi/KLmPGS9wk86lUFWZFN6sISo4g==", + "version": "17.0.23", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.23.tgz", + "integrity": "sha512-yuogunc04OnzGQCrfHx+Kk883Q4X0aSwmYZhKjI21m+SVYzjIbrWl8dOOwSv5hf2Um2pdCOXWo9isteZTNXUZQ==", "dev": true, "dependencies": { "@types/yargs-parser": "*" @@ -2697,19 +3017,19 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.54.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.54.1.tgz", - "integrity": "sha512-a2RQAkosH3d3ZIV08s3DcL/mcGc2M/UC528VkPULFxR9VnVPT8pBu0IyBAJJmVsCmhVfwQX1v6q+QGnmSe1bew==", + "version": "5.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.56.0.tgz", + "integrity": "sha512-ZNW37Ccl3oMZkzxrYDUX4o7cnuPgU+YrcaYXzsRtLB16I1FR5SHMqga3zGsaSliZADCWo2v8qHWqAYIj8nWCCg==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.54.1", - "@typescript-eslint/type-utils": "5.54.1", - "@typescript-eslint/utils": "5.54.1", + "@eslint-community/regexpp": "^4.4.0", + "@typescript-eslint/scope-manager": "5.56.0", + "@typescript-eslint/type-utils": "5.56.0", + "@typescript-eslint/utils": "5.56.0", "debug": "^4.3.4", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "natural-compare-lite": "^1.4.0", - "regexpp": "^3.2.0", "semver": "^7.3.7", "tsutils": "^3.21.0" }, @@ -2731,14 +3051,14 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "5.54.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.54.1.tgz", - "integrity": "sha512-8zaIXJp/nG9Ff9vQNh7TI+C3nA6q6iIsGJ4B4L6MhZ7mHnTMR4YP5vp2xydmFXIy8rpyIVbNAG44871LMt6ujg==", + "version": "5.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.56.0.tgz", + "integrity": "sha512-sn1OZmBxUsgxMmR8a8U5QM/Wl+tyqlH//jTqCg8daTAmhAk26L2PFhcqPLlYBhYUJMZJK276qLXlHN3a83o2cg==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.54.1", - "@typescript-eslint/types": "5.54.1", - "@typescript-eslint/typescript-estree": "5.54.1", + "@typescript-eslint/scope-manager": "5.56.0", + "@typescript-eslint/types": "5.56.0", + "@typescript-eslint/typescript-estree": "5.56.0", "debug": "^4.3.4" }, "engines": { @@ -2758,13 +3078,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.54.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.54.1.tgz", - "integrity": "sha512-zWKuGliXxvuxyM71UA/EcPxaviw39dB2504LqAmFDjmkpO8qNLHcmzlh6pbHs1h/7YQ9bnsO8CCcYCSA8sykUg==", + "version": "5.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.56.0.tgz", + "integrity": "sha512-jGYKyt+iBakD0SA5Ww8vFqGpoV2asSjwt60Gl6YcO8ksQ8s2HlUEyHBMSa38bdLopYqGf7EYQMUIGdT/Luw+sw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.54.1", - "@typescript-eslint/visitor-keys": "5.54.1" + "@typescript-eslint/types": "5.56.0", + "@typescript-eslint/visitor-keys": "5.56.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2775,13 +3095,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.54.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.54.1.tgz", - "integrity": "sha512-WREHsTz0GqVYLIbzIZYbmUUr95DKEKIXZNH57W3s+4bVnuF1TKe2jH8ZNH8rO1CeMY3U4j4UQeqPNkHMiGem3g==", + "version": "5.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.56.0.tgz", + "integrity": "sha512-8WxgOgJjWRy6m4xg9KoSHPzBNZeQbGlQOH7l2QEhQID/+YseaFxg5J/DLwWSsi9Axj4e/cCiKx7PVzOq38tY4A==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "5.54.1", - "@typescript-eslint/utils": "5.54.1", + "@typescript-eslint/typescript-estree": "5.56.0", + "@typescript-eslint/utils": "5.56.0", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -2802,9 +3122,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.54.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.54.1.tgz", - "integrity": "sha512-G9+1vVazrfAfbtmCapJX8jRo2E4MDXxgm/IMOF4oGh3kq7XuK3JRkOg6y2Qu1VsTRmWETyTkWt1wxy7X7/yLkw==", + "version": "5.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.56.0.tgz", + "integrity": "sha512-JyAzbTJcIyhuUhogmiu+t79AkdnqgPUEsxMTMc/dCZczGMJQh1MK2wgrju++yMN6AWroVAy2jxyPcPr3SWCq5w==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2815,13 +3135,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.54.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.54.1.tgz", - "integrity": "sha512-bjK5t+S6ffHnVwA0qRPTZrxKSaFYocwFIkZx5k7pvWfsB1I57pO/0M0Skatzzw1sCkjJ83AfGTL0oFIFiDX3bg==", + "version": "5.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.56.0.tgz", + "integrity": "sha512-41CH/GncsLXOJi0jb74SnC7jVPWeVJ0pxQj8bOjH1h2O26jXN3YHKDT1ejkVz5YeTEQPeLCCRY0U2r68tfNOcg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.54.1", - "@typescript-eslint/visitor-keys": "5.54.1", + "@typescript-eslint/types": "5.56.0", + "@typescript-eslint/visitor-keys": "5.56.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2842,18 +3162,18 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "5.54.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.54.1.tgz", - "integrity": "sha512-IY5dyQM8XD1zfDe5X8jegX6r2EVU5o/WJnLu/znLPWCBF7KNGC+adacXnt5jEYS9JixDcoccI6CvE4RCjHMzCQ==", + "version": "5.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.56.0.tgz", + "integrity": "sha512-XhZDVdLnUJNtbzaJeDSCIYaM+Tgr59gZGbFuELgF7m0IY03PlciidS7UQNKLE0+WpUTn1GlycEr6Ivb/afjbhA==", "dev": true, "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.54.1", - "@typescript-eslint/types": "5.54.1", - "@typescript-eslint/typescript-estree": "5.54.1", + "@typescript-eslint/scope-manager": "5.56.0", + "@typescript-eslint/types": "5.56.0", + "@typescript-eslint/typescript-estree": "5.56.0", "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0", "semver": "^7.3.7" }, "engines": { @@ -2868,12 +3188,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.54.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.54.1.tgz", - "integrity": "sha512-q8iSoHTgwCfgcRJ2l2x+xCbu8nBlRAlsQ33k24Adj8eoVBE0f8dUeI+bAa8F84Mv05UGbAx57g2zrRsYIooqQg==", + "version": "5.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.56.0.tgz", + "integrity": "sha512-1mFdED7u5bZpX6Xxf5N9U2c18sb+8EvU3tyOIj6LQZ5OOvnmj8BVeNNP603OFPm5KkS1a7IvCIcwrdHXaEMG/Q==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.54.1", + "@typescript-eslint/types": "5.56.0", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -2922,15 +3242,6 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -3021,17 +3332,10 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", - "dev": true - }, "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, "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -3040,110 +3344,397 @@ "node": ">= 8" } }, - "node_modules/aproba": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", - "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" - }, - "node_modules/are-we-there-yet": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", - "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "node_modules/apollo-datasource": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/apollo-datasource/-/apollo-datasource-3.3.2.tgz", + "integrity": "sha512-L5TiS8E2Hn/Yz7SSnWIVbZw0ZfEIXZCa5VUiVxD9P53JvSrf4aStvsFDlGWPvpIdCR+aly2CfoB79B9/JjKFqg==", + "deprecated": "The `apollo-datasource` package is part of Apollo Server v2 and v3, which are now deprecated (end-of-life October 22nd 2023). See https://www.apollographql.com/docs/apollo-server/previous-versions/ for more details.", "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" + "@apollo/utils.keyvaluecache": "^1.0.1", + "apollo-server-env": "^4.2.1" }, "engines": { - "node": ">=10" + "node": ">=12.0" } }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true + "node_modules/apollo-reporting-protobuf": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/apollo-reporting-protobuf/-/apollo-reporting-protobuf-3.4.0.tgz", + "integrity": "sha512-h0u3EbC/9RpihWOmcSsvTW2O6RXVaD/mPEjfrPkxRPTEPWqncsgOoRJw+wih4OqfH3PvTJvoEIf4LwKrUaqWog==", + "deprecated": "The `apollo-reporting-protobuf` package is part of Apollo Server v2 and v3, which are now deprecated (end-of-life October 22nd 2023). This package's functionality is now found in the `@apollo/usage-reporting-protobuf` package. See https://www.apollographql.com/docs/apollo-server/previous-versions/ for more details.", + "dependencies": { + "@apollo/protobufjs": "1.2.6" + } }, - "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 + "node_modules/apollo-reporting-protobuf/node_modules/@apollo/protobufjs": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@apollo/protobufjs/-/protobufjs-1.2.6.tgz", + "integrity": "sha512-Wqo1oSHNUj/jxmsVp4iR3I480p6qdqHikn38lKrFhfzcDJ7lwd7Ck7cHRl4JE81tWNArl77xhnG/OkZhxKBYOw==", + "hasInstallScript": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.0", + "@types/node": "^10.1.0", + "long": "^4.0.0" + }, + "bin": { + "apollo-pbjs": "bin/pbjs", + "apollo-pbts": "bin/pbts" + } + }, + "node_modules/apollo-reporting-protobuf/node_modules/@types/node": { + "version": "10.17.60", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", + "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==" + }, + "node_modules/apollo-server-core": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/apollo-server-core/-/apollo-server-core-3.12.0.tgz", + "integrity": "sha512-hq7iH6Cgldgmnjs9FVSZeKWRpi0/ZR+iJ1arzeD2VXGxxgk1mAm/cz1Tx0TYgegZI+FvvrRl0UhKEx7sLnIxIg==", + "deprecated": "The `apollo-server-core` package is part of Apollo Server v2 and v3, which are now deprecated (end-of-life October 22nd 2023). This package's functionality is now found in the `@apollo/server` package. See https://www.apollographql.com/docs/apollo-server/previous-versions/ for more details.", + "dependencies": { + "@apollo/utils.keyvaluecache": "^1.0.1", + "@apollo/utils.logger": "^1.0.0", + "@apollo/utils.usagereporting": "^1.0.0", + "@apollographql/apollo-tools": "^0.5.3", + "@apollographql/graphql-playground-html": "1.6.29", + "@graphql-tools/mock": "^8.1.2", + "@graphql-tools/schema": "^8.0.0", + "@josephg/resolvable": "^1.0.0", + "apollo-datasource": "^3.3.2", + "apollo-reporting-protobuf": "^3.4.0", + "apollo-server-env": "^4.2.1", + "apollo-server-errors": "^3.3.1", + "apollo-server-plugin-base": "^3.7.2", + "apollo-server-types": "^3.8.0", + "async-retry": "^1.2.1", + "fast-json-stable-stringify": "^2.1.0", + "graphql-tag": "^2.11.0", + "loglevel": "^1.6.8", + "lru-cache": "^6.0.0", + "node-abort-controller": "^3.0.1", + "sha.js": "^2.4.11", + "uuid": "^9.0.0", + "whatwg-mimetype": "^3.0.0" + }, + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "graphql": "^15.3.0 || ^16.0.0" + } }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + "node_modules/apollo-server-core/node_modules/@graphql-tools/merge": { + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-8.3.1.tgz", + "integrity": "sha512-BMm99mqdNZbEYeTPK3it9r9S6rsZsQKtlqJsSBknAclXq2pGEfOxjcIZi+kBSkHZKPKCRrYDd5vY0+rUmIHVLg==", + "dependencies": { + "@graphql-tools/utils": "8.9.0", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } }, - "node_modules/array-includes": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", - "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", - "dev": true, + "node_modules/apollo-server-core/node_modules/@graphql-tools/schema": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-8.5.1.tgz", + "integrity": "sha512-0Esilsh0P/qYcB5DKQpiKeQs/jevzIadNTaT0jeWklPMwNbT7yMX4EqZany7mbeRRlSRwMzNzL5olyFdffHBZg==", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "get-intrinsic": "^1.1.3", - "is-string": "^1.0.7" + "@graphql-tools/merge": "8.3.1", + "@graphql-tools/utils": "8.9.0", + "tslib": "^2.4.0", + "value-or-promise": "1.0.11" }, - "engines": { - "node": ">= 0.4" + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/apollo-server-core/node_modules/@graphql-tools/utils": { + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.9.0.tgz", + "integrity": "sha512-pjJIWH0XOVnYGXCqej8g/u/tsfV4LvLlj0eATKQu5zwnxd/TiTHq7Cg313qUPTFFHZ3PP5wJ15chYVtLDwaymg==", + "dependencies": { + "tslib": "^2.4.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.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, + "node_modules/apollo-server-core/node_modules/value-or-promise": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/value-or-promise/-/value-or-promise-1.0.11.tgz", + "integrity": "sha512-41BrgH+dIbCFXClcSapVs5M6GkENd3gQOJpEfPDNa71LsUGMXDL0jMWpI/Rh7WhX+Aalfz2TTS3Zt5pUsbnhLg==", "engines": { - "node": ">=8" + "node": ">=12" } }, - "node_modules/array.prototype.flat": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz", - "integrity": "sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==", - "dev": true, + "node_modules/apollo-server-env": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/apollo-server-env/-/apollo-server-env-4.2.1.tgz", + "integrity": "sha512-vm/7c7ld+zFMxibzqZ7SSa5tBENc4B0uye9LTfjJwGoQFY5xsUPH5FpO5j0bMUDZ8YYNbrF9SNtzc5Cngcr90g==", + "deprecated": "The `apollo-server-env` package is part of Apollo Server v2 and v3, which are now deprecated (end-of-life October 22nd 2023). This package's functionality is now found in the `@apollo/utils.fetcher` package. See https://www.apollographql.com/docs/apollo-server/previous-versions/ for more details.", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "es-shim-unscopables": "^1.0.0" + "node-fetch": "^2.6.7" }, "engines": { - "node": ">= 0.4" + "node": ">=12.0" + } + }, + "node_modules/apollo-server-errors": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/apollo-server-errors/-/apollo-server-errors-3.3.1.tgz", + "integrity": "sha512-xnZJ5QWs6FixHICXHxUfm+ZWqqxrNuPlQ+kj5m6RtEgIpekOPssH/SD9gf2B4HuWV0QozorrygwZnux8POvyPA==", + "deprecated": "The `apollo-server-errors` package is part of Apollo Server v2 and v3, which are now deprecated (end-of-life October 22nd 2023). This package's functionality is now found in the `@apollo/server` package. See https://www.apollographql.com/docs/apollo-server/previous-versions/ for more details.", + "engines": { + "node": ">=12.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependencies": { + "graphql": "^15.3.0 || ^16.0.0" } }, - "node_modules/array.prototype.flatmap": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", - "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", - "dev": true, + "node_modules/apollo-server-express": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/apollo-server-express/-/apollo-server-express-3.12.0.tgz", + "integrity": "sha512-m8FaGPUfDOEGSm7QRWRmUUGjG/vqvpQoorkId9/FXkC57fz/A59kEdrzkMt9538Xgsa5AV+X4MEWLJhTvlW3LQ==", + "deprecated": "The `apollo-server-express` package is part of Apollo Server v2 and v3, which are now deprecated (end-of-life October 22nd 2023). This package's functionality is now found in the `@apollo/server` package. See https://www.apollographql.com/docs/apollo-server/previous-versions/ for more details.", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "es-shim-unscopables": "^1.0.0" + "@types/accepts": "^1.3.5", + "@types/body-parser": "1.19.2", + "@types/cors": "2.8.12", + "@types/express": "4.17.14", + "@types/express-serve-static-core": "4.17.31", + "accepts": "^1.3.5", + "apollo-server-core": "^3.12.0", + "apollo-server-types": "^3.8.0", + "body-parser": "^1.19.0", + "cors": "^2.8.5", + "parseurl": "^1.3.3" }, "engines": { - "node": ">= 0.4" + "node": ">=12.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependencies": { + "express": "^4.17.1", + "graphql": "^15.3.0 || ^16.0.0" + } + }, + "node_modules/apollo-server-express/node_modules/@types/express": { + "version": "4.17.14", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.14.tgz", + "integrity": "sha512-TEbt+vaPFQ+xpxFLFssxUDXj5cWCxZJjIcB7Yg0k0GMHGtgtQgpvx/MUQUeAkNbA9AAGrwkAsoeItdTgS7FMyg==", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.18", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/apollo-server-express/node_modules/@types/express-serve-static-core": { + "version": "4.17.31", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.31.tgz", + "integrity": "sha512-DxMhY+NAsTwMMFHBTtJFNp5qiHKJ7TeqOo23zVEM9alT1Ml27Q3xcTH0xwxn7Q0BbMcVEJOs/7aQtUWupUQN3Q==", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, + "node_modules/apollo-server-plugin-base": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/apollo-server-plugin-base/-/apollo-server-plugin-base-3.7.2.tgz", + "integrity": "sha512-wE8dwGDvBOGehSsPTRZ8P/33Jan6/PmL0y0aN/1Z5a5GcbFhDaaJCjK5cav6npbbGL2DPKK0r6MPXi3k3N45aw==", + "deprecated": "The `apollo-server-plugin-base` package is part of Apollo Server v2 and v3, which are now deprecated (end-of-life October 22nd 2023). This package's functionality is now found in the `@apollo/server` package. See https://www.apollographql.com/docs/apollo-server/previous-versions/ for more details.", + "dependencies": { + "apollo-server-types": "^3.8.0" + }, + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "graphql": "^15.3.0 || ^16.0.0" + } + }, + "node_modules/apollo-server-types": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/apollo-server-types/-/apollo-server-types-3.8.0.tgz", + "integrity": "sha512-ZI/8rTE4ww8BHktsVpb91Sdq7Cb71rdSkXELSwdSR0eXu600/sY+1UXhTWdiJvk+Eq5ljqoHLwLbY2+Clq2b9A==", + "deprecated": "The `apollo-server-types` package is part of Apollo Server v2 and v3, which are now deprecated (end-of-life October 22nd 2023). This package's functionality is now found in the `@apollo/server` package. See https://www.apollographql.com/docs/apollo-server/previous-versions/ for more details.", + "dependencies": { + "@apollo/utils.keyvaluecache": "^1.0.1", + "@apollo/utils.logger": "^1.0.0", + "apollo-reporting-protobuf": "^3.4.0", + "apollo-server-env": "^4.2.1" + }, + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "graphql": "^15.3.0 || ^16.0.0" + } + }, + "node_modules/aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" + }, + "node_modules/are-we-there-yet": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/are-we-there-yet/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==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/are-we-there-yet/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", + "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "is-array-buffer": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "node_modules/array-includes": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", + "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "get-intrinsic": "^1.1.3", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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, + "engines": { + "node": ">=8" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz", + "integrity": "sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", + "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "dev": true + }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dev": true, + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "dev": true, + "engines": { + "node": ">=0.8" } }, - "node_modules/asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", - "dev": true - }, "node_modules/astral-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", @@ -3162,6 +3753,14 @@ "tslib": "^2.3.1" } }, + "node_modules/async-retry": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", + "integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==", + "dependencies": { + "retry": "0.13.1" + } + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -3180,6 +3779,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", + "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==", + "dev": true + }, "node_modules/babel-jest": { "version": "29.5.0", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.5.0.tgz", @@ -3309,6 +3923,23 @@ "node": ">= 10.0.0" } }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "dev": true, + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "engines": { + "node": ">=8" + } + }, "node_modules/bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", @@ -3320,13 +3951,36 @@ "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, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bl/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", "dependencies": { "bytes": "3.1.2", - "content-type": "~1.0.4", + "content-type": "~1.0.5", "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", @@ -3334,7 +3988,7 @@ "iconv-lite": "0.4.24", "on-finished": "2.4.1", "qs": "6.11.0", - "raw-body": "2.5.1", + "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" }, @@ -3375,7 +4029,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, "dependencies": { "fill-range": "^7.0.1" }, @@ -3433,13 +4086,19 @@ } }, "node_modules/bson": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/bson/-/bson-5.0.1.tgz", - "integrity": "sha512-y09gBGusgHtinMon/GVbv1J6FrXhnr/+6hqLlSmEFzkz6PodqF6TxjyvfvY3AfO+oG1mgUtbC86xSbOlwvM62Q==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-5.1.0.tgz", + "integrity": "sha512-FEecNHkhYRBe7X9KDkdG12xNuz5VHGeH6mCE0B5sBmYtiR/Ux/9vUH/v4NUoBCDr6NuEhvahjoLiiRogptVW0A==", "engines": { "node": ">=14.20.1" } }, + "node_modules/bson-objectid": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/bson-objectid/-/bson-objectid-2.0.4.tgz", + "integrity": "sha512-vgnKAUzcDoa+AeyYwXCoHyF2q6u/8H46dxu5JN+4/TZeq/Dlinn0K6GvxsCLb3LHUJl0m/TLiEK31kUwtgocMQ==", + "dev": true + }, "node_modules/buffer": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", @@ -3489,6 +4148,7 @@ "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", "dev": true, + "peer": true, "dependencies": { "semver": "^7.0.0" } @@ -3532,9 +4192,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001460", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001460.tgz", - "integrity": "sha512-Bud7abqjvEjipUkpLs4D7gR0l8hBYBHoa+tGtKJHvT2AYzLp1z7EmVkUT4ERpVUfca8S2HGIVs883D8pUH1ZzQ==", + "version": "1.0.30001469", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001469.tgz", + "integrity": "sha512-Rcp7221ScNqQPP3W+lVOYDyjdR6dC+neEQCttoNr5bAyz54AboB4iwpnWgyi8P4YUsPybVzT4LgWiBbI3drL4g==", "dev": true, "funding": [ { @@ -3547,6 +4207,12 @@ } ] }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "dev": true + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -3572,6 +4238,43 @@ "node": ">=10" } }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "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" + }, + "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==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/chownr": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", @@ -3639,17 +4342,14 @@ } }, "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "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, "dependencies": { "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", + "strip-ansi": "^6.0.0", "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" } }, "node_modules/cliui/node_modules/emoji-regex": { @@ -3816,12 +4516,62 @@ "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==", "dev": true }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "node_modules/copyfiles": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/copyfiles/-/copyfiles-2.4.1.tgz", + "integrity": "sha512-fereAvAvxDrQDOXybk3Qu3dPbOoKoysFMWtkY3mv5BsL8//OSZVL5DCLYqgRfY5cWirgRzlC+WSrxp6Bo3eNZg==", + "dev": true, + "dependencies": { + "glob": "^7.0.5", + "minimatch": "^3.0.3", + "mkdirp": "^1.0.4", + "noms": "0.0.0", + "through2": "^2.0.1", + "untildify": "^4.0.0", + "yargs": "^16.1.0" + }, + "bin": { + "copyfiles": "copyfiles", + "copyup": "copyfiles" + } + }, + "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 }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/coveralls": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.1.1.tgz", + "integrity": "sha512-+dxnG2NHncSD1NrqbSM3dn/lE57O6Qf/koe9+I7c+wzkqRmEvcp0kgJdxKInzYzkICKkFMZsX3Vct3++tsF9ww==", + "dev": true, + "dependencies": { + "js-yaml": "^3.13.1", + "lcov-parse": "^1.0.0", + "log-driver": "^1.2.7", + "minimist": "^1.2.5", + "request": "^2.88.2" + }, + "bin": { + "coveralls": "bin/coveralls.js" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -3836,6 +4586,23 @@ "node": ">= 8" } }, + "node_modules/cssfilter": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/cssfilter/-/cssfilter-0.0.10.tgz", + "integrity": "sha512-FAaLDaplstoRsDR8XGYH51znUN0UY7nMc6Z9/fvE8EXGwvJE9hu7W2vHwx1+bd6gCYnln9nLbzxFTrcO9YQDZw==" + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -3865,9 +4632,9 @@ "dev": true }, "node_modules/deepmerge": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.0.tgz", - "integrity": "sha512-z2wJZXrmeHdvYJp/Ux55wIjqo81G5Bp4c+oELTW+7ar6SogWHajt5a9gO3s3IDaGSAXjDk0vlQKN3rms8ab3og==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "dev": true, "engines": { "node": ">=0.10.0" @@ -3957,15 +4724,6 @@ "underscore": "*" } }, - "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, "node_modules/diff-sequences": { "version": "29.4.3", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", @@ -4005,6 +4763,16 @@ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "dev": true }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "dev": true, + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, "node_modules/ecdsa-sig-formatter": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", @@ -4019,9 +4787,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.4.320", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.320.tgz", - "integrity": "sha512-h70iRscrNluMZPVICXYl5SSB+rBKo22XfuIS1ER0OQxQZpKTnFpuS6coj7wY9M/3trv7OR88rRMOlKmRvDty7Q==", + "version": "1.4.334", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.334.tgz", + "integrity": "sha512-laZ1odk+TRen6q0GeyQx/JEkpD3iSZT7ewopCpKqg9bTjP1l8XRfU3Bg20CFjNPZkp5+NDBl3iqd4o/kPO+Vew==", "dev": true }, "node_modules/emittery": { @@ -4069,18 +4837,18 @@ } }, "node_modules/es-abstract": { - "version": "1.21.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.1.tgz", - "integrity": "sha512-QudMsPOz86xYz/1dG1OuGBKOELjCh99IIWHLzy5znUB6j8xG2yMA7bfTV86VSqKF+Y/H08vQPR+9jyXpuC6hfg==", + "version": "1.21.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.2.tgz", + "integrity": "sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg==", "dev": true, "dependencies": { + "array-buffer-byte-length": "^1.0.0", "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", "es-set-tostringtag": "^2.0.1", "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.1.3", + "get-intrinsic": "^1.2.0", "get-symbol-description": "^1.0.0", "globalthis": "^1.0.3", "gopd": "^1.0.1", @@ -4088,8 +4856,8 @@ "has-property-descriptors": "^1.0.0", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", - "internal-slot": "^1.0.4", - "is-array-buffer": "^3.0.1", + "internal-slot": "^1.0.5", + "is-array-buffer": "^3.0.2", "is-callable": "^1.2.7", "is-negative-zero": "^2.0.2", "is-regex": "^1.1.4", @@ -4097,11 +4865,12 @@ "is-string": "^1.0.7", "is-typed-array": "^1.1.10", "is-weakref": "^1.0.2", - "object-inspect": "^1.12.2", + "object-inspect": "^1.12.3", "object-keys": "^1.1.1", "object.assign": "^4.1.4", "regexp.prototype.flags": "^1.4.3", "safe-regex-test": "^1.0.0", + "string.prototype.trim": "^1.2.7", "string.prototype.trimend": "^1.0.6", "string.prototype.trimstart": "^1.0.6", "typed-array-length": "^1.0.4", @@ -4182,13 +4951,15 @@ } }, "node_modules/eslint": { - "version": "8.35.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.35.0.tgz", - "integrity": "sha512-BxAf1fVL7w+JLRQhWl2pzGeSiGqbWumV4WNvc9Rhp6tiCtm4oHnyPBSEtMGZwrQgudFQ+otqzWoPB7x+hxoWsw==", + "version": "8.36.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.36.0.tgz", + "integrity": "sha512-Y956lmS7vDqomxlaaQAHVmeb4tNMp2FWIvU/RnU5BD3IKMD/MJPr76xdyr68P8tV1iNMvN2mRK0yy3c+UjL+bw==", "dev": true, "dependencies": { - "@eslint/eslintrc": "^2.0.0", - "@eslint/js": "8.35.0", + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.4.0", + "@eslint/eslintrc": "^2.0.1", + "@eslint/js": "8.36.0", "@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -4199,9 +4970,8 @@ "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", "eslint-visitor-keys": "^3.3.0", - "espree": "^9.4.0", + "espree": "^9.5.0", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -4223,7 +4993,6 @@ "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.1", - "regexpp": "^3.2.0", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" @@ -4265,16 +5034,16 @@ } }, "node_modules/eslint-config-standard-with-typescript": { - "version": "34.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-standard-with-typescript/-/eslint-config-standard-with-typescript-34.0.0.tgz", - "integrity": "sha512-zhCsI4/A0rJ1ma8sf3RLXYc0gc7yPmdTWRVXMh9dtqeUx3yBQyALH0wosHhk1uQ9QyItynLdNOtcHKNw8G7lQw==", + "version": "34.0.1", + "resolved": "https://registry.npmjs.org/eslint-config-standard-with-typescript/-/eslint-config-standard-with-typescript-34.0.1.tgz", + "integrity": "sha512-J7WvZeLtd0Vr9F+v4dZbqJCLD16cbIy4U+alJMq4MiXdpipdBM3U5NkXaGUjePc4sb1ZE01U9g6VuTBpHHz1fg==", "dev": true, "dependencies": { - "@typescript-eslint/parser": "^5.0.0", + "@typescript-eslint/parser": "^5.43.0", "eslint-config-standard": "17.0.0" }, "peerDependencies": { - "@typescript-eslint/eslint-plugin": "^5.0.0", + "@typescript-eslint/eslint-plugin": "^5.43.0", "eslint": "^8.0.1", "eslint-plugin-import": "^2.25.2", "eslint-plugin-n": "^15.0.0", @@ -4333,6 +5102,7 @@ "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-4.1.0.tgz", "integrity": "sha512-GILhQTnjYE2WorX5Jyi5i4dz5ALWxBIdQECVQavL6s7cI76IZTDWleTHkxz/QT3kvcs2QlGHvKLYsSlPOlPXnQ==", "dev": true, + "peer": true, "dependencies": { "eslint-utils": "^2.0.0", "regexpp": "^3.0.0" @@ -4352,6 +5122,7 @@ "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, + "peer": true, "dependencies": { "eslint-visitor-keys": "^1.1.0" }, @@ -4367,6 +5138,7 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true, + "peer": true, "engines": { "node": ">=4" } @@ -4435,6 +5207,7 @@ "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-15.6.1.tgz", "integrity": "sha512-R9xw9OtCRxxaxaszTQmQAlPgM+RdGjaL1akWuY/Fv9fRAi8Wj4CUKc6iYVG8QNRjRuo8/BqVYIpfqberJUEacA==", "dev": true, + "peer": true, "dependencies": { "builtins": "^5.0.1", "eslint-plugin-es": "^4.1.0", @@ -4455,6 +5228,78 @@ "eslint": ">=7.0.0" } }, + "node_modules/eslint-plugin-node": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", + "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", + "dev": true, + "dependencies": { + "eslint-plugin-es": "^3.0.0", + "eslint-utils": "^2.0.0", + "ignore": "^5.1.1", + "minimatch": "^3.0.4", + "resolve": "^1.10.1", + "semver": "^6.1.0" + }, + "engines": { + "node": ">=8.10.0" + }, + "peerDependencies": { + "eslint": ">=5.16.0" + } + }, + "node_modules/eslint-plugin-node/node_modules/eslint-plugin-es": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", + "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", + "dev": true, + "dependencies": { + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" + }, + "engines": { + "node": ">=8.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=4.19.1" + } + }, + "node_modules/eslint-plugin-node/node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/eslint-plugin-node/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-plugin-node/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/eslint-plugin-promise": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz", @@ -4467,6 +5312,30 @@ "eslint": "^7.0.0 || ^8.0.0" } }, + "node_modules/eslint-plugin-standard": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-5.0.0.tgz", + "integrity": "sha512-eSIXPc9wBM4BrniMzJRBm2uoVuXz2EPa+NXPk2+itrVt+r5SbKFERx/IgrK/HmfjddyKVz2f+j+7gBRvu19xLg==", + "deprecated": "standard 16.0.0 and eslint-config-standard 16.0.0 no longer require the eslint-plugin-standard package. You can remove it from your dependencies with 'npm rm eslint-plugin-standard'. More info here: https://github.com/standard/standard/issues/1316", + "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" + } + ], + "peerDependencies": { + "eslint": ">=5.0.0" + } + }, "node_modules/eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", @@ -4485,6 +5354,7 @@ "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", "dev": true, + "peer": true, "dependencies": { "eslint-visitor-keys": "^2.0.0" }, @@ -4503,6 +5373,7 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", "dev": true, + "peer": true, "engines": { "node": ">=10" } @@ -4516,6 +5387,12 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/eslint/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 + }, "node_modules/eslint/node_modules/eslint-scope": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", @@ -4538,10 +5415,22 @@ "node": ">=4.0" } }, + "node_modules/eslint/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/espree": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", - "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.0.tgz", + "integrity": "sha512-JPbJGhKc47++oo4JkEoTe2wjy4fmMwvFpgJT9cQzmfXKp22Dr6Hf1tdCteLz1h0P3t+mGvWZ+4Uankvh8+c6zw==", "dev": true, "dependencies": { "acorn": "^8.8.0", @@ -4725,6 +5614,29 @@ "node": ">= 0.10.0" } }, + "node_modules/express/node_modules/body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, "node_modules/express/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -4738,6 +5650,41 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, + "node_modules/express/node_modules/raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "dev": true, + "engines": [ + "node >=0.6.0" + ] + }, + "node_modules/faker": { + "version": "6.6.6", + "resolved": "https://registry.npmjs.org/faker/-/faker-6.6.6.tgz", + "integrity": "sha512-9tCqYEDHI5RYFQigXFwF1hnCwcWCOJl/hmll0lr5D2Ljjb0o4wphb69wikeJDz5qCEzXCoPvG6ss5SDP6IfOdg==", + "dev": true + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -4775,8 +5722,7 @@ "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 + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" }, "node_modules/fast-levenshtein": { "version": "2.0.6", @@ -4849,7 +5795,6 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, "dependencies": { "to-regex-range": "^5.0.1" }, @@ -4963,18 +5908,27 @@ "is-callable": "^1.1.3" } }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", "dev": true, "dependencies": { "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", + "combined-stream": "^1.0.6", "mime-types": "^2.1.12" }, "engines": { - "node": ">= 6" + "node": ">= 0.12" } }, "node_modules/formidable": { @@ -5036,11 +5990,6 @@ "node": ">=8" } }, - "node_modules/fs-minipass/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -5050,7 +5999,6 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -5217,6 +6165,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + } + }, "node_modules/git-commit-msg-linter": { "version": "4.9.2", "resolved": "https://registry.npmjs.org/git-commit-msg-linter/-/git-commit-msg-linter-4.9.2.tgz", @@ -5415,9 +6372,9 @@ } }, "node_modules/graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true }, "node_modules/grapheme-splitter": { @@ -5426,6 +6383,65 @@ "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", "dev": true }, + "node_modules/graphql": { + "version": "16.6.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.6.0.tgz", + "integrity": "sha512-KPIBPDlW7NxrbT/eh4qPXz5FiFdL5UbaA0XUNz2Rp3Z3hqBSkbj0GVjwFDztsWVauZUWsbKHgMg++sk8UX0bkw==", + "engines": { + "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" + } + }, + "node_modules/graphql-scalars": { + "version": "1.20.4", + "resolved": "https://registry.npmjs.org/graphql-scalars/-/graphql-scalars-1.20.4.tgz", + "integrity": "sha512-/hDzWcphV/aV4MEx2pqVMMekBLi9VXYD/HrJSclpOCLkSB/dE3Rb5VVZBXsQhgBxqeCsE7K0PEO2/cWAUzQsrQ==", + "dependencies": { + "tslib": "~2.5.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" + } + }, + "node_modules/graphql-tag": { + "version": "2.12.6", + "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.6.tgz", + "integrity": "sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==", + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "graphql": "^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" + } + }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", + "dev": true, + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -5540,6 +6556,21 @@ "node": ">= 0.8" } }, + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, "node_modules/https-proxy-agent": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", @@ -5616,6 +6647,11 @@ "node": ">= 4" } }, + "node_modules/ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==" + }, "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -5742,6 +6778,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "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==", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/is-boolean-object": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", @@ -5801,7 +6848,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -5831,7 +6877,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, "dependencies": { "is-extglob": "^2.1.1" }, @@ -5855,7 +6900,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, "engines": { "node": ">=0.12.0" } @@ -5973,6 +7017,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true + }, "node_modules/is-weakref": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", @@ -5985,12 +7035,24 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "dev": true + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", + "dev": true + }, "node_modules/istanbul-lib-coverage": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", @@ -6170,6 +7232,67 @@ } } }, + "node_modules/jest-cli/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/jest-cli/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 + }, + "node_modules/jest-cli/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-cli/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, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-cli/node_modules/yargs": { + "version": "17.7.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", + "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/jest-config": { "version": "29.5.0", "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.5.0.tgz", @@ -6641,17 +7764,24 @@ "dev": true }, "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, "dependencies": { - "argparse": "^2.0.1" + "argparse": "^1.0.7", + "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", + "dev": true + }, "node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -6670,6 +7800,12 @@ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "dev": true + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -6682,6 +7818,12 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true + }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -6709,6 +7851,21 @@ "npm": ">=6" } }, + "node_modules/jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "dev": true, + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, "node_modules/jwa": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", @@ -6737,6 +7894,15 @@ "node": ">=6" } }, + "node_modules/lcov-parse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-1.0.0.tgz", + "integrity": "sha512-aprLII/vPzuQvYZnDRU78Fns9I2Ag3gi4Ipga/hxnVMCZC8DnR2nI7XBqrPoywGfxqIx/DgarGvDJZAD3YBTgQ==", + "dev": true, + "bin": { + "lcov-parse": "bin/cli.js" + } + }, "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -6826,9 +7992,9 @@ } }, "node_modules/lint-staged/node_modules/execa": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-7.0.0.tgz", - "integrity": "sha512-tQbH0pH/8LHTnwTrsKWideqi6rFB/QNUawEwrn+WHyz7PX1Tuz2u7wfTvbaNBdP5JD5LVWxNo8/A8CHNZ3bV6g==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-7.1.1.tgz", + "integrity": "sha512-wH0eMf/UXckdUYnO21+HDztteVv05rq2GXksxT4fCGeHkBhw1DROXh40wcjMcRqDOWE7iPJ4n3M7e2+YFP+76Q==", "dev": true, "dependencies": { "cross-spawn": "^7.0.3", @@ -6849,9 +8015,9 @@ } }, "node_modules/lint-staged/node_modules/human-signals": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.0.tgz", - "integrity": "sha512-zyzVyMjpGBX2+6cDVZeFPCdtOtdsxOeseRhB9tkQ6xXmGUNrcnBzdEKPy3VPNYz+4gy1oukVOXcrJCunSyc6QQ==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz", + "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==", "dev": true, "engines": { "node": ">=14.18.0" @@ -6936,9 +8102,9 @@ } }, "node_modules/listr2": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-5.0.7.tgz", - "integrity": "sha512-MD+qXHPmtivrHIDRwPYdfNkrzqDiuaKU/rfBcec3WMyMF3xylQj3jMq344OtvQxz7zaCFViRAeqlr2AFhPvXHw==", + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-5.0.8.tgz", + "integrity": "sha512-mC73LitKHj9w6v30nLNGPetZIlfpUniNSsxxrbaPcWOjDb92SHPzJPi/t+v1YC/lxKz/AJ9egOjww0qUuFxBpA==", "dev": true, "dependencies": { "cli-truncate": "^2.1.0", @@ -7053,6 +8219,20 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "node_modules/lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==" + }, + "node_modules/log-driver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", + "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==", + "dev": true, + "engines": { + "node": ">=0.8.6" + } + }, "node_modules/log-update": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", @@ -7131,13 +8311,32 @@ "node": ">=8" } }, + "node_modules/loglevel": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.8.1.tgz", + "integrity": "sha512-tCRIJM51SHjAayKwC+QAg8hT8vg6z7GSgLJKGvzuPb1Wc+hLzqtuVLxp6/HzSPOozuK+8ErAhy7U/sVzw8Dgfg==", + "engines": { + "node": ">= 0.6.0" + }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/loglevel" + } + }, + "node_modules/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dependencies": { - "yallist": "^3.0.2" + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" } }, "node_modules/make-dir": { @@ -7304,9 +8503,9 @@ } }, "node_modules/minipass": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.4.tgz", - "integrity": "sha512-lwycX3cBMTvcejsHITUgYj6Gy6A7Nh4Q6h9NP4sTHY1ccJlC7yKzDmiShEHsJ16Jf1nKGDEaiHxiltsJEvk0nQ==", + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.5.tgz", + "integrity": "sha512-+yQl7SX3bIT83Lhb4BVorMAHVuqsskxRdlmO9kTpyukp8vsm2Sn/fUOV9xlnG8/a5JsypJzap21lz/y3FBMJ8Q==", "engines": { "node": ">=8" } @@ -7334,11 +8533,6 @@ "node": ">=8" } }, - "node_modules/minizlib/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, "node_modules/mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", @@ -7361,6 +8555,11 @@ "resolved": "https://registry.npmjs.org/module-alias/-/module-alias-2.2.2.tgz", "integrity": "sha512-A/78XjoX2EmNvppVWEhM2oGk3x4lLxnkEA4jTbaK97QKSDjkIoOsKQlfylt/d3kKKi596Qy3NP5XrXJ6fZIC9Q==" }, + "node_modules/mongo-round": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mongo-round/-/mongo-round-1.0.0.tgz", + "integrity": "sha512-lwvLJv827Uks+3HnTOt1I/Qr78Avke3du1oMaFqFpTwtRKtOposNOKkfpGXQN4ZGpRN3XAS8fEppIJ4TUj0xQw==" + }, "node_modules/mongodb": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-5.1.0.tgz", @@ -7403,150 +8602,26 @@ } }, "node_modules/mongodb-memory-server": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/mongodb-memory-server/-/mongodb-memory-server-8.12.0.tgz", - "integrity": "sha512-F5BLfliNiLK4FwpXbh4+F3UjvIHVq/G9GPob+xJMLWywRfSfH23cLPEmPuqqqPpOI/ROztUdaeAz8sn6U74kuQ==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "mongodb-memory-server-core": "8.12.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=12.22.0" - } - }, - "node_modules/mongodb-memory-server-core": { "version": "8.11.5", - "resolved": "https://registry.npmjs.org/mongodb-memory-server-core/-/mongodb-memory-server-core-8.11.5.tgz", - "integrity": "sha512-bhptlOruCEYrLofCbjACMoClgP1rFkhSNDzI/bbG/pUAg41UB00eaDPerYVvRf2jvOJqKF4+U9xqXiSvkbMvXw==", - "dev": true, - "dependencies": { - "@types/tmp": "^0.2.3", - "async-mutex": "^0.3.2", - "camelcase": "^6.3.0", - "debug": "^4.3.4", - "find-cache-dir": "^3.3.2", - "get-port": "^5.1.1", - "https-proxy-agent": "^5.0.1", - "md5-file": "^5.0.0", - "mongodb": "^4.13.0", - "new-find-package-json": "^2.0.0", - "semver": "^7.3.8", - "tar-stream": "^2.1.4", - "tmp": "^0.2.1", - "tslib": "^2.4.1", - "uuid": "^9.0.0", - "yauzl": "^2.10.0" - }, - "engines": { - "node": ">=12.22.0" - } - }, - "node_modules/mongodb-memory-server-core/node_modules/bson": { - "version": "4.7.2", - "resolved": "https://registry.npmjs.org/bson/-/bson-4.7.2.tgz", - "integrity": "sha512-Ry9wCtIZ5kGqkJoi6aD8KjxFZEx78guTQDnpXWiNthsxzrxAK/i8E6pCHAIZTbaEFWcOCvbecMukfK7XUvyLpQ==", - "dev": true, - "dependencies": { - "buffer": "^5.6.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/mongodb-memory-server-core/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mongodb-memory-server-core/node_modules/mongodb": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-4.14.0.tgz", - "integrity": "sha512-coGKkWXIBczZPr284tYKFLg+KbGPPLlSbdgfKAb6QqCFt5bo5VFZ50O3FFzsw4rnkqjwT6D8Qcoo9nshYKM7Mg==", - "dev": true, - "dependencies": { - "bson": "^4.7.0", - "mongodb-connection-string-url": "^2.5.4", - "socks": "^2.7.1" - }, - "engines": { - "node": ">=12.9.0" - }, - "optionalDependencies": { - "@aws-sdk/credential-providers": "^3.186.0", - "saslprep": "^1.0.3" - } - }, - "node_modules/mongodb-memory-server-global": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/mongodb-memory-server-global/-/mongodb-memory-server-global-8.12.0.tgz", - "integrity": "sha512-xNr6nMhQHFVWmciIoA9m5GAiETScEKoh+HFHEqYgLwc9/sfmF8fcvZNgQFVTUY4H9Ud0rQdUeUUkkfBzqqM82w==", + "resolved": "https://registry.npmjs.org/mongodb-memory-server/-/mongodb-memory-server-8.11.5.tgz", + "integrity": "sha512-/yiw3L2TIMpi9I6GXg379k6d+RG3k+9V9o24kK5h+NBTtYLNuWa5iEvtce/O3jqhg6yo31T5XG2e/Hm4UwBM1A==", "dev": true, "hasInstallScript": true, "dependencies": { - "mongodb-memory-server-core": "8.12.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=12.22.0" - } - }, - "node_modules/mongodb-memory-server-global/node_modules/bson": { - "version": "4.7.2", - "resolved": "https://registry.npmjs.org/bson/-/bson-4.7.2.tgz", - "integrity": "sha512-Ry9wCtIZ5kGqkJoi6aD8KjxFZEx78guTQDnpXWiNthsxzrxAK/i8E6pCHAIZTbaEFWcOCvbecMukfK7XUvyLpQ==", - "dev": true, - "dependencies": { - "buffer": "^5.6.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/mongodb-memory-server-global/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mongodb-memory-server-global/node_modules/mongodb": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-4.14.0.tgz", - "integrity": "sha512-coGKkWXIBczZPr284tYKFLg+KbGPPLlSbdgfKAb6QqCFt5bo5VFZ50O3FFzsw4rnkqjwT6D8Qcoo9nshYKM7Mg==", - "dev": true, - "dependencies": { - "bson": "^4.7.0", - "mongodb-connection-string-url": "^2.5.4", - "socks": "^2.7.1" - }, - "engines": { - "node": ">=12.9.0" - }, - "optionalDependencies": { - "@aws-sdk/credential-providers": "^3.186.0", - "saslprep": "^1.0.3" + "mongodb-memory-server-core": "8.11.5", + "tslib": "^2.4.1" + }, + "engines": { + "node": ">=12.22.0" } }, - "node_modules/mongodb-memory-server-global/node_modules/mongodb-memory-server-core": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/mongodb-memory-server-core/-/mongodb-memory-server-core-8.12.0.tgz", - "integrity": "sha512-p+4DbwMJAUqwv15w+WSFkFsGI9zjaUT0BJ1xkQd7sNkO8c9+3Ch5ZCH9AoTzbnNcvqHXj4rpj3VRJb8EZNMT3g==", + "node_modules/mongodb-memory-server-core": { + "version": "8.11.5", + "resolved": "https://registry.npmjs.org/mongodb-memory-server-core/-/mongodb-memory-server-core-8.11.5.tgz", + "integrity": "sha512-bhptlOruCEYrLofCbjACMoClgP1rFkhSNDzI/bbG/pUAg41UB00eaDPerYVvRf2jvOJqKF4+U9xqXiSvkbMvXw==", "dev": true, "dependencies": { + "@types/tmp": "^0.2.3", "async-mutex": "^0.3.2", "camelcase": "^6.3.0", "debug": "^4.3.4", @@ -7558,7 +8633,8 @@ "new-find-package-json": "^2.0.0", "semver": "^7.3.8", "tar-stream": "^2.1.4", - "tslib": "^2.5.0", + "tmp": "^0.2.1", + "tslib": "^2.4.1", "uuid": "^9.0.0", "yauzl": "^2.10.0" }, @@ -7566,7 +8642,7 @@ "node": ">=12.22.0" } }, - "node_modules/mongodb-memory-server/node_modules/bson": { + "node_modules/mongodb-memory-server-core/node_modules/bson": { "version": "4.7.2", "resolved": "https://registry.npmjs.org/bson/-/bson-4.7.2.tgz", "integrity": "sha512-Ry9wCtIZ5kGqkJoi6aD8KjxFZEx78guTQDnpXWiNthsxzrxAK/i8E6pCHAIZTbaEFWcOCvbecMukfK7XUvyLpQ==", @@ -7578,7 +8654,7 @@ "node": ">=6.9.0" } }, - "node_modules/mongodb-memory-server/node_modules/camelcase": { + "node_modules/mongodb-memory-server-core/node_modules/camelcase": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", @@ -7590,7 +8666,7 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mongodb-memory-server/node_modules/mongodb": { + "node_modules/mongodb-memory-server-core/node_modules/mongodb": { "version": "4.14.0", "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-4.14.0.tgz", "integrity": "sha512-coGKkWXIBczZPr284tYKFLg+KbGPPLlSbdgfKAb6QqCFt5bo5VFZ50O3FFzsw4rnkqjwT6D8Qcoo9nshYKM7Mg==", @@ -7608,47 +8684,11 @@ "saslprep": "^1.0.3" } }, - "node_modules/mongodb-memory-server/node_modules/mongodb-memory-server-core": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/mongodb-memory-server-core/-/mongodb-memory-server-core-8.12.0.tgz", - "integrity": "sha512-p+4DbwMJAUqwv15w+WSFkFsGI9zjaUT0BJ1xkQd7sNkO8c9+3Ch5ZCH9AoTzbnNcvqHXj4rpj3VRJb8EZNMT3g==", - "dev": true, - "dependencies": { - "async-mutex": "^0.3.2", - "camelcase": "^6.3.0", - "debug": "^4.3.4", - "find-cache-dir": "^3.3.2", - "get-port": "^5.1.1", - "https-proxy-agent": "^5.0.1", - "md5-file": "^5.0.0", - "mongodb": "^4.13.0", - "new-find-package-json": "^2.0.0", - "semver": "^7.3.8", - "tar-stream": "^2.1.4", - "tslib": "^2.5.0", - "uuid": "^9.0.0", - "yauzl": "^2.10.0" - }, - "engines": { - "node": ">=12.22.0" - } - }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, - "node_modules/mz": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "dev": true, - "dependencies": { - "any-promise": "^1.0.0", - "object-assign": "^4.0.1", - "thenify-all": "^1.0.0" - } - }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -7681,6 +8721,11 @@ "node": ">=12.22.0" } }, + "node_modules/node-abort-controller": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", + "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==" + }, "node_modules/node-addon-api": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", @@ -7736,6 +8781,78 @@ "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==", "dev": true }, + "node_modules/nodemon": { + "version": "2.0.21", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.21.tgz", + "integrity": "sha512-djN/n2549DUtY33S7o1djRCd7dEm0kBnj9c7S9XVXqRUbuggN1MZH/Nqa+5RFQr63Fbefq37nFXAE9VU86yL1A==", + "dependencies": { + "chokidar": "^3.5.2", + "debug": "^3.2.7", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.1.2", + "pstree.remy": "^1.1.8", + "semver": "^5.7.1", + "simple-update-notifier": "^1.0.7", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "bin": { + "nodemon": "bin/nodemon.js" + }, + "engines": { + "node": ">=8.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nodemon" + } + }, + "node_modules/nodemon/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/nodemon/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==", + "engines": { + "node": ">=4" + } + }, + "node_modules/nodemon/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/nodemon/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==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/noms": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/noms/-/noms-0.0.0.tgz", + "integrity": "sha512-lNDU9VJaOPxUmXcLb+HQFeUgQQPtMI24Gt6hgfuMHRJgMRHMF/qZ4HJD3GDru4sSw9IQl2jPjAYnQrdIeLbwow==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "readable-stream": "~1.0.31" + } + }, "node_modules/nopt": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", @@ -7754,7 +8871,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -7782,6 +8898,15 @@ "set-blocking": "^2.0.0" } }, + "node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -8062,6 +9187,12 @@ "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", "dev": true }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "dev": true + }, "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -8072,7 +9203,6 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, "engines": { "node": ">=8.6" }, @@ -8200,6 +9330,12 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "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 + }, "node_modules/prompts": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", @@ -8225,6 +9361,17 @@ "node": ">= 0.10" } }, + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", + "dev": true + }, + "node_modules/pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==" + }, "node_modules/punycode": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", @@ -8234,9 +9381,9 @@ } }, "node_modules/pure-rand": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.0.tgz", - "integrity": "sha512-rLSBxJjP+4DQOgcJAx6RZHT2he2pkhQdSnofG5VWyVl6GRq/K02ISOuOLcsMOrtKDIJb8JN2zm3FFzWNbezdPw==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.1.tgz", + "integrity": "sha512-t+x1zEHDjBwkDGY5v5ApnZ/utcd4XYDiJsaQQoptTXgUXX95sDg1elCdJghzicm7n2mbCBJ3uYWr6M22SO19rg==", "dev": true, "funding": [ { @@ -8292,9 +9439,9 @@ } }, "node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", @@ -8312,16 +9459,26 @@ "dev": true }, "node_modules/readable-stream": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.1.tgz", - "integrity": "sha512-+rQmrWMYGA90yenhTYsLWAsLsqVC8osOw6PKE1HDYiO0gdPeKe/xDHNzIAIn4C91YQ6oenEhfYqqc1883qHbjQ==", + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", + "dev": true, "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dependencies": { + "picomatch": "^2.2.1" }, "engines": { - "node": ">= 6" + "node": ">=8.10.0" } }, "node_modules/regexp.prototype.flags": { @@ -8353,6 +9510,57 @@ "url": "https://github.com/sponsors/mysticatea" } }, + "node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dev": true, + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/request/node_modules/qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/request/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -8431,6 +9639,14 @@ "node": ">=8" } }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "engines": { + "node": ">= 4" + } + }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -8475,9 +9691,9 @@ } }, "node_modules/rimraf/node_modules/glob": { - "version": "9.2.1", - "resolved": "https://registry.npmjs.org/glob/-/glob-9.2.1.tgz", - "integrity": "sha512-Pxxgq3W0HyA3XUvSXcFhRSs+43Jsx0ddxcFrbjxNGkL2Ak5BAUBxLqI5G6ADDeCHLfzzXFhe0b1yYcctGmytMA==", + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.1.tgz", + "integrity": "sha512-qERvJb7IGsnkx6YYmaaGvDpf77c951hICMdWaFXyH3PlVob8sbPJJyJX0kWkiCWyXUzoy9UOTNjGg0RbD8bYIw==", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", @@ -8603,22 +9819,6 @@ "node": ">=10" } }, - "node_modules/semver/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==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, "node_modules/send": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", @@ -8684,6 +9884,18 @@ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" }, + "node_modules/sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -8723,6 +9935,25 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, + "node_modules/simple-update-notifier": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz", + "integrity": "sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==", + "dependencies": { + "semver": "~7.0.0" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/simple-update-notifier/node_modules/semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", @@ -8822,6 +10053,31 @@ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, + "node_modules/sshpk": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", + "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", + "dev": true, + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/stack-utils": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", @@ -8852,12 +10108,10 @@ } }, "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", + "dev": true }, "node_modules/string-argv": { "version": "0.3.1", @@ -8925,6 +10179,23 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, + "node_modules/string.prototype.trim": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz", + "integrity": "sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/string.prototype.trimend": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", @@ -9000,56 +10271,6 @@ "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==", "optional": true }, - "node_modules/sucrase": { - "version": "3.29.0", - "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.29.0.tgz", - "integrity": "sha512-bZPAuGA5SdFHuzqIhTAqt9fvNEo9rESqXIG3oiKdF8K4UmkQxC4KlNL3lVyAErXp+mPvUqZ5l13qx6TrDIGf3A==", - "dev": true, - "dependencies": { - "commander": "^4.0.0", - "glob": "7.1.6", - "lines-and-columns": "^1.1.6", - "mz": "^2.7.0", - "pirates": "^4.0.1", - "ts-interface-checker": "^0.1.9" - }, - "bin": { - "sucrase": "bin/sucrase", - "sucrase-node": "bin/sucrase-node" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/sucrase/node_modules/commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/sucrase/node_modules/glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/superagent": { "version": "8.0.9", "resolved": "https://registry.npmjs.org/superagent/-/superagent-8.0.9.tgz", @@ -9071,6 +10292,20 @@ "node": ">=6.4.0 <13 || >=14" } }, + "node_modules/superagent/node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/superagent/node_modules/mime": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", @@ -9161,20 +10396,38 @@ "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", "dev": true, "dependencies": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", + "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, + "dependencies": { "inherits": "^2.0.3", - "readable-stream": "^3.1.1" + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" }, "engines": { - "node": ">=6" + "node": ">= 6" } }, - "node_modules/tar/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "node_modules/tar-stream/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } }, "node_modules/test-exclude": { "version": "6.0.0", @@ -9196,33 +10449,58 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, - "node_modules/thenify": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", - "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, + "node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", "dev": true, "dependencies": { - "any-promise": "^1.0.0" + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" } }, - "node_modules/thenify-all": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "node_modules/through2/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 + }, + "node_modules/through2/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, "dependencies": { - "thenify": ">= 3.1.0 < 4" - }, - "engines": { - "node": ">=0.8" + "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/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "node_modules/through2/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 }, + "node_modules/through2/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, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/tmp": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", @@ -9269,7 +10547,6 @@ "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, "dependencies": { "is-number": "^7.0.0" }, @@ -9285,6 +10562,44 @@ "node": ">=0.6" } }, + "node_modules/touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dependencies": { + "nopt": "~1.0.10" + }, + "bin": { + "nodetouch": "bin/nodetouch.js" + } + }, + "node_modules/touch/node_modules/nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/tr46": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", @@ -9296,12 +10611,6 @@ "node": ">=12" } }, - "node_modules/ts-interface-checker": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", - "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", - "dev": true - }, "node_modules/ts-jest": { "version": "29.0.5", "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.0.5.tgz", @@ -9345,49 +10654,6 @@ } } }, - "node_modules/ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", - "dev": true, - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, "node_modules/tsconfig-paths": { "version": "3.14.2", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", @@ -9424,8 +10690,7 @@ "node_modules/tslib": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", - "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==", - "devOptional": true + "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==" }, "node_modules/tsutils": { "version": "3.21.0", @@ -9448,6 +10713,24 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, + "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, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", + "dev": true + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -9508,16 +10791,16 @@ } }, "node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.2.tgz", + "integrity": "sha512-wVORMBGO/FAs/++blGNeAVdbNKtIh1rbBL2EyQ1+J9lClJ93KiiKe8PmFIVdXhHcyv44SL9oglmfeSsndo0jRw==", "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { - "node": ">=4.2.0" + "node": ">=12.20" } }, "node_modules/unbox-primitive": { @@ -9535,6 +10818,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==" + }, "node_modules/underscore": { "version": "1.13.6", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", @@ -9549,6 +10837,15 @@ "node": ">= 0.8" } }, + "node_modules/untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/update-browserslist-db": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", @@ -9601,17 +10898,10 @@ "version": "9.0.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", - "dev": true, "bin": { "uuid": "dist/bin/uuid" } }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true - }, "node_modules/v8-to-istanbul": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz", @@ -9640,6 +10930,14 @@ "node": ">= 0.10" } }, + "node_modules/value-or-promise": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/value-or-promise/-/value-or-promise-1.0.12.tgz", + "integrity": "sha512-Z6Uz+TYwEqE7ZN50gwn+1LCVo9ZVrpxRPOhOLnncYkY1ZzOYtrX8Fwf/rFktZ8R5mJms6EZf5TqNOMeZmnPq9Q==", + "engines": { + "node": ">=12" + } + }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -9648,6 +10946,26 @@ "node": ">= 0.8" } }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/verror/node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "dev": true + }, "node_modules/walker": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", @@ -9665,6 +10983,14 @@ "node": ">=12" } }, + "node_modules/whatwg-mimetype": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", + "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", + "engines": { + "node": ">=12" + } + }, "node_modules/whatwg-url": { "version": "11.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", @@ -9835,6 +11161,35 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, + "node_modules/xss": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/xss/-/xss-1.0.14.tgz", + "integrity": "sha512-og7TEJhXvn1a7kzZGQ7ETjdQVS2UfZyTlsEdDOqvQF7GoxNfY+0YLCzBy1kPdsDDx4QuNAonQPddpsn6Xl/7sw==", + "dependencies": { + "commander": "^2.20.3", + "cssfilter": "0.0.10" + }, + "bin": { + "xss": "bin/xss" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/xss/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "engines": { + "node": ">=0.4" + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -9845,10 +11200,9 @@ } }, "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/yaml": { "version": "2.2.1", @@ -9860,21 +11214,21 @@ } }, "node_modules/yargs": { - "version": "17.7.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", - "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "dependencies": { - "cliui": "^8.0.1", + "cliui": "^7.0.2", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "string-width": "^4.2.3", + "string-width": "^4.2.0", "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" + "yargs-parser": "^20.2.2" }, "engines": { - "node": ">=12" + "node": ">=10" } }, "node_modules/yargs-parser": { @@ -9915,6 +11269,15 @@ "node": ">=8" } }, + "node_modules/yargs/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, + "engines": { + "node": ">=10" + } + }, "node_modules/yauzl": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", @@ -9925,15 +11288,6 @@ "fd-slicer": "~1.1.0" } }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", @@ -9958,6 +11312,113 @@ "@jridgewell/trace-mapping": "^0.3.9" } }, + "@apollo/protobufjs": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@apollo/protobufjs/-/protobufjs-1.2.7.tgz", + "integrity": "sha512-Lahx5zntHPZia35myYDBRuF58tlwPskwHc5CWBZC/4bMKB6siTBWwtMrkqXcsNwQiFSzSx5hKdRPUmemrEp3Gg==", + "requires": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.0", + "long": "^4.0.0" + } + }, + "@apollo/usage-reporting-protobuf": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@apollo/usage-reporting-protobuf/-/usage-reporting-protobuf-4.1.0.tgz", + "integrity": "sha512-hXouMuw5pQVkzi8dgMybmr6Y11+eRmMQVoB5TF0HyTwAg9SOq/v3OCuiYqcVUKdBcskU9Msp+XvjAk0GKpWCwQ==", + "requires": { + "@apollo/protobufjs": "1.2.7" + } + }, + "@apollo/utils.dropunuseddefinitions": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@apollo/utils.dropunuseddefinitions/-/utils.dropunuseddefinitions-1.1.0.tgz", + "integrity": "sha512-jU1XjMr6ec9pPoL+BFWzEPW7VHHulVdGKMkPAMiCigpVIT11VmCbnij0bWob8uS3ODJ65tZLYKAh/55vLw2rbg==", + "requires": {} + }, + "@apollo/utils.keyvaluecache": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@apollo/utils.keyvaluecache/-/utils.keyvaluecache-1.0.2.tgz", + "integrity": "sha512-p7PVdLPMnPzmXSQVEsy27cYEjVON+SH/Wb7COyW3rQN8+wJgT1nv9jZouYtztWW8ZgTkii5T6tC9qfoDREd4mg==", + "requires": { + "@apollo/utils.logger": "^1.0.0", + "lru-cache": "7.10.1 - 7.13.1" + }, + "dependencies": { + "lru-cache": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.13.1.tgz", + "integrity": "sha512-CHqbAq7NFlW3RSnoWXLJBxCWaZVBrfa9UEHId2M3AW8iEBurbqduNexEUCGc3SHc6iCYXNJCDi903LajSVAEPQ==" + } + } + }, + "@apollo/utils.logger": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.logger/-/utils.logger-1.0.1.tgz", + "integrity": "sha512-XdlzoY7fYNK4OIcvMD2G94RoFZbzTQaNP0jozmqqMudmaGo2I/2Jx71xlDJ801mWA/mbYRihyaw6KJii7k5RVA==" + }, + "@apollo/utils.printwithreducedwhitespace": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@apollo/utils.printwithreducedwhitespace/-/utils.printwithreducedwhitespace-1.1.0.tgz", + "integrity": "sha512-GfFSkAv3n1toDZ4V6u2d7L4xMwLA+lv+6hqXicMN9KELSJ9yy9RzuEXaX73c/Ry+GzRsBy/fdSUGayGqdHfT2Q==", + "requires": {} + }, + "@apollo/utils.removealiases": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@apollo/utils.removealiases/-/utils.removealiases-1.0.0.tgz", + "integrity": "sha512-6cM8sEOJW2LaGjL/0vHV0GtRaSekrPQR4DiywaApQlL9EdROASZU5PsQibe2MWeZCOhNrPRuHh4wDMwPsWTn8A==", + "requires": {} + }, + "@apollo/utils.sortast": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@apollo/utils.sortast/-/utils.sortast-1.1.0.tgz", + "integrity": "sha512-VPlTsmUnOwzPK5yGZENN069y6uUHgeiSlpEhRnLFYwYNoJHsuJq2vXVwIaSmts015WTPa2fpz1inkLYByeuRQA==", + "requires": { + "lodash.sortby": "^4.7.0" + } + }, + "@apollo/utils.stripsensitiveliterals": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@apollo/utils.stripsensitiveliterals/-/utils.stripsensitiveliterals-1.2.0.tgz", + "integrity": "sha512-E41rDUzkz/cdikM5147d8nfCFVKovXxKBcjvLEQ7bjZm/cg9zEcXvS6vFY8ugTubI3fn6zoqo0CyU8zT+BGP9w==", + "requires": {} + }, + "@apollo/utils.usagereporting": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.usagereporting/-/utils.usagereporting-1.0.1.tgz", + "integrity": "sha512-6dk+0hZlnDbahDBB2mP/PZ5ybrtCJdLMbeNJD+TJpKyZmSY6bA3SjI8Cr2EM9QA+AdziywuWg+SgbWUF3/zQqQ==", + "requires": { + "@apollo/usage-reporting-protobuf": "^4.0.0", + "@apollo/utils.dropunuseddefinitions": "^1.1.0", + "@apollo/utils.printwithreducedwhitespace": "^1.1.0", + "@apollo/utils.removealiases": "1.0.0", + "@apollo/utils.sortast": "^1.1.0", + "@apollo/utils.stripsensitiveliterals": "^1.2.0" + } + }, + "@apollographql/apollo-tools": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/@apollographql/apollo-tools/-/apollo-tools-0.5.4.tgz", + "integrity": "sha512-shM3q7rUbNyXVVRkQJQseXv6bnYM3BUma/eZhwXR4xsuM+bqWnJKvW7SAfRjP7LuSCocrexa5AXhjjawNHrIlw==", + "requires": {} + }, + "@apollographql/graphql-playground-html": { + "version": "1.6.29", + "resolved": "https://registry.npmjs.org/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.29.tgz", + "integrity": "sha512-xCcXpoz52rI4ksJSdOCxeOCn2DLocxwHf9dVT/Q90Pte1LX+LY+91SFtJF3KXVHH8kEin+g1KKCQPKBjZJfWNA==", + "requires": { + "xss": "^1.0.8" + } + }, "@aws-crypto/ie11-detection": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@aws-crypto/ie11-detection/-/ie11-detection-3.0.0.tgz", @@ -10055,441 +11516,441 @@ } }, "@aws-sdk/abort-controller": { - "version": "3.272.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/abort-controller/-/abort-controller-3.272.0.tgz", - "integrity": "sha512-s2TV3phapcTwZNr4qLxbfuQuE9ZMP4RoJdkvRRCkKdm6jslsWLJf2Zlcxti/23hOlINUMYv2iXE2pftIgWGdpg==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/abort-controller/-/abort-controller-3.295.0.tgz", + "integrity": "sha512-uohsGotvQ8RTgVZ9sQt0y3L60jBEYgN8MOn3Seaku8HpIIo9c6iIfkF0bMXZeFI2sCxqbrBDbsPKYWxr7rd8LA==", "optional": true, "requires": { - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" } }, "@aws-sdk/client-cognito-identity": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.282.0.tgz", - "integrity": "sha512-OU9Wy50u31Mog4xmj9o+lLOb/y+yuQBTFwEVYApJtCkPsI2e3DtZFt36IcAy04fcjNUaSD3u6SGgfYo2vDQ2zA==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.295.0.tgz", + "integrity": "sha512-W17vm7epIEHT7Lr12T0xTAipze4dyS5u6onLV7Sx+5tEiMObmkfkXQsjCheMqHD7pGEJNZqAvY43GeirtzOlSw==", "optional": true, "requires": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/client-sts": "3.282.0", - "@aws-sdk/config-resolver": "3.282.0", - "@aws-sdk/credential-provider-node": "3.282.0", - "@aws-sdk/fetch-http-handler": "3.282.0", - "@aws-sdk/hash-node": "3.272.0", - "@aws-sdk/invalid-dependency": "3.272.0", - "@aws-sdk/middleware-content-length": "3.282.0", - "@aws-sdk/middleware-endpoint": "3.282.0", - "@aws-sdk/middleware-host-header": "3.282.0", - "@aws-sdk/middleware-logger": "3.272.0", - "@aws-sdk/middleware-recursion-detection": "3.282.0", - "@aws-sdk/middleware-retry": "3.282.0", - "@aws-sdk/middleware-serde": "3.272.0", - "@aws-sdk/middleware-signing": "3.282.0", - "@aws-sdk/middleware-stack": "3.272.0", - "@aws-sdk/middleware-user-agent": "3.282.0", - "@aws-sdk/node-config-provider": "3.272.0", - "@aws-sdk/node-http-handler": "3.282.0", - "@aws-sdk/protocol-http": "3.282.0", - "@aws-sdk/smithy-client": "3.279.0", - "@aws-sdk/types": "3.272.0", - "@aws-sdk/url-parser": "3.272.0", - "@aws-sdk/util-base64": "3.208.0", - "@aws-sdk/util-body-length-browser": "3.188.0", - "@aws-sdk/util-body-length-node": "3.208.0", - "@aws-sdk/util-defaults-mode-browser": "3.279.0", - "@aws-sdk/util-defaults-mode-node": "3.282.0", - "@aws-sdk/util-endpoints": "3.272.0", - "@aws-sdk/util-retry": "3.272.0", - "@aws-sdk/util-user-agent-browser": "3.282.0", - "@aws-sdk/util-user-agent-node": "3.282.0", - "@aws-sdk/util-utf8": "3.254.0", - "tslib": "^2.3.1" + "@aws-sdk/client-sts": "3.295.0", + "@aws-sdk/config-resolver": "3.295.0", + "@aws-sdk/credential-provider-node": "3.295.0", + "@aws-sdk/fetch-http-handler": "3.295.0", + "@aws-sdk/hash-node": "3.295.0", + "@aws-sdk/invalid-dependency": "3.295.0", + "@aws-sdk/middleware-content-length": "3.295.0", + "@aws-sdk/middleware-endpoint": "3.295.0", + "@aws-sdk/middleware-host-header": "3.295.0", + "@aws-sdk/middleware-logger": "3.295.0", + "@aws-sdk/middleware-recursion-detection": "3.295.0", + "@aws-sdk/middleware-retry": "3.295.0", + "@aws-sdk/middleware-serde": "3.295.0", + "@aws-sdk/middleware-signing": "3.295.0", + "@aws-sdk/middleware-stack": "3.295.0", + "@aws-sdk/middleware-user-agent": "3.295.0", + "@aws-sdk/node-config-provider": "3.295.0", + "@aws-sdk/node-http-handler": "3.295.0", + "@aws-sdk/protocol-http": "3.295.0", + "@aws-sdk/smithy-client": "3.295.0", + "@aws-sdk/types": "3.295.0", + "@aws-sdk/url-parser": "3.295.0", + "@aws-sdk/util-base64": "3.295.0", + "@aws-sdk/util-body-length-browser": "3.295.0", + "@aws-sdk/util-body-length-node": "3.295.0", + "@aws-sdk/util-defaults-mode-browser": "3.295.0", + "@aws-sdk/util-defaults-mode-node": "3.295.0", + "@aws-sdk/util-endpoints": "3.295.0", + "@aws-sdk/util-retry": "3.295.0", + "@aws-sdk/util-user-agent-browser": "3.295.0", + "@aws-sdk/util-user-agent-node": "3.295.0", + "@aws-sdk/util-utf8": "3.295.0", + "tslib": "^2.5.0" } }, "@aws-sdk/client-sso": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.282.0.tgz", - "integrity": "sha512-VzdCCaxlDyU+7wvLDWh+uACQ6RPfaKLQ3yJ2UY0B0SkH4R0E4GLDJ2OJzqS5eyyOsnq1rxfY75S4WYzj8E2cvg==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.295.0.tgz", + "integrity": "sha512-uNEchm1LAQHP2/S21jz0NxCe8yqUe3J1jZG3N/dwx7uKVndHomTmjBsClGxT8IL9hC/Xl57G+fEpTCrFMjUR2g==", "optional": true, "requires": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/config-resolver": "3.282.0", - "@aws-sdk/fetch-http-handler": "3.282.0", - "@aws-sdk/hash-node": "3.272.0", - "@aws-sdk/invalid-dependency": "3.272.0", - "@aws-sdk/middleware-content-length": "3.282.0", - "@aws-sdk/middleware-endpoint": "3.282.0", - "@aws-sdk/middleware-host-header": "3.282.0", - "@aws-sdk/middleware-logger": "3.272.0", - "@aws-sdk/middleware-recursion-detection": "3.282.0", - "@aws-sdk/middleware-retry": "3.282.0", - "@aws-sdk/middleware-serde": "3.272.0", - "@aws-sdk/middleware-stack": "3.272.0", - "@aws-sdk/middleware-user-agent": "3.282.0", - "@aws-sdk/node-config-provider": "3.272.0", - "@aws-sdk/node-http-handler": "3.282.0", - "@aws-sdk/protocol-http": "3.282.0", - "@aws-sdk/smithy-client": "3.279.0", - "@aws-sdk/types": "3.272.0", - "@aws-sdk/url-parser": "3.272.0", - "@aws-sdk/util-base64": "3.208.0", - "@aws-sdk/util-body-length-browser": "3.188.0", - "@aws-sdk/util-body-length-node": "3.208.0", - "@aws-sdk/util-defaults-mode-browser": "3.279.0", - "@aws-sdk/util-defaults-mode-node": "3.282.0", - "@aws-sdk/util-endpoints": "3.272.0", - "@aws-sdk/util-retry": "3.272.0", - "@aws-sdk/util-user-agent-browser": "3.282.0", - "@aws-sdk/util-user-agent-node": "3.282.0", - "@aws-sdk/util-utf8": "3.254.0", - "tslib": "^2.3.1" + "@aws-sdk/config-resolver": "3.295.0", + "@aws-sdk/fetch-http-handler": "3.295.0", + "@aws-sdk/hash-node": "3.295.0", + "@aws-sdk/invalid-dependency": "3.295.0", + "@aws-sdk/middleware-content-length": "3.295.0", + "@aws-sdk/middleware-endpoint": "3.295.0", + "@aws-sdk/middleware-host-header": "3.295.0", + "@aws-sdk/middleware-logger": "3.295.0", + "@aws-sdk/middleware-recursion-detection": "3.295.0", + "@aws-sdk/middleware-retry": "3.295.0", + "@aws-sdk/middleware-serde": "3.295.0", + "@aws-sdk/middleware-stack": "3.295.0", + "@aws-sdk/middleware-user-agent": "3.295.0", + "@aws-sdk/node-config-provider": "3.295.0", + "@aws-sdk/node-http-handler": "3.295.0", + "@aws-sdk/protocol-http": "3.295.0", + "@aws-sdk/smithy-client": "3.295.0", + "@aws-sdk/types": "3.295.0", + "@aws-sdk/url-parser": "3.295.0", + "@aws-sdk/util-base64": "3.295.0", + "@aws-sdk/util-body-length-browser": "3.295.0", + "@aws-sdk/util-body-length-node": "3.295.0", + "@aws-sdk/util-defaults-mode-browser": "3.295.0", + "@aws-sdk/util-defaults-mode-node": "3.295.0", + "@aws-sdk/util-endpoints": "3.295.0", + "@aws-sdk/util-retry": "3.295.0", + "@aws-sdk/util-user-agent-browser": "3.295.0", + "@aws-sdk/util-user-agent-node": "3.295.0", + "@aws-sdk/util-utf8": "3.295.0", + "tslib": "^2.5.0" } }, "@aws-sdk/client-sso-oidc": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.282.0.tgz", - "integrity": "sha512-upC4yBZllAXg5OVIuS8Lu9MI1aqfAObl2BBixj9fIYbDanQ02s0b1IwfZqlOqNNkGzMko1AWyiOSyOdVgyJ+xg==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.295.0.tgz", + "integrity": "sha512-HijuG2OAmTy0Wa3JHgIMBrBlsWC6GjWkH8KcRIGbFUH2nW8LFh3gBKuB1oubZ4wAdOIBFNECWA6FKFayFlKmew==", "optional": true, "requires": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/config-resolver": "3.282.0", - "@aws-sdk/fetch-http-handler": "3.282.0", - "@aws-sdk/hash-node": "3.272.0", - "@aws-sdk/invalid-dependency": "3.272.0", - "@aws-sdk/middleware-content-length": "3.282.0", - "@aws-sdk/middleware-endpoint": "3.282.0", - "@aws-sdk/middleware-host-header": "3.282.0", - "@aws-sdk/middleware-logger": "3.272.0", - "@aws-sdk/middleware-recursion-detection": "3.282.0", - "@aws-sdk/middleware-retry": "3.282.0", - "@aws-sdk/middleware-serde": "3.272.0", - "@aws-sdk/middleware-stack": "3.272.0", - "@aws-sdk/middleware-user-agent": "3.282.0", - "@aws-sdk/node-config-provider": "3.272.0", - "@aws-sdk/node-http-handler": "3.282.0", - "@aws-sdk/protocol-http": "3.282.0", - "@aws-sdk/smithy-client": "3.279.0", - "@aws-sdk/types": "3.272.0", - "@aws-sdk/url-parser": "3.272.0", - "@aws-sdk/util-base64": "3.208.0", - "@aws-sdk/util-body-length-browser": "3.188.0", - "@aws-sdk/util-body-length-node": "3.208.0", - "@aws-sdk/util-defaults-mode-browser": "3.279.0", - "@aws-sdk/util-defaults-mode-node": "3.282.0", - "@aws-sdk/util-endpoints": "3.272.0", - "@aws-sdk/util-retry": "3.272.0", - "@aws-sdk/util-user-agent-browser": "3.282.0", - "@aws-sdk/util-user-agent-node": "3.282.0", - "@aws-sdk/util-utf8": "3.254.0", - "tslib": "^2.3.1" + "@aws-sdk/config-resolver": "3.295.0", + "@aws-sdk/fetch-http-handler": "3.295.0", + "@aws-sdk/hash-node": "3.295.0", + "@aws-sdk/invalid-dependency": "3.295.0", + "@aws-sdk/middleware-content-length": "3.295.0", + "@aws-sdk/middleware-endpoint": "3.295.0", + "@aws-sdk/middleware-host-header": "3.295.0", + "@aws-sdk/middleware-logger": "3.295.0", + "@aws-sdk/middleware-recursion-detection": "3.295.0", + "@aws-sdk/middleware-retry": "3.295.0", + "@aws-sdk/middleware-serde": "3.295.0", + "@aws-sdk/middleware-stack": "3.295.0", + "@aws-sdk/middleware-user-agent": "3.295.0", + "@aws-sdk/node-config-provider": "3.295.0", + "@aws-sdk/node-http-handler": "3.295.0", + "@aws-sdk/protocol-http": "3.295.0", + "@aws-sdk/smithy-client": "3.295.0", + "@aws-sdk/types": "3.295.0", + "@aws-sdk/url-parser": "3.295.0", + "@aws-sdk/util-base64": "3.295.0", + "@aws-sdk/util-body-length-browser": "3.295.0", + "@aws-sdk/util-body-length-node": "3.295.0", + "@aws-sdk/util-defaults-mode-browser": "3.295.0", + "@aws-sdk/util-defaults-mode-node": "3.295.0", + "@aws-sdk/util-endpoints": "3.295.0", + "@aws-sdk/util-retry": "3.295.0", + "@aws-sdk/util-user-agent-browser": "3.295.0", + "@aws-sdk/util-user-agent-node": "3.295.0", + "@aws-sdk/util-utf8": "3.295.0", + "tslib": "^2.5.0" } }, "@aws-sdk/client-sts": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.282.0.tgz", - "integrity": "sha512-JZybEaST0rloS9drlX/0yJAnKHuV7DlS1n1WZxgaM2DY704ydlGiviiPQvC/q/dItsX4017gscC0blGJcUjK1g==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.295.0.tgz", + "integrity": "sha512-KrLnG5EcXvry9tmsTAONhlj60F0+Z7P2PtT0XDsS8pLayHAtd9lKXsf14DOSQa9+LbPLMFbfLbuSwvPYvgxMzg==", "optional": true, "requires": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/config-resolver": "3.282.0", - "@aws-sdk/credential-provider-node": "3.282.0", - "@aws-sdk/fetch-http-handler": "3.282.0", - "@aws-sdk/hash-node": "3.272.0", - "@aws-sdk/invalid-dependency": "3.272.0", - "@aws-sdk/middleware-content-length": "3.282.0", - "@aws-sdk/middleware-endpoint": "3.282.0", - "@aws-sdk/middleware-host-header": "3.282.0", - "@aws-sdk/middleware-logger": "3.272.0", - "@aws-sdk/middleware-recursion-detection": "3.282.0", - "@aws-sdk/middleware-retry": "3.282.0", - "@aws-sdk/middleware-sdk-sts": "3.282.0", - "@aws-sdk/middleware-serde": "3.272.0", - "@aws-sdk/middleware-signing": "3.282.0", - "@aws-sdk/middleware-stack": "3.272.0", - "@aws-sdk/middleware-user-agent": "3.282.0", - "@aws-sdk/node-config-provider": "3.272.0", - "@aws-sdk/node-http-handler": "3.282.0", - "@aws-sdk/protocol-http": "3.282.0", - "@aws-sdk/smithy-client": "3.279.0", - "@aws-sdk/types": "3.272.0", - "@aws-sdk/url-parser": "3.272.0", - "@aws-sdk/util-base64": "3.208.0", - "@aws-sdk/util-body-length-browser": "3.188.0", - "@aws-sdk/util-body-length-node": "3.208.0", - "@aws-sdk/util-defaults-mode-browser": "3.279.0", - "@aws-sdk/util-defaults-mode-node": "3.282.0", - "@aws-sdk/util-endpoints": "3.272.0", - "@aws-sdk/util-retry": "3.272.0", - "@aws-sdk/util-user-agent-browser": "3.282.0", - "@aws-sdk/util-user-agent-node": "3.282.0", - "@aws-sdk/util-utf8": "3.254.0", + "@aws-sdk/config-resolver": "3.295.0", + "@aws-sdk/credential-provider-node": "3.295.0", + "@aws-sdk/fetch-http-handler": "3.295.0", + "@aws-sdk/hash-node": "3.295.0", + "@aws-sdk/invalid-dependency": "3.295.0", + "@aws-sdk/middleware-content-length": "3.295.0", + "@aws-sdk/middleware-endpoint": "3.295.0", + "@aws-sdk/middleware-host-header": "3.295.0", + "@aws-sdk/middleware-logger": "3.295.0", + "@aws-sdk/middleware-recursion-detection": "3.295.0", + "@aws-sdk/middleware-retry": "3.295.0", + "@aws-sdk/middleware-sdk-sts": "3.295.0", + "@aws-sdk/middleware-serde": "3.295.0", + "@aws-sdk/middleware-signing": "3.295.0", + "@aws-sdk/middleware-stack": "3.295.0", + "@aws-sdk/middleware-user-agent": "3.295.0", + "@aws-sdk/node-config-provider": "3.295.0", + "@aws-sdk/node-http-handler": "3.295.0", + "@aws-sdk/protocol-http": "3.295.0", + "@aws-sdk/smithy-client": "3.295.0", + "@aws-sdk/types": "3.295.0", + "@aws-sdk/url-parser": "3.295.0", + "@aws-sdk/util-base64": "3.295.0", + "@aws-sdk/util-body-length-browser": "3.295.0", + "@aws-sdk/util-body-length-node": "3.295.0", + "@aws-sdk/util-defaults-mode-browser": "3.295.0", + "@aws-sdk/util-defaults-mode-node": "3.295.0", + "@aws-sdk/util-endpoints": "3.295.0", + "@aws-sdk/util-retry": "3.295.0", + "@aws-sdk/util-user-agent-browser": "3.295.0", + "@aws-sdk/util-user-agent-node": "3.295.0", + "@aws-sdk/util-utf8": "3.295.0", "fast-xml-parser": "4.1.2", - "tslib": "^2.3.1" + "tslib": "^2.5.0" } }, "@aws-sdk/config-resolver": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/config-resolver/-/config-resolver-3.282.0.tgz", - "integrity": "sha512-30qFLh2N4NXQ2EAook7NIFeu1K/nlrRLrdVb2BtGFi/F3cZnz+sy9o0XmL6x+sO9TznWjdNxD1RKQdqoAwGnCQ==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/config-resolver/-/config-resolver-3.295.0.tgz", + "integrity": "sha512-oSGdGAjmOesxGAT/Ce8P7Gdvf4KVQjasKqmlAMTXsUBxh8Mx8BQH9V3UCiCdfJ2Vx7H4pqN4Y8WcAQkje4uvbQ==", "optional": true, "requires": { - "@aws-sdk/signature-v4": "3.282.0", - "@aws-sdk/types": "3.272.0", - "@aws-sdk/util-config-provider": "3.208.0", - "@aws-sdk/util-middleware": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/signature-v4": "3.295.0", + "@aws-sdk/types": "3.295.0", + "@aws-sdk/util-config-provider": "3.295.0", + "@aws-sdk/util-middleware": "3.295.0", + "tslib": "^2.5.0" } }, "@aws-sdk/credential-provider-cognito-identity": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.282.0.tgz", - "integrity": "sha512-GsLOt6GzckLQbMzgXOblKcRtXyMu3NcP0vFkYpy4r9oEzoxqPhy1yUpRNLeDv7r2qoa8naN81F5FwPwd17PrKg==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.295.0.tgz", + "integrity": "sha512-1cqqctA2UdzeV+jCg3vk5yIbkT9JX0M+xtyPcsIcKqwBHEl48SCmLUTs6C7ZpcRS61vlkvE0bTEq+EfMCxuaDw==", "optional": true, "requires": { - "@aws-sdk/client-cognito-identity": "3.282.0", - "@aws-sdk/property-provider": "3.272.0", - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/client-cognito-identity": "3.295.0", + "@aws-sdk/property-provider": "3.295.0", + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" } }, "@aws-sdk/credential-provider-env": { - "version": "3.272.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.272.0.tgz", - "integrity": "sha512-QI65NbLnKLYHyTYhXaaUrq6eVsCCrMUb05WDA7+TJkWkjXesovpjc8vUKgFiLSxmgKmb2uOhHNcDyObKMrYQFw==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.295.0.tgz", + "integrity": "sha512-YjUDJwhgwUgFYT4fJQVCMA1Abw2Jw1xC3EeNxeV2L54CvM9PlbFuRa5qJehePKoTLyva4bjLsMXsensXrEEIGQ==", "optional": true, "requires": { - "@aws-sdk/property-provider": "3.272.0", - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/property-provider": "3.295.0", + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" } }, "@aws-sdk/credential-provider-imds": { - "version": "3.272.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-imds/-/credential-provider-imds-3.272.0.tgz", - "integrity": "sha512-wwAfVY1jTFQEfxVfdYD5r5ieYGl+0g4nhekVxNMqE8E1JeRDd18OqiwAflzpgBIqxfqvCUkf+vl5JYyacMkNAQ==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-imds/-/credential-provider-imds-3.295.0.tgz", + "integrity": "sha512-+tOVCZi7LUG2pvjK9P35hhXL1cZTJsbGtrMsIxrlUODjKEhht4RSiQH7zT324x6MkYby9iLjU4SUejyKBKDhYQ==", "optional": true, "requires": { - "@aws-sdk/node-config-provider": "3.272.0", - "@aws-sdk/property-provider": "3.272.0", - "@aws-sdk/types": "3.272.0", - "@aws-sdk/url-parser": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/node-config-provider": "3.295.0", + "@aws-sdk/property-provider": "3.295.0", + "@aws-sdk/types": "3.295.0", + "@aws-sdk/url-parser": "3.295.0", + "tslib": "^2.5.0" } }, "@aws-sdk/credential-provider-ini": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.282.0.tgz", - "integrity": "sha512-2GKduXORcUgOigF1jZF7A1Wh4W/aJt3ynh7xb1vfx020nHx6YDljrEGpzgH6pOVzl7ZhgthpojicCuy2UumkMA==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.295.0.tgz", + "integrity": "sha512-XU3UqVVxxjyXcZ2Wkx3CM+/eLUM/EDlqJkLU6nl3FDGzPZeXC3G9Z9ZywGBo7dpRbBpDfpzSSukJisiGLTwg2w==", "optional": true, "requires": { - "@aws-sdk/credential-provider-env": "3.272.0", - "@aws-sdk/credential-provider-imds": "3.272.0", - "@aws-sdk/credential-provider-process": "3.272.0", - "@aws-sdk/credential-provider-sso": "3.282.0", - "@aws-sdk/credential-provider-web-identity": "3.272.0", - "@aws-sdk/property-provider": "3.272.0", - "@aws-sdk/shared-ini-file-loader": "3.272.0", - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/credential-provider-env": "3.295.0", + "@aws-sdk/credential-provider-imds": "3.295.0", + "@aws-sdk/credential-provider-process": "3.295.0", + "@aws-sdk/credential-provider-sso": "3.295.0", + "@aws-sdk/credential-provider-web-identity": "3.295.0", + "@aws-sdk/property-provider": "3.295.0", + "@aws-sdk/shared-ini-file-loader": "3.295.0", + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" } }, "@aws-sdk/credential-provider-node": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.282.0.tgz", - "integrity": "sha512-qyHipZW0ep8STY+SO+Me8ObQ1Ee/aaZTmAK0Os/gB+EsiZhIE+mi6zRcScwdnpgJPLRYMEe4p/Cr6DOrA0G0GQ==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.295.0.tgz", + "integrity": "sha512-dU+nDJJKCyx/YBKeGgSuFM1okdoNVGWLTzrkPohPGy5+KnPaFCscrqRe2ni0ihQscguwSFXygV5SQoYNp1FGwA==", "optional": true, "requires": { - "@aws-sdk/credential-provider-env": "3.272.0", - "@aws-sdk/credential-provider-imds": "3.272.0", - "@aws-sdk/credential-provider-ini": "3.282.0", - "@aws-sdk/credential-provider-process": "3.272.0", - "@aws-sdk/credential-provider-sso": "3.282.0", - "@aws-sdk/credential-provider-web-identity": "3.272.0", - "@aws-sdk/property-provider": "3.272.0", - "@aws-sdk/shared-ini-file-loader": "3.272.0", - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/credential-provider-env": "3.295.0", + "@aws-sdk/credential-provider-imds": "3.295.0", + "@aws-sdk/credential-provider-ini": "3.295.0", + "@aws-sdk/credential-provider-process": "3.295.0", + "@aws-sdk/credential-provider-sso": "3.295.0", + "@aws-sdk/credential-provider-web-identity": "3.295.0", + "@aws-sdk/property-provider": "3.295.0", + "@aws-sdk/shared-ini-file-loader": "3.295.0", + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" } }, "@aws-sdk/credential-provider-process": { - "version": "3.272.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.272.0.tgz", - "integrity": "sha512-hiCAjWWm2PeBFp5cjkxqyam/XADjiS+e7GzwC34TbZn3LisS0uoweLojj9tD11NnnUhyhbLteUvu5+rotOLwrg==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.295.0.tgz", + "integrity": "sha512-efA41QAcKlb/hbDZVXnUApMPjOnu8Zj58o0WqHAdcpu7qSDzZdsmJ6dqknAbj14cyDjzXaexuN+wubGUAL9IoQ==", "optional": true, "requires": { - "@aws-sdk/property-provider": "3.272.0", - "@aws-sdk/shared-ini-file-loader": "3.272.0", - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/property-provider": "3.295.0", + "@aws-sdk/shared-ini-file-loader": "3.295.0", + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" } }, "@aws-sdk/credential-provider-sso": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.282.0.tgz", - "integrity": "sha512-c4nibry7u0hkYRMi7+cWzdwYXfDDG+j3VYFxk2oOvU1VIJRyE6oeJqVaz3jgYLX9brHyrLJjuFCIJCUV/WXgIA==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.295.0.tgz", + "integrity": "sha512-cJoCLbg3ud3/NK7otcBHkRaPvdsVEyX9tryLIPuj8rgagFWneexVh4Kzs9k+PtRN764TjVFzITw99LxBf0fe1w==", "optional": true, "requires": { - "@aws-sdk/client-sso": "3.282.0", - "@aws-sdk/property-provider": "3.272.0", - "@aws-sdk/shared-ini-file-loader": "3.272.0", - "@aws-sdk/token-providers": "3.282.0", - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/client-sso": "3.295.0", + "@aws-sdk/property-provider": "3.295.0", + "@aws-sdk/shared-ini-file-loader": "3.295.0", + "@aws-sdk/token-providers": "3.295.0", + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" } }, "@aws-sdk/credential-provider-web-identity": { - "version": "3.272.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.272.0.tgz", - "integrity": "sha512-ImrHMkcgneGa/HadHAQXPwOrX26sAKuB8qlMxZF/ZCM2B55u8deY+ZVkVuraeKb7YsahMGehPFOfRAF6mvFI5Q==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.295.0.tgz", + "integrity": "sha512-rBDhRYh4PiOnvz0M7AbYZZCiaPm5JDkM0xzGHEKKiW/A1wS2Gd2qbyEIK4APQ7vZMX+IJaSBBabfqm+vX5Y1kw==", "optional": true, "requires": { - "@aws-sdk/property-provider": "3.272.0", - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/property-provider": "3.295.0", + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" } }, "@aws-sdk/credential-providers": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.282.0.tgz", - "integrity": "sha512-/Pau2Ht15j26ibTSTaJHbx6wA3suNT0Qgu+++6ZUoVCeHL5ZN/otcoebsR/lOZTw8Fji7K5kl8TW41UNAE8s2w==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.295.0.tgz", + "integrity": "sha512-2SV5UFD0pyCkSP74z4MtPq1AT71uaQ/ERhLMms/kpwcyfWWI/e6m8rfSzSRsVjJOU3t08t8WGHOgaUiJrBh/DA==", "optional": true, "requires": { - "@aws-sdk/client-cognito-identity": "3.282.0", - "@aws-sdk/client-sso": "3.282.0", - "@aws-sdk/client-sts": "3.282.0", - "@aws-sdk/credential-provider-cognito-identity": "3.282.0", - "@aws-sdk/credential-provider-env": "3.272.0", - "@aws-sdk/credential-provider-imds": "3.272.0", - "@aws-sdk/credential-provider-ini": "3.282.0", - "@aws-sdk/credential-provider-node": "3.282.0", - "@aws-sdk/credential-provider-process": "3.272.0", - "@aws-sdk/credential-provider-sso": "3.282.0", - "@aws-sdk/credential-provider-web-identity": "3.272.0", - "@aws-sdk/property-provider": "3.272.0", - "@aws-sdk/shared-ini-file-loader": "3.272.0", - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/client-cognito-identity": "3.295.0", + "@aws-sdk/client-sso": "3.295.0", + "@aws-sdk/client-sts": "3.295.0", + "@aws-sdk/credential-provider-cognito-identity": "3.295.0", + "@aws-sdk/credential-provider-env": "3.295.0", + "@aws-sdk/credential-provider-imds": "3.295.0", + "@aws-sdk/credential-provider-ini": "3.295.0", + "@aws-sdk/credential-provider-node": "3.295.0", + "@aws-sdk/credential-provider-process": "3.295.0", + "@aws-sdk/credential-provider-sso": "3.295.0", + "@aws-sdk/credential-provider-web-identity": "3.295.0", + "@aws-sdk/property-provider": "3.295.0", + "@aws-sdk/shared-ini-file-loader": "3.295.0", + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" } }, "@aws-sdk/fetch-http-handler": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/fetch-http-handler/-/fetch-http-handler-3.282.0.tgz", - "integrity": "sha512-RTd53UzKtUucIEdVLGGgtlbVwp0QkOt3ZfHuA/A1lOH7meChSh1kz7B5z3p4HQDpXO+MQ1Y6Ble9Vg2fh1zwJQ==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/fetch-http-handler/-/fetch-http-handler-3.295.0.tgz", + "integrity": "sha512-xs274LSLeF2313dAaq7gvm/m0e0tb0/Bt2vew4Lj2zP6YNRtuNlStfSNhYHHuIkOqjTwLeAmKdK+cWFnXKQPTA==", "optional": true, "requires": { - "@aws-sdk/protocol-http": "3.282.0", - "@aws-sdk/querystring-builder": "3.272.0", - "@aws-sdk/types": "3.272.0", - "@aws-sdk/util-base64": "3.208.0", - "tslib": "^2.3.1" + "@aws-sdk/protocol-http": "3.295.0", + "@aws-sdk/querystring-builder": "3.295.0", + "@aws-sdk/types": "3.295.0", + "@aws-sdk/util-base64": "3.295.0", + "tslib": "^2.5.0" } }, "@aws-sdk/hash-node": { - "version": "3.272.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/hash-node/-/hash-node-3.272.0.tgz", - "integrity": "sha512-40dwND+iAm3VtPHPZu7/+CIdVJFk2s0cWZt1lOiMPMSXycSYJ45wMk7Lly3uoqRx0uWfFK5iT2OCv+fJi5jTng==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/hash-node/-/hash-node-3.295.0.tgz", + "integrity": "sha512-jLq6QXUpvtYYu9+K8BECXpw7U52RBrewj/t/ALUVJsEhtwpx16K1WzMqwcVhkQ8mc/xQiki/T4eFSThODZAlcw==", "optional": true, "requires": { - "@aws-sdk/types": "3.272.0", - "@aws-sdk/util-buffer-from": "3.208.0", - "@aws-sdk/util-utf8": "3.254.0", - "tslib": "^2.3.1" + "@aws-sdk/types": "3.295.0", + "@aws-sdk/util-buffer-from": "3.295.0", + "@aws-sdk/util-utf8": "3.295.0", + "tslib": "^2.5.0" } }, "@aws-sdk/invalid-dependency": { - "version": "3.272.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/invalid-dependency/-/invalid-dependency-3.272.0.tgz", - "integrity": "sha512-ysW6wbjl1Y78txHUQ/Tldj2Rg1BI7rpMO9B9xAF6yAX3mQ7t6SUPQG/ewOGvH2208NBIl3qP5e/hDf0Q6r/1iw==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/invalid-dependency/-/invalid-dependency-3.295.0.tgz", + "integrity": "sha512-ctXFKW4qnhLqZ0+qyEK1l0TOYQYwd2+vjj6wdjAiHuKoH6yIMqJ97LOT7oq3drvMQbnXa4I2jCOSFVuNSnzJ7Q==", "optional": true, "requires": { - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" } }, "@aws-sdk/is-array-buffer": { - "version": "3.201.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/is-array-buffer/-/is-array-buffer-3.201.0.tgz", - "integrity": "sha512-UPez5qLh3dNgt0DYnPD/q0mVJY84rA17QE26hVNOW3fAji8W2wrwrxdacWOxyXvlxWsVRcKmr+lay1MDqpAMfg==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/is-array-buffer/-/is-array-buffer-3.295.0.tgz", + "integrity": "sha512-SCIt10cr5dud7hvwveU4wkLjvkGssJ3GrcbHCds2NwI+JHmpcaaNYLAqi305JAuT29T36U5ssTFDSmrrEOcfag==", "optional": true, "requires": { - "tslib": "^2.3.1" + "tslib": "^2.5.0" } }, "@aws-sdk/middleware-content-length": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-content-length/-/middleware-content-length-3.282.0.tgz", - "integrity": "sha512-SDgMLRRTMr9LlHSNk4bXUXynYnkT4oNMqE+FxhjsdbT8hK36eS4AadM58R7nPwgjR3EuWRW4ZRRawLWatpWspA==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-content-length/-/middleware-content-length-3.295.0.tgz", + "integrity": "sha512-XzrVPuO1JwxJx5PFHP9eMZLP9zyQxPZ8PM9gTWdOgoc1BMtxCkDZ3HLOnJtcfmfbz8nwSt2/H+wlBEXaRrf7Fg==", "optional": true, "requires": { - "@aws-sdk/protocol-http": "3.282.0", - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/protocol-http": "3.295.0", + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" } }, "@aws-sdk/middleware-endpoint": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-endpoint/-/middleware-endpoint-3.282.0.tgz", - "integrity": "sha512-8U9Mv/Sbdo1KI6/ip7IIUdBl5pgmalFbfkYAyO+AtmkEvawI9ipdWFs5HB0Dwd1BGVup5choY72Ik/7sCAAFTQ==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-endpoint/-/middleware-endpoint-3.295.0.tgz", + "integrity": "sha512-MFRW6XyZABAOeFPu2CC37h+ol6ADaKs8fqqJrv9gtNb13r6c0UeztQFwI6V3tLlZwX7zzH7HcwYFKyks5VO6Xw==", "optional": true, "requires": { - "@aws-sdk/middleware-serde": "3.272.0", - "@aws-sdk/protocol-http": "3.282.0", - "@aws-sdk/signature-v4": "3.282.0", - "@aws-sdk/types": "3.272.0", - "@aws-sdk/url-parser": "3.272.0", - "@aws-sdk/util-config-provider": "3.208.0", - "@aws-sdk/util-middleware": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/middleware-serde": "3.295.0", + "@aws-sdk/protocol-http": "3.295.0", + "@aws-sdk/signature-v4": "3.295.0", + "@aws-sdk/types": "3.295.0", + "@aws-sdk/url-parser": "3.295.0", + "@aws-sdk/util-config-provider": "3.295.0", + "@aws-sdk/util-middleware": "3.295.0", + "tslib": "^2.5.0" } }, "@aws-sdk/middleware-host-header": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.282.0.tgz", - "integrity": "sha512-90dfYow4zh4tCatTOnqB3nE/dIAucQLZnMqwN/WBPu0fUqjymzpsNkPchqWBPnSWdNE8w3PiKMqqD9rjYwqw4Q==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.295.0.tgz", + "integrity": "sha512-CjdC8eCILSuNHTF2AZOtFta5lMvLMM3bXBTto0LKYeHQixgBHmRSgcShfBTiWEPgIgeNSFEjMbKX6bLnHSnODg==", "optional": true, "requires": { - "@aws-sdk/protocol-http": "3.282.0", - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/protocol-http": "3.295.0", + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" } }, "@aws-sdk/middleware-logger": { - "version": "3.272.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.272.0.tgz", - "integrity": "sha512-u2SQ0hWrFwxbxxYMG5uMEgf01pQY5jauK/LYWgGIvuCmFgiyRQQP3oN7kkmsxnS9MWmNmhbyQguX2NY02s5e9w==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.295.0.tgz", + "integrity": "sha512-dbv0VTA7Dh6ZCkmCs0U7/ssZiDtHDI7Bq3zab+RxEyLEE4wr73bW6occq579U/QQJHOZQ6EBdvYig8ntRNlzVg==", "optional": true, "requires": { - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" } }, "@aws-sdk/middleware-recursion-detection": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.282.0.tgz", - "integrity": "sha512-cSLq/daEaTEucbP/TgAXIOcpwLu7Bfw3VGzH1U56ngDjI4KWvUheF16JiB6OqKQXduPBPsdZ9dVmkDVKddmCRw==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.295.0.tgz", + "integrity": "sha512-9Wjb8Y7H0ctL8gIKtGFwXhpHb3c2UGGi2P9I+p2PJwW08rDnMlOpUItY0v49SbZ+6uct1VNBs6iJ+jkv0h5MEQ==", "optional": true, "requires": { - "@aws-sdk/protocol-http": "3.282.0", - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/protocol-http": "3.295.0", + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" } }, "@aws-sdk/middleware-retry": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-retry/-/middleware-retry-3.282.0.tgz", - "integrity": "sha512-3+0M1GP9o480IdqHVZbkhTgge63uKhDFlS6cQznpNGj0eIuQPhXRnlEz2/rma0INUqFm6+7qJ5yzHR4WQbfHpw==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-retry/-/middleware-retry-3.295.0.tgz", + "integrity": "sha512-IdVX86VaDSSPcGI1JJM8lffabOMmGC9TUpskKkKdFnLW6eKtFohye+hlf2h6Y/2wdvoqCdi6XZyQX9WPJHiHtw==", "optional": true, "requires": { - "@aws-sdk/protocol-http": "3.282.0", - "@aws-sdk/service-error-classification": "3.272.0", - "@aws-sdk/types": "3.272.0", - "@aws-sdk/util-middleware": "3.272.0", - "@aws-sdk/util-retry": "3.272.0", - "tslib": "^2.3.1", + "@aws-sdk/protocol-http": "3.295.0", + "@aws-sdk/service-error-classification": "3.295.0", + "@aws-sdk/types": "3.295.0", + "@aws-sdk/util-middleware": "3.295.0", + "@aws-sdk/util-retry": "3.295.0", + "tslib": "^2.5.0", "uuid": "^8.3.2" }, "dependencies": { @@ -10502,363 +11963,364 @@ } }, "@aws-sdk/middleware-sdk-sts": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.282.0.tgz", - "integrity": "sha512-Qe20mtJcF6lxt7280FhTFD2IpBDn39MEXmbm/zIkXR2/cAmvji8YhcxhNrq1l7XiuMM6SokBDC/f3dlF1oOC6g==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.295.0.tgz", + "integrity": "sha512-QTHR+ZXAmii8XsbdRrqJWn6LVeGiRcFfGlniIb1YEjw1p2FU5kpayq8N1SLLtj3JWmE61Bpn0J+LAQmfjbCqFA==", "optional": true, "requires": { - "@aws-sdk/middleware-signing": "3.282.0", - "@aws-sdk/property-provider": "3.272.0", - "@aws-sdk/protocol-http": "3.282.0", - "@aws-sdk/signature-v4": "3.282.0", - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/middleware-signing": "3.295.0", + "@aws-sdk/property-provider": "3.295.0", + "@aws-sdk/protocol-http": "3.295.0", + "@aws-sdk/signature-v4": "3.295.0", + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" } }, "@aws-sdk/middleware-serde": { - "version": "3.272.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-serde/-/middleware-serde-3.272.0.tgz", - "integrity": "sha512-kW1uOxgPSwtXPB5rm3QLdWomu42lkYpQL94tM1BjyFOWmBLO2lQhk5a7Dw6HkTozT9a+vxtscLChRa6KZe61Hw==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-serde/-/middleware-serde-3.295.0.tgz", + "integrity": "sha512-LAKtKNKdu6Si7rmLatAq87LSa27mR6HUZ7tZHD2E4SQWOoNpS4ikKfUfATkbjC2GOfbrBYmFmQgBvpghYYZ3jw==", "optional": true, "requires": { - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" } }, "@aws-sdk/middleware-signing": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.282.0.tgz", - "integrity": "sha512-eE5qMDcqqxZPdSwybUEph/knrA2j2cHjW+B2ddROw3Ojg0XLjep5hOhithAudgBREQhYF9pdsBr6mUMynUIrKw==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.295.0.tgz", + "integrity": "sha512-LcNzGqtpo9sdWJ9mKtgjragncbin/Ynbz/pklH/HcIIi45w8ZVrhLBpW1iQZ0MBKyDacAAeWtXxKHy55DkHlvg==", "optional": true, "requires": { - "@aws-sdk/property-provider": "3.272.0", - "@aws-sdk/protocol-http": "3.282.0", - "@aws-sdk/signature-v4": "3.282.0", - "@aws-sdk/types": "3.272.0", - "@aws-sdk/util-middleware": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/property-provider": "3.295.0", + "@aws-sdk/protocol-http": "3.295.0", + "@aws-sdk/signature-v4": "3.295.0", + "@aws-sdk/types": "3.295.0", + "@aws-sdk/util-middleware": "3.295.0", + "tslib": "^2.5.0" } }, "@aws-sdk/middleware-stack": { - "version": "3.272.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-stack/-/middleware-stack-3.272.0.tgz", - "integrity": "sha512-jhwhknnPBGhfXAGV5GXUWfEhDFoP/DN8MPCO2yC5OAxyp6oVJ8lTPLkZYMTW5VL0c0eG44dXpF4Ib01V+PlDrQ==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-stack/-/middleware-stack-3.295.0.tgz", + "integrity": "sha512-65HahosleRbpNgu6/XkABcrBmZHudRYTNpyKRfSY18QPKVQv3PRgRqv/goHrc6DHo8cxAliBoMciN88Ali1ufQ==", "optional": true, "requires": { - "tslib": "^2.3.1" + "tslib": "^2.5.0" } }, "@aws-sdk/middleware-user-agent": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.282.0.tgz", - "integrity": "sha512-P1ealsSrUALo0w0Qu5nBKsNQwsmqIfsoNtFWpaznjIcXE5rRMlZL69zb0KnGbQCBfEXsgaMOWjeGT8I3/XbOHQ==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.295.0.tgz", + "integrity": "sha512-11MGXHFxmXgQx6aAFshLqHm3US7awXMP1Hq3IAu6j+GXSdkpkIojh/LlzRbSUftAhh23C5oQpgOkqs6fox4xCw==", "optional": true, "requires": { - "@aws-sdk/protocol-http": "3.282.0", - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/protocol-http": "3.295.0", + "@aws-sdk/types": "3.295.0", + "@aws-sdk/util-endpoints": "3.295.0", + "tslib": "^2.5.0" } }, "@aws-sdk/node-config-provider": { - "version": "3.272.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/node-config-provider/-/node-config-provider-3.272.0.tgz", - "integrity": "sha512-YYCIBh9g1EQo7hm2l22HX5Yr9RoPQ2RCvhzKvF1n1e8t1QH4iObQrYUtqHG4khcm64Cft8C5MwZmgzHbya5Z6Q==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/node-config-provider/-/node-config-provider-3.295.0.tgz", + "integrity": "sha512-6lkCmPMmXn6CF1qQHkE/Ii88ge/Mz9MWX+Krj3ICdBRwdMqm4LGzc9qG+bJeqbVI3tPO3djmL+b4SW4a3pvKsw==", "optional": true, "requires": { - "@aws-sdk/property-provider": "3.272.0", - "@aws-sdk/shared-ini-file-loader": "3.272.0", - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/property-provider": "3.295.0", + "@aws-sdk/shared-ini-file-loader": "3.295.0", + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" } }, "@aws-sdk/node-http-handler": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/node-http-handler/-/node-http-handler-3.282.0.tgz", - "integrity": "sha512-LIA4lsSKA/l1kTR5ERkJG2gARveB7Y40MR6yDwtIuhXeVu7Xo9m4BJFanCYIbyc093W0T53x438bwoBR+R+/fw==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/node-http-handler/-/node-http-handler-3.295.0.tgz", + "integrity": "sha512-Ga3vp/IY3LgzTdlSTAcxncYebE0lpQAdgxnko+z1i67OaI8DqNlTL8vdYBoHDaFOb9E6ErShLytVoHAEuJ5TpA==", "optional": true, "requires": { - "@aws-sdk/abort-controller": "3.272.0", - "@aws-sdk/protocol-http": "3.282.0", - "@aws-sdk/querystring-builder": "3.272.0", - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/abort-controller": "3.295.0", + "@aws-sdk/protocol-http": "3.295.0", + "@aws-sdk/querystring-builder": "3.295.0", + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" } }, "@aws-sdk/property-provider": { - "version": "3.272.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/property-provider/-/property-provider-3.272.0.tgz", - "integrity": "sha512-V1pZTaH5eqpAt8O8CzbItHhOtzIfFuWymvwZFkAtwKuaHpnl7jjrTouV482zoq8AD/fF+VVSshwBKYA7bhidIw==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/property-provider/-/property-provider-3.295.0.tgz", + "integrity": "sha512-5hxI1W36JWugYaBng7hKH2IxDtNohk0KMsz6wgyHVxTcsrO9VohlYa+5rHntmt3SbQAyy7n5ft9/vb1Nb5TGCw==", "optional": true, "requires": { - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" } }, "@aws-sdk/protocol-http": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/protocol-http/-/protocol-http-3.282.0.tgz", - "integrity": "sha512-aOPv5DhsbG06WKfeh2g0H8RGnaeI8pLhaA+Mq1BvzXcghhlDu+FM9K/GjC/f1lWk1UNryfevOR7SdQm95ciHQg==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/protocol-http/-/protocol-http-3.295.0.tgz", + "integrity": "sha512-mDl1jfNDtOFXKQrkiTY0dbTwC9LLjmmAmE8TpxXC1v6JbOihVrARiyPdumZWP4J/71YAim1ASS6JlQHw/GuAqg==", "optional": true, "requires": { - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" } }, "@aws-sdk/querystring-builder": { - "version": "3.272.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-builder/-/querystring-builder-3.272.0.tgz", - "integrity": "sha512-ndo++7GkdCj5tBXE6rGcITpSpZS4PfyV38wntGYAlj9liL1omk3bLZRY6uzqqkJpVHqbg2fD7O2qHNItzZgqhw==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-builder/-/querystring-builder-3.295.0.tgz", + "integrity": "sha512-zgFb2pSkxOCHVusZpPjQVIwmQZf59MQEYJETk42OKaigItGTHjap9DrFzKo6+SrHeyEpJLxlZKSz5up4Hulwdw==", "optional": true, "requires": { - "@aws-sdk/types": "3.272.0", - "@aws-sdk/util-uri-escape": "3.201.0", - "tslib": "^2.3.1" + "@aws-sdk/types": "3.295.0", + "@aws-sdk/util-uri-escape": "3.295.0", + "tslib": "^2.5.0" } }, "@aws-sdk/querystring-parser": { - "version": "3.272.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-parser/-/querystring-parser-3.272.0.tgz", - "integrity": "sha512-5oS4/9n6N1LZW9tI3qq/0GnCuWoOXRgcHVB+AJLRBvDbEe+GI+C/xK1tKLsfpDNgsQJHc4IPQoIt4megyZ/1+A==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-parser/-/querystring-parser-3.295.0.tgz", + "integrity": "sha512-bcm8IBHmflH1e6EHznScJbfvAmNZqwZtC6QaynNk6no/YYKr5Swm+GHqxurKBm86qCYIOoSvdoq8tyhUjXnh4Q==", "optional": true, "requires": { - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" } }, "@aws-sdk/service-error-classification": { - "version": "3.272.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/service-error-classification/-/service-error-classification-3.272.0.tgz", - "integrity": "sha512-REoltM1LK9byyIufLqx9znhSolPcHQgVHIA2S0zu5sdt5qER4OubkLAXuo4MBbisUTmh8VOOvIyUb5ijZCXq1w==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/service-error-classification/-/service-error-classification-3.295.0.tgz", + "integrity": "sha512-zqGxXkZUxPD7E0FJXKHZLuJwr02zg/Ux4d+elT/MUTYT9eKupmG2S5586/hZdjUxGGA7gmMMJr92mjrLVJUAkQ==", "optional": true }, "@aws-sdk/shared-ini-file-loader": { - "version": "3.272.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/shared-ini-file-loader/-/shared-ini-file-loader-3.272.0.tgz", - "integrity": "sha512-lzFPohp5sy2XvwFjZIzLVCRpC0i5cwBiaXmFzXYQZJm6FSCszHO4ax+m9yrtlyVFF/2YPWl+/bzNthy4aJtseA==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/shared-ini-file-loader/-/shared-ini-file-loader-3.295.0.tgz", + "integrity": "sha512-LF9+jk37/VPoIyadeb+Ls0Tqda6dauo3uG7FDfg7qdiOpdyNRuFaIZE//MTSG5mk4ExAwjkFsnslZaw31hbbUw==", "optional": true, "requires": { - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" } }, "@aws-sdk/signature-v4": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4/-/signature-v4-3.282.0.tgz", - "integrity": "sha512-rnSL3UyF/No7+O2EMtN1sTCiqL1a+odbfnfo3wCSl8DH5PEYINt2kZgVEvT1Fgaffk1pUggBBOZoR+arPIIDJA==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4/-/signature-v4-3.295.0.tgz", + "integrity": "sha512-yS00sIwWEnPB4aHZWJZpXVL2/wbwrymxbPZw/Xq0JXbR9+RXhzENBqw7C3d7E11K1xLnoTYlVqcJhNuNXgyeZg==", "optional": true, "requires": { - "@aws-sdk/is-array-buffer": "3.201.0", - "@aws-sdk/types": "3.272.0", - "@aws-sdk/util-hex-encoding": "3.201.0", - "@aws-sdk/util-middleware": "3.272.0", - "@aws-sdk/util-uri-escape": "3.201.0", - "@aws-sdk/util-utf8": "3.254.0", - "tslib": "^2.3.1" + "@aws-sdk/is-array-buffer": "3.295.0", + "@aws-sdk/types": "3.295.0", + "@aws-sdk/util-hex-encoding": "3.295.0", + "@aws-sdk/util-middleware": "3.295.0", + "@aws-sdk/util-uri-escape": "3.295.0", + "@aws-sdk/util-utf8": "3.295.0", + "tslib": "^2.5.0" } }, "@aws-sdk/smithy-client": { - "version": "3.279.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/smithy-client/-/smithy-client-3.279.0.tgz", - "integrity": "sha512-ZcYWUQDGAYN6NXRpJuSn46PetrpPCA6TrDVwP9+3pERzTXZ66npXoG2XhHjNrOXy/Ted5A3OxKrM4/zLu9tK3A==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/smithy-client/-/smithy-client-3.295.0.tgz", + "integrity": "sha512-6Ifq+szMeX6MjWkEEiXvQGm7moY5Wt6WfFi+dMLkZmPdOEWYB0Cr0EBpY605WHWGz702CpFLvM/z6rUkvtak5g==", "optional": true, "requires": { - "@aws-sdk/middleware-stack": "3.272.0", - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/middleware-stack": "3.295.0", + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" } }, "@aws-sdk/token-providers": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.282.0.tgz", - "integrity": "sha512-Qk/D6i+Hpc0fp/2SRHbfJeKPgUIugzsmye3NL0OV1bqd1Y40dW5LT4u67VcZHwqxzYDKe6Eo+7NHJu7qfvwhog==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.295.0.tgz", + "integrity": "sha512-/6PsplDacgBoQxFBbKYMW9ZlEeTHHdAm+xE6V+qjEsc0YXy32LwuFllfihryXLjWftrC3kr8EiehLU6d+9JaKA==", "optional": true, "requires": { - "@aws-sdk/client-sso-oidc": "3.282.0", - "@aws-sdk/property-provider": "3.272.0", - "@aws-sdk/shared-ini-file-loader": "3.272.0", - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/client-sso-oidc": "3.295.0", + "@aws-sdk/property-provider": "3.295.0", + "@aws-sdk/shared-ini-file-loader": "3.295.0", + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" } }, "@aws-sdk/types": { - "version": "3.272.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.272.0.tgz", - "integrity": "sha512-MmmL6vxMGP5Bsi+4wRx4mxYlU/LX6M0noOXrDh/x5FfG7/4ZOar/nDxqDadhJtNM88cuWVHZWY59P54JzkGWmA==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.295.0.tgz", + "integrity": "sha512-flwibucy5+PshdFLeMCClMqV3eFmjUDhcLkEUeQvVgyhGxJPIrU3ntGAfqz27bvk47ZVX5TUdCG5JdxuUaRO+A==", "optional": true, "requires": { - "tslib": "^2.3.1" + "tslib": "^2.5.0" } }, "@aws-sdk/url-parser": { - "version": "3.272.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/url-parser/-/url-parser-3.272.0.tgz", - "integrity": "sha512-vX/Tx02PlnQ/Kgtf5TnrNDHPNbY+amLZjW0Z1d9vzAvSZhQ4i9Y18yxoRDIaDTCNVRDjdhV8iuctW+05PB5JtQ==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/url-parser/-/url-parser-3.295.0.tgz", + "integrity": "sha512-hev5gbi+EWHLaFNgVpoNeNTaJpqfa9ev0SvqgvCPqGlIdUnt3cP9t1Mc8jvx2kUk8ebPtrrq6cp8ZslfxoFeVA==", "optional": true, "requires": { - "@aws-sdk/querystring-parser": "3.272.0", - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/querystring-parser": "3.295.0", + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" } }, "@aws-sdk/util-base64": { - "version": "3.208.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-base64/-/util-base64-3.208.0.tgz", - "integrity": "sha512-PQniZph5A6N7uuEOQi+1hnMz/FSOK/8kMFyFO+4DgA1dZ5pcKcn5wiFwHkcTb/BsgVqQa3Jx0VHNnvhlS8JyTg==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-base64/-/util-base64-3.295.0.tgz", + "integrity": "sha512-z1r40BsBiOTALnzASvLb4qutGwPpL+jH2UKTCV5WJLXZFMzRnpZaRfeZGE8lMJ/i0+jv9H9G1FmVzE8UgB4rhw==", "optional": true, "requires": { - "@aws-sdk/util-buffer-from": "3.208.0", - "tslib": "^2.3.1" + "@aws-sdk/util-buffer-from": "3.295.0", + "tslib": "^2.5.0" } }, "@aws-sdk/util-body-length-browser": { - "version": "3.188.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-body-length-browser/-/util-body-length-browser-3.188.0.tgz", - "integrity": "sha512-8VpnwFWXhnZ/iRSl9mTf+VKOX9wDE8QtN4bj9pBfxwf90H1X7E8T6NkiZD3k+HubYf2J94e7DbeHs7fuCPW5Qg==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-body-length-browser/-/util-body-length-browser-3.295.0.tgz", + "integrity": "sha512-NbG4/RSHV1VueStPRclSo5zRjNUmcDlNAs29sniZF+YaN0+Ad7hEdu/YgJw39shBfUaurz2Wv0pufU3cxE5Tng==", "optional": true, "requires": { - "tslib": "^2.3.1" + "tslib": "^2.5.0" } }, "@aws-sdk/util-body-length-node": { - "version": "3.208.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-body-length-node/-/util-body-length-node-3.208.0.tgz", - "integrity": "sha512-3zj50e5g7t/MQf53SsuuSf0hEELzMtD8RX8C76f12OSRo2Bca4FLLYHe0TZbxcfQHom8/hOaeZEyTyMogMglqg==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-body-length-node/-/util-body-length-node-3.295.0.tgz", + "integrity": "sha512-dvGf8VBmrT66lM0n6P/h7wnlHS4Atafyivyl8f4TUCMvRdpqryvvrtnX6yYcq3T7VKQmas/2SOlgDvcrhGXaiw==", "optional": true, "requires": { - "tslib": "^2.3.1" + "tslib": "^2.5.0" } }, "@aws-sdk/util-buffer-from": { - "version": "3.208.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-buffer-from/-/util-buffer-from-3.208.0.tgz", - "integrity": "sha512-7L0XUixNEFcLUGPeBF35enCvB9Xl+K6SQsmbrPk1P3mlV9mguWSDQqbOBwY1Ir0OVbD6H/ZOQU7hI/9RtRI0Zw==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-buffer-from/-/util-buffer-from-3.295.0.tgz", + "integrity": "sha512-5ezVEITQnrQKn+CU9qfZHgRp2nrrbX0Clmlm9aiNjAEQEPHY33tWl0t6n8h8yU+IpGiNRMWBVC4aSJaE5NA1mA==", "optional": true, "requires": { - "@aws-sdk/is-array-buffer": "3.201.0", - "tslib": "^2.3.1" + "@aws-sdk/is-array-buffer": "3.295.0", + "tslib": "^2.5.0" } }, "@aws-sdk/util-config-provider": { - "version": "3.208.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-config-provider/-/util-config-provider-3.208.0.tgz", - "integrity": "sha512-DSRqwrERUsT34ug+anlMBIFooBEGwM8GejC7q00Y/9IPrQy50KnG5PW2NiTjuLKNi7pdEOlwTSEocJE15eDZIg==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-config-provider/-/util-config-provider-3.295.0.tgz", + "integrity": "sha512-/5Dl1aV2yI8YQjqwmg4RTnl/E9NmNsx7HIwBZt+dTcOrM0LMUwczQBFFcLyqCj/qv5y+VsvLoAAA/OiBT7hb3w==", "optional": true, "requires": { - "tslib": "^2.3.1" + "tslib": "^2.5.0" } }, "@aws-sdk/util-defaults-mode-browser": { - "version": "3.279.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-defaults-mode-browser/-/util-defaults-mode-browser-3.279.0.tgz", - "integrity": "sha512-RnchYRrpapTT5Hu23LOfk6e8RMVq0kUzho6xA6TJj1a4uGxkcRMvgzPipCq1P5uHu0mrkQBg9pGPEVNOUs38/Q==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-defaults-mode-browser/-/util-defaults-mode-browser-3.295.0.tgz", + "integrity": "sha512-QqVyl4Sxi9Umn2+TdhZR8fHQRWWs2361JCylig1GzH+ud+8jinDS6tLtWxhzrea2XdKGb4xqjTC4AhCuBqgSmA==", "optional": true, "requires": { - "@aws-sdk/property-provider": "3.272.0", - "@aws-sdk/types": "3.272.0", + "@aws-sdk/property-provider": "3.295.0", + "@aws-sdk/types": "3.295.0", "bowser": "^2.11.0", - "tslib": "^2.3.1" + "tslib": "^2.5.0" } }, "@aws-sdk/util-defaults-mode-node": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-defaults-mode-node/-/util-defaults-mode-node-3.282.0.tgz", - "integrity": "sha512-D1BlFoA7ZMeK2diDUWFx1xBFrSaJuBZMRBuWbnbT9AnRYNCsASZ8DRU1KkZ8LuFQIwmZz94P9q683emYnZBhiw==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-defaults-mode-node/-/util-defaults-mode-node-3.295.0.tgz", + "integrity": "sha512-R1e94v6HMsUec8/P2tJmab5fYsT9X3+Kh1rMzCEA27V+kAD88eKStzE26Yb1kQDAC+Fg3Fe1KS1bg4dmQKUSVg==", "optional": true, "requires": { - "@aws-sdk/config-resolver": "3.282.0", - "@aws-sdk/credential-provider-imds": "3.272.0", - "@aws-sdk/node-config-provider": "3.272.0", - "@aws-sdk/property-provider": "3.272.0", - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/config-resolver": "3.295.0", + "@aws-sdk/credential-provider-imds": "3.295.0", + "@aws-sdk/node-config-provider": "3.295.0", + "@aws-sdk/property-provider": "3.295.0", + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" } }, "@aws-sdk/util-endpoints": { - "version": "3.272.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.272.0.tgz", - "integrity": "sha512-c4MPUaJt2G6gGpoiwIOqDfUa98c1J63RpYvf/spQEKOtC/tF5Gfqlxuq8FnAl5lHnrqj1B9ZXLLxFhHtDR0IiQ==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.295.0.tgz", + "integrity": "sha512-WZR6jAD++7Wb6ER1SM/U82xU+OVWihcc8V90AzTWyDb0JPeKuogwWokV1aHXiGaQGbWULr1wY1R3wthhvEs3Bg==", "optional": true, "requires": { - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" } }, "@aws-sdk/util-hex-encoding": { - "version": "3.201.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-hex-encoding/-/util-hex-encoding-3.201.0.tgz", - "integrity": "sha512-7t1vR1pVxKx0motd3X9rI3m/xNp78p3sHtP5yo4NP4ARpxyJ0fokBomY8ScaH2D/B+U5o9ARxldJUdMqyBlJcA==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-hex-encoding/-/util-hex-encoding-3.295.0.tgz", + "integrity": "sha512-XJcoVo41kHzhe28PBm/rqt5mdCp8R6abwiW9ug1dA6FOoPUO8kBUxDv6xaOmA2hfRvd2ocFfBXaUCBqUowkGcQ==", "optional": true, "requires": { - "tslib": "^2.3.1" + "tslib": "^2.5.0" } }, "@aws-sdk/util-locate-window": { - "version": "3.208.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.208.0.tgz", - "integrity": "sha512-iua1A2+P7JJEDHVgvXrRJSvsnzG7stYSGQnBVphIUlemwl6nN5D+QrgbjECtrbxRz8asYFHSzhdhECqN+tFiBg==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.295.0.tgz", + "integrity": "sha512-d/s+zhUx5Kh4l/ecMP/TBjzp1GR/g89Q4nWH6+wH5WgdHsK+LG+vmsk6mVNuP/8wsCofYG4NBqp5Ulbztbm9QA==", "optional": true, "requires": { - "tslib": "^2.3.1" + "tslib": "^2.5.0" } }, "@aws-sdk/util-middleware": { - "version": "3.272.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-middleware/-/util-middleware-3.272.0.tgz", - "integrity": "sha512-Abw8m30arbwxqmeMMha5J11ESpHUNmCeSqSzE8/C4B8jZQtHY4kq7f+upzcNIQ11lsd+uzBEzNG3+dDRi0XOJQ==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-middleware/-/util-middleware-3.295.0.tgz", + "integrity": "sha512-t6UdduLHV97IRZmd1YA0v5HCwerz+OXxDF8lLK0G7qihde0jv6tq5w8fTTjgehDFKM0UGUiaahOtjEcRK7F2Aw==", "optional": true, "requires": { - "tslib": "^2.3.1" + "tslib": "^2.5.0" } }, "@aws-sdk/util-retry": { - "version": "3.272.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-retry/-/util-retry-3.272.0.tgz", - "integrity": "sha512-Ngha5414LR4gRHURVKC9ZYXsEJhMkm+SJ+44wlzOhavglfdcKKPUsibz5cKY1jpUV7oKECwaxHWpBB8r6h+hOg==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-retry/-/util-retry-3.295.0.tgz", + "integrity": "sha512-3xp3A5XtPWGsN9aLuzM3mB4hpM3nZJ5JJiGFgUXu/CTP2ahipbVbMwtRpIUjYDh1kvdjoaDJatEVJ7JhJrXFew==", "optional": true, "requires": { - "@aws-sdk/service-error-classification": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/service-error-classification": "3.295.0", + "tslib": "^2.5.0" } }, "@aws-sdk/util-uri-escape": { - "version": "3.201.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-uri-escape/-/util-uri-escape-3.201.0.tgz", - "integrity": "sha512-TeTWbGx4LU2c5rx0obHeDFeO9HvwYwQtMh1yniBz00pQb6Qt6YVOETVQikRZ+XRQwEyCg/dA375UplIpiy54mA==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-uri-escape/-/util-uri-escape-3.295.0.tgz", + "integrity": "sha512-1H5DcyIoXF8XcPBWf7wzHt0l+TW2EoR8Oq4gsVrPTQkHMTVclC2Yn8EF3gc4arwVBzwLulI9LMBE2L8fexGfTQ==", "optional": true, "requires": { - "tslib": "^2.3.1" + "tslib": "^2.5.0" } }, "@aws-sdk/util-user-agent-browser": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.282.0.tgz", - "integrity": "sha512-Z639oyTa5fZfyi4Xr64+eiAwBCxfpe9Op4Vhnr1z/RwonQM/qywydv6Ttpeq1q5uQ0nG4wTkOMpfh39g+VqIgw==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.295.0.tgz", + "integrity": "sha512-lSU80r6yMwSDLkBZ0900G/kHLz/QgXewPXz56Xnq7NHWu7YliY6fzT1zWHPRGwcfCctTGMTWw+10ZSu/0Xv9nw==", "optional": true, "requires": { - "@aws-sdk/types": "3.272.0", + "@aws-sdk/types": "3.295.0", "bowser": "^2.11.0", - "tslib": "^2.3.1" + "tslib": "^2.5.0" } }, "@aws-sdk/util-user-agent-node": { - "version": "3.282.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.282.0.tgz", - "integrity": "sha512-GSOdWNmzEd554wR9HBrgeYptKBOybveVwUkd6ws+YTdCOz4xD5Gga+I5JomKkcMEUVdBrJnYVUtq7ZsJy2f11w==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.295.0.tgz", + "integrity": "sha512-EVt/4nWTYLbS6llhjE4sn2tn1mBlifyK6ezAse5kr6boNG3dJt6Y7gHAXXglkmblw2bflxqgOaKj5YCcZFUSyQ==", "optional": true, "requires": { - "@aws-sdk/node-config-provider": "3.272.0", - "@aws-sdk/types": "3.272.0", - "tslib": "^2.3.1" + "@aws-sdk/node-config-provider": "3.295.0", + "@aws-sdk/types": "3.295.0", + "tslib": "^2.5.0" } }, "@aws-sdk/util-utf8": { - "version": "3.254.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8/-/util-utf8-3.254.0.tgz", - "integrity": "sha512-14Kso/eIt5/qfIBmhEL9L1IfyUqswjSTqO2mY7KOzUZ9SZbwn3rpxmtkhmATkRjD7XIlLKaxBkI7tU9Zjzj8Kw==", + "version": "3.295.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8/-/util-utf8-3.295.0.tgz", + "integrity": "sha512-ITN8v3F63ZkA4sdmCtSbS/mhav4F0MEAiXDAUXtMJLNqVtaVcyQST4i9vNmPpIVthAPAtP0QjyF2tq/Di8bxtQ==", "optional": true, "requires": { - "@aws-sdk/util-buffer-from": "3.208.0", - "tslib": "^2.3.1" + "@aws-sdk/util-buffer-from": "3.295.0", + "tslib": "^2.5.0" } }, "@aws-sdk/util-utf8-browser": { @@ -10886,21 +12348,21 @@ "dev": true }, "@babel/core": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.0.tgz", - "integrity": "sha512-PuxUbxcW6ZYe656yL3EAhpy7qXKq0DmYsrJLpbB8XrsCP9Nm+XCg9XFMb5vIDliPD7+U/+M+QJlH17XOcB7eXA==", + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.3.tgz", + "integrity": "sha512-qIJONzoa/qiHghnm0l1n4i/6IIziDpzqc36FBs4pzMhDUraHqponwJLiAKm1hGLP3OSB/TVNz6rMwVGpwxxySw==", "dev": true, "requires": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.21.0", + "@babel/generator": "^7.21.3", "@babel/helper-compilation-targets": "^7.20.7", - "@babel/helper-module-transforms": "^7.21.0", + "@babel/helper-module-transforms": "^7.21.2", "@babel/helpers": "^7.21.0", - "@babel/parser": "^7.21.0", + "@babel/parser": "^7.21.3", "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.0", - "@babel/types": "^7.21.0", + "@babel/traverse": "^7.21.3", + "@babel/types": "^7.21.3", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -10923,12 +12385,12 @@ } }, "@babel/generator": { - "version": "7.21.1", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.1.tgz", - "integrity": "sha512-1lT45bAYlQhFn/BHivJs43AiW2rg3/UbLyShGfF3C0KmHvO5fSghWd5kBJy30kpRRucGzXStvnnCFniCR2kXAA==", + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.3.tgz", + "integrity": "sha512-QS3iR1GYC/YGUnW7IdggFeN5c1poPUurnGttOV/bZgPGV+izC/D8HnD6DLwod0fsatNyVn1G3EVWMYIF0nHbeA==", "dev": true, "requires": { - "@babel/types": "^7.21.0", + "@babel/types": "^7.21.3", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -10960,11 +12422,26 @@ "semver": "^6.3.0" }, "dependencies": { + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true } } }, @@ -11141,9 +12618,9 @@ } }, "@babel/parser": { - "version": "7.21.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.2.tgz", - "integrity": "sha512-URpaIJQwEkEC2T9Kn+Ai6Xe/02iNaVCuT/PtoRz3GPVJVDpPd7mLo+VddTbhCRU9TXqW5mSrQfXZyi8kDKOVpQ==", + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.3.tgz", + "integrity": "sha512-lobG0d7aOfQRXh8AyklEAgZGvA4FShxo6xQbUrrT/cNBPUdIDojlokwJsQyCC/eKia7ifqM0yP+2DRZ4WKw2RQ==", "dev": true }, "@babel/plugin-syntax-async-generators": { @@ -11284,19 +12761,19 @@ } }, "@babel/traverse": { - "version": "7.21.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.2.tgz", - "integrity": "sha512-ts5FFU/dSUPS13tv8XiEObDu9K+iagEKME9kAbaP7r0Y9KtZJZ+NGndDvWoRAYNpeWafbpFeki3q9QoMD6gxyw==", + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.3.tgz", + "integrity": "sha512-XLyopNeaTancVitYZe2MlUEvgKb6YVVPXzofHgqHijCImG33b/uTurMS488ht/Hbsb2XK3U2BnSTxKVNGV3nGQ==", "dev": true, "requires": { "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.21.1", + "@babel/generator": "^7.21.3", "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-function-name": "^7.21.0", "@babel/helper-hoist-variables": "^7.18.6", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.21.2", - "@babel/types": "^7.21.2", + "@babel/parser": "^7.21.3", + "@babel/types": "^7.21.3", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -11310,9 +12787,9 @@ } }, "@babel/types": { - "version": "7.21.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.2.tgz", - "integrity": "sha512-3wRZSs7jiFaB8AjxiiD+VqN5DTG2iRvJGQ+qYFrs/654lg6kGTQWIOFjlBo5RaXuAZjBmP3+OQH4dmhqiiyYxw==", + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.3.tgz", + "integrity": "sha512-sBGdETxC+/M4o/zKC0sl6sjWv62WFR/uzxrJ6uYyMLZOUlPnwzw0tKgVHOXxaAd5l2g8pEDM5RZ495GPQI77kg==", "dev": true, "requires": { "@babel/helper-string-parser": "^7.19.4", @@ -11326,50 +12803,113 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, - "@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "@eslint-community/eslint-utils": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.3.0.tgz", + "integrity": "sha512-v3oplH6FYCULtFuCeqyuTd9D2WKO937Dxdq+GmHOLL72TTRriLxz2VLlNfkZRsvj6PKnOPAtuT6dwrs/pA5DvA==", "dev": true, "requires": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "dependencies": { - "@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - } + "eslint-visitor-keys": "^3.3.0" } }, + "@eslint-community/regexpp": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.4.0.tgz", + "integrity": "sha512-A9983Q0LnDGdLPjxyXQ00sbV+K+O+ko2Dr+CZigbHWtX9pNfxlaBkMR8X1CztI73zuEyEBXTVjx7CE+/VSwDiQ==", + "dev": true + }, "@eslint/eslintrc": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.0.tgz", - "integrity": "sha512-fluIaaV+GyV24CCu/ggiHdV+j4RNh85yQnAYS/G2mZODZgGmmlrgCydjUcV3YvxCm9x8nMAfThsqTni4KiXT4A==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.1.tgz", + "integrity": "sha512-eFRmABvW2E5Ho6f5fHLqgena46rOj7r7OKHYfLElqcBfGFHHpjBhivyi5+jOEQuSpdc/1phIZJlbC2te+tZNIw==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.4.0", + "espree": "^9.5.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" + }, + "dependencies": { + "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 + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + } } }, "@eslint/js": { - "version": "8.35.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.35.0.tgz", - "integrity": "sha512-JXdzbRiWclLVoD8sNUjR443VVlYqiYmDVT6rGUEIEHU5YJW0gaVZwV2xgM7D4arkvASqD0IlLUVjHiFuxaftRw==", + "version": "8.36.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.36.0.tgz", + "integrity": "sha512-lxJ9R5ygVm8ZWgYdUweoq5ownDlJ4upvoWmO4eLxBYHdMo+vZ/Rx0EN6MbKWDJOSUGrqJy2Gt+Dyv/VKml0fjg==", + "dev": true + }, + "@faker-js/faker": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-7.6.0.tgz", + "integrity": "sha512-XK6BTq1NDMo9Xqw/YkYyGjSsg44fbNwYRx7QK2CuoQgyy+f1rrTDHoExVM5PsyXCtfl2vs2vVJ0MN0yN6LppRw==", "dev": true }, + "@graphql-tools/merge": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-8.4.0.tgz", + "integrity": "sha512-3XYCWe0d3I4F1azNj1CdShlbHfTIfiDgj00R9uvFH8tHKh7i1IWN3F7QQYovcHKhayaR6zPok3YYMESYQcBoaA==", + "requires": { + "@graphql-tools/utils": "9.2.1", + "tslib": "^2.4.0" + } + }, + "@graphql-tools/mock": { + "version": "8.7.19", + "resolved": "https://registry.npmjs.org/@graphql-tools/mock/-/mock-8.7.19.tgz", + "integrity": "sha512-LT2boYM+Y1vGFEhzmC7xDFRL8RPG20FbNcuk2/hHGH0Kh8K1hkItvL89tul3Pl7N6xerOnDZ3c3fx7Ls5GuFxA==", + "requires": { + "@graphql-tools/schema": "9.0.17", + "@graphql-tools/utils": "9.2.1", + "fast-json-stable-stringify": "^2.1.0", + "tslib": "^2.4.0" + } + }, + "@graphql-tools/schema": { + "version": "9.0.17", + "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-9.0.17.tgz", + "integrity": "sha512-HVLq0ecbkuXhJlpZ50IHP5nlISqH2GbNgjBJhhRzHeXhfwlUOT4ISXGquWTmuq61K0xSaO0aCjMpxe4QYbKTng==", + "requires": { + "@graphql-tools/merge": "8.4.0", + "@graphql-tools/utils": "9.2.1", + "tslib": "^2.4.0", + "value-or-promise": "1.0.12" + } + }, + "@graphql-tools/utils": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz", + "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==", + "requires": { + "@graphql-typed-document-node/core": "^3.1.1", + "tslib": "^2.4.0" + } + }, + "@graphql-typed-document-node/core": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.2.0.tgz", + "integrity": "sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==", + "requires": {} + }, "@humanwhocodes/config-array": { "version": "0.11.8", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", @@ -11406,15 +12946,6 @@ "resolve-from": "^5.0.0" }, "dependencies": { - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, "find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -11425,16 +12956,6 @@ "path-exists": "^4.0.0" } }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -11696,6 +13217,11 @@ "chalk": "^4.0.0" } }, + "@josephg/resolvable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@josephg/resolvable/-/resolvable-1.0.1.tgz", + "integrity": "sha512-CtzORUwWTTOTqfVtHaKRJ0I1kNQd1bpn3sUh8I3nJDVY+5/M/Oe1DnEWzPQvqq/xPIIkzzzIP7mfCoAjFRvDhg==" + }, "@jridgewell/gen-mapping": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", @@ -11786,6 +13312,60 @@ "fastq": "^1.6.0" } }, + "@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" + }, + "@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" + }, + "@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "requires": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" + }, + "@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" + }, + "@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" + }, + "@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" + }, + "@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" + }, "@shelf/jest-mongodb": { "version": "4.1.7", "resolved": "https://registry.npmjs.org/@shelf/jest-mongodb/-/jest-mongodb-4.1.7.tgz", @@ -11794,18 +13374,6 @@ "requires": { "debug": "4.3.4", "mongodb-memory-server": "8.11.5" - }, - "dependencies": { - "mongodb-memory-server": { - "version": "8.11.5", - "resolved": "https://registry.npmjs.org/mongodb-memory-server/-/mongodb-memory-server-8.11.5.tgz", - "integrity": "sha512-/yiw3L2TIMpi9I6GXg379k6d+RG3k+9V9o24kK5h+NBTtYLNuWa5iEvtce/O3jqhg6yo31T5XG2e/Hm4UwBM1A==", - "dev": true, - "requires": { - "mongodb-memory-server-core": "8.11.5", - "tslib": "^2.4.1" - } - } } }, "@sinclair/typebox": { @@ -11832,29 +13400,13 @@ "@sinonjs/commons": "^2.0.0" } }, - "@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true - }, - "@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true - }, - "@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true - }, - "@tsconfig/node16": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", - "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", - "dev": true + "@types/accepts": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/accepts/-/accepts-1.3.5.tgz", + "integrity": "sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ==", + "requires": { + "@types/node": "*" + } }, "@types/babel__core": { "version": "7.20.0", @@ -11910,7 +13462,6 @@ "version": "1.19.2", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", - "dev": true, "requires": { "@types/connect": "*", "@types/node": "*" @@ -11920,7 +13471,6 @@ "version": "3.4.35", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", - "dev": true, "requires": { "@types/node": "*" } @@ -11931,6 +13481,11 @@ "integrity": "sha512-t73xJJrvdTjXrn4jLS9VSGRbz0nUY3cl2DMGDU48lKl+HR9dbbjW2A9r3g40VA++mQpy6uuHg33gy7du2BKpog==", "dev": true }, + "@types/cors": { + "version": "2.8.12", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz", + "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==" + }, "@types/express": { "version": "4.17.17", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", @@ -11954,6 +13509,15 @@ "@types/range-parser": "*" } }, + "@types/faker": { + "version": "6.6.9", + "resolved": "https://registry.npmjs.org/@types/faker/-/faker-6.6.9.tgz", + "integrity": "sha512-Y9YYm5L//8ooiiknO++4Gr539zzdI0j3aXnOBjo1Vk+kTvffY10GuE2wn78AFPECwZ5MYGTjiDVw1naLLdDimw==", + "dev": true, + "requires": { + "faker": "*" + } + }, "@types/graceful-fs": { "version": "4.1.6", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz", @@ -11963,6 +13527,32 @@ "@types/node": "*" } }, + "@types/graphql": { + "version": "14.5.0", + "resolved": "https://registry.npmjs.org/@types/graphql/-/graphql-14.5.0.tgz", + "integrity": "sha512-MOkzsEp1Jk5bXuAsHsUi6BVv0zCO+7/2PTiZMXWDSsMXvNU6w/PLMQT2vHn8hy2i0JqojPz1Sz6rsFjHtsU0lA==", + "dev": true, + "requires": { + "graphql": "*" + } + }, + "@types/graphql-iso-date": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@types/graphql-iso-date/-/graphql-iso-date-3.4.0.tgz", + "integrity": "sha512-V3jITHTsoI2E8TGt9+/HPDz6LWt3z9/HYnPJYWI6WwiLRexsngg7KzaQlCgQkA4jkEbGPROUD0hJFc9F02W9WA==", + "dev": true, + "requires": { + "graphql": "^15.1.0" + }, + "dependencies": { + "graphql": { + "version": "15.8.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-15.8.0.tgz", + "integrity": "sha512-5gghUc24tP9HRznNpV2+FIoq3xKkj5dTQqf4v0CpdPbFVwFkWoxOM+o+2OC9ZSvjEMTjfmG9QT+gcvggTwW1zw==", + "dev": true + } + } + }, "@types/istanbul-lib-coverage": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", @@ -11988,9 +13578,9 @@ } }, "@types/jest": { - "version": "29.4.0", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.4.0.tgz", - "integrity": "sha512-VaywcGQ9tPorCX/Jkkni7RWGFfI11whqzs8dvxF41P17Z+z872thvEvlIbznjPJ02kl1HMX3LmLOonsj2n7HeQ==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.0.tgz", + "integrity": "sha512-3Emr5VOl/aoBwnWcH/EFQvlSAmjV+XtV9GGu5mwdYew5vhQh0IUZx/60x0TzHDu09Bi7HMx10t/namdJw5QIcg==", "dev": true, "requires": { "expect": "^29.0.0", @@ -12018,11 +13608,15 @@ "@types/node": "*" } }, + "@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" + }, "@types/mime": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz", - "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==", - "dev": true + "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==" }, "@types/mongodb": { "version": "4.0.7", @@ -12034,9 +13628,9 @@ } }, "@types/node": { - "version": "18.15.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.0.tgz", - "integrity": "sha512-z6nr0TTEOBGkzLGmbypWOGnpSpSIBorEhC4L+4HeQ2iezKCi4f77kyslRwvHeNitymGQ+oFyIWGP96l/DPSV9w==" + "version": "18.15.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.5.tgz", + "integrity": "sha512-Ark2WDjjZO7GmvsyFFf81MXuGTA/d6oP38anyxWOL6EREyBKAxKoFHwBhaZxCfLRLpO8JgVXwqOwSwa7jRcjew==" }, "@types/prettier": { "version": "2.7.2", @@ -12047,14 +13641,12 @@ "@types/qs": { "version": "6.9.7", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", - "dev": true + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" }, "@types/range-parser": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", - "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", - "dev": true + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" }, "@types/semver": { "version": "7.3.13", @@ -12066,7 +13658,6 @@ "version": "1.15.1", "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.1.tgz", "integrity": "sha512-NUo5XNiAdULrJENtJXZZ3fHtfMolzZwczzBbnAeBbqBwG+LaG6YaJtuwzwGSQZ2wsCrxjEhNNjAkKigy3n8teQ==", - "dev": true, "requires": { "@types/mime": "*", "@types/node": "*" @@ -12114,9 +13705,9 @@ "dev": true }, "@types/validator": { - "version": "13.7.13", - "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.7.13.tgz", - "integrity": "sha512-EMfHccxNKXaSxTK6DN0En9WsXa7uR4w3LQtx31f6Z2JjG5hJQeVX5zUYMZoatjZgnoQmRcT94WnNWwi0BzQW6Q==", + "version": "13.7.14", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.7.14.tgz", + "integrity": "sha512-J6OAed6rhN6zyqL9Of6ZMamhlsOEU/poBVvbHr/dKOYKTeuYYMlDkMv+b6UUV0o2i0tw73cgyv/97WTWaUl0/g==", "dev": true }, "@types/webidl-conversions": { @@ -12134,9 +13725,9 @@ } }, "@types/yargs": { - "version": "17.0.22", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.22.tgz", - "integrity": "sha512-pet5WJ9U8yPVRhkwuEIp5ktAeAqRZOq4UdAyWLWzxbtpyXnzbtLdKiXAjJzi/KLmPGS9wk86lUFWZFN6sISo4g==", + "version": "17.0.23", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.23.tgz", + "integrity": "sha512-yuogunc04OnzGQCrfHx+Kk883Q4X0aSwmYZhKjI21m+SVYzjIbrWl8dOOwSv5hf2Um2pdCOXWo9isteZTNXUZQ==", "dev": true, "requires": { "@types/yargs-parser": "*" @@ -12149,71 +13740,71 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "5.54.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.54.1.tgz", - "integrity": "sha512-a2RQAkosH3d3ZIV08s3DcL/mcGc2M/UC528VkPULFxR9VnVPT8pBu0IyBAJJmVsCmhVfwQX1v6q+QGnmSe1bew==", + "version": "5.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.56.0.tgz", + "integrity": "sha512-ZNW37Ccl3oMZkzxrYDUX4o7cnuPgU+YrcaYXzsRtLB16I1FR5SHMqga3zGsaSliZADCWo2v8qHWqAYIj8nWCCg==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.54.1", - "@typescript-eslint/type-utils": "5.54.1", - "@typescript-eslint/utils": "5.54.1", + "@eslint-community/regexpp": "^4.4.0", + "@typescript-eslint/scope-manager": "5.56.0", + "@typescript-eslint/type-utils": "5.56.0", + "@typescript-eslint/utils": "5.56.0", "debug": "^4.3.4", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "natural-compare-lite": "^1.4.0", - "regexpp": "^3.2.0", "semver": "^7.3.7", "tsutils": "^3.21.0" } }, "@typescript-eslint/parser": { - "version": "5.54.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.54.1.tgz", - "integrity": "sha512-8zaIXJp/nG9Ff9vQNh7TI+C3nA6q6iIsGJ4B4L6MhZ7mHnTMR4YP5vp2xydmFXIy8rpyIVbNAG44871LMt6ujg==", + "version": "5.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.56.0.tgz", + "integrity": "sha512-sn1OZmBxUsgxMmR8a8U5QM/Wl+tyqlH//jTqCg8daTAmhAk26L2PFhcqPLlYBhYUJMZJK276qLXlHN3a83o2cg==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.54.1", - "@typescript-eslint/types": "5.54.1", - "@typescript-eslint/typescript-estree": "5.54.1", + "@typescript-eslint/scope-manager": "5.56.0", + "@typescript-eslint/types": "5.56.0", + "@typescript-eslint/typescript-estree": "5.56.0", "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { - "version": "5.54.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.54.1.tgz", - "integrity": "sha512-zWKuGliXxvuxyM71UA/EcPxaviw39dB2504LqAmFDjmkpO8qNLHcmzlh6pbHs1h/7YQ9bnsO8CCcYCSA8sykUg==", + "version": "5.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.56.0.tgz", + "integrity": "sha512-jGYKyt+iBakD0SA5Ww8vFqGpoV2asSjwt60Gl6YcO8ksQ8s2HlUEyHBMSa38bdLopYqGf7EYQMUIGdT/Luw+sw==", "dev": true, "requires": { - "@typescript-eslint/types": "5.54.1", - "@typescript-eslint/visitor-keys": "5.54.1" + "@typescript-eslint/types": "5.56.0", + "@typescript-eslint/visitor-keys": "5.56.0" } }, "@typescript-eslint/type-utils": { - "version": "5.54.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.54.1.tgz", - "integrity": "sha512-WREHsTz0GqVYLIbzIZYbmUUr95DKEKIXZNH57W3s+4bVnuF1TKe2jH8ZNH8rO1CeMY3U4j4UQeqPNkHMiGem3g==", + "version": "5.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.56.0.tgz", + "integrity": "sha512-8WxgOgJjWRy6m4xg9KoSHPzBNZeQbGlQOH7l2QEhQID/+YseaFxg5J/DLwWSsi9Axj4e/cCiKx7PVzOq38tY4A==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "5.54.1", - "@typescript-eslint/utils": "5.54.1", + "@typescript-eslint/typescript-estree": "5.56.0", + "@typescript-eslint/utils": "5.56.0", "debug": "^4.3.4", "tsutils": "^3.21.0" } }, "@typescript-eslint/types": { - "version": "5.54.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.54.1.tgz", - "integrity": "sha512-G9+1vVazrfAfbtmCapJX8jRo2E4MDXxgm/IMOF4oGh3kq7XuK3JRkOg6y2Qu1VsTRmWETyTkWt1wxy7X7/yLkw==", + "version": "5.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.56.0.tgz", + "integrity": "sha512-JyAzbTJcIyhuUhogmiu+t79AkdnqgPUEsxMTMc/dCZczGMJQh1MK2wgrju++yMN6AWroVAy2jxyPcPr3SWCq5w==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.54.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.54.1.tgz", - "integrity": "sha512-bjK5t+S6ffHnVwA0qRPTZrxKSaFYocwFIkZx5k7pvWfsB1I57pO/0M0Skatzzw1sCkjJ83AfGTL0oFIFiDX3bg==", + "version": "5.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.56.0.tgz", + "integrity": "sha512-41CH/GncsLXOJi0jb74SnC7jVPWeVJ0pxQj8bOjH1h2O26jXN3YHKDT1ejkVz5YeTEQPeLCCRY0U2r68tfNOcg==", "dev": true, "requires": { - "@typescript-eslint/types": "5.54.1", - "@typescript-eslint/visitor-keys": "5.54.1", + "@typescript-eslint/types": "5.56.0", + "@typescript-eslint/visitor-keys": "5.56.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -12222,28 +13813,28 @@ } }, "@typescript-eslint/utils": { - "version": "5.54.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.54.1.tgz", - "integrity": "sha512-IY5dyQM8XD1zfDe5X8jegX6r2EVU5o/WJnLu/znLPWCBF7KNGC+adacXnt5jEYS9JixDcoccI6CvE4RCjHMzCQ==", + "version": "5.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.56.0.tgz", + "integrity": "sha512-XhZDVdLnUJNtbzaJeDSCIYaM+Tgr59gZGbFuELgF7m0IY03PlciidS7UQNKLE0+WpUTn1GlycEr6Ivb/afjbhA==", "dev": true, "requires": { + "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.54.1", - "@typescript-eslint/types": "5.54.1", - "@typescript-eslint/typescript-estree": "5.54.1", + "@typescript-eslint/scope-manager": "5.56.0", + "@typescript-eslint/types": "5.56.0", + "@typescript-eslint/typescript-estree": "5.56.0", "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0", "semver": "^7.3.7" } }, "@typescript-eslint/visitor-keys": { - "version": "5.54.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.54.1.tgz", - "integrity": "sha512-q8iSoHTgwCfgcRJ2l2x+xCbu8nBlRAlsQ33k24Adj8eoVBE0f8dUeI+bAa8F84Mv05UGbAx57g2zrRsYIooqQg==", + "version": "5.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.56.0.tgz", + "integrity": "sha512-1mFdED7u5bZpX6Xxf5N9U2c18sb+8EvU3tyOIj6LQZ5OOvnmj8BVeNNP603OFPm5KkS1a7IvCIcwrdHXaEMG/Q==", "dev": true, "requires": { - "@typescript-eslint/types": "5.54.1", + "@typescript-eslint/types": "5.56.0", "eslint-visitor-keys": "^3.3.0" } }, @@ -12274,12 +13865,6 @@ "dev": true, "requires": {} }, - "acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true - }, "agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -12327,34 +13912,210 @@ } } }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" - }, - "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, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + }, + "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, + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "apollo-datasource": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/apollo-datasource/-/apollo-datasource-3.3.2.tgz", + "integrity": "sha512-L5TiS8E2Hn/Yz7SSnWIVbZw0ZfEIXZCa5VUiVxD9P53JvSrf4aStvsFDlGWPvpIdCR+aly2CfoB79B9/JjKFqg==", + "requires": { + "@apollo/utils.keyvaluecache": "^1.0.1", + "apollo-server-env": "^4.2.1" + } + }, + "apollo-reporting-protobuf": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/apollo-reporting-protobuf/-/apollo-reporting-protobuf-3.4.0.tgz", + "integrity": "sha512-h0u3EbC/9RpihWOmcSsvTW2O6RXVaD/mPEjfrPkxRPTEPWqncsgOoRJw+wih4OqfH3PvTJvoEIf4LwKrUaqWog==", + "requires": { + "@apollo/protobufjs": "1.2.6" + }, + "dependencies": { + "@apollo/protobufjs": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@apollo/protobufjs/-/protobufjs-1.2.6.tgz", + "integrity": "sha512-Wqo1oSHNUj/jxmsVp4iR3I480p6qdqHikn38lKrFhfzcDJ7lwd7Ck7cHRl4JE81tWNArl77xhnG/OkZhxKBYOw==", + "requires": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.0", + "@types/node": "^10.1.0", + "long": "^4.0.0" + } + }, + "@types/node": { + "version": "10.17.60", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", + "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==" + } + } + }, + "apollo-server-core": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/apollo-server-core/-/apollo-server-core-3.12.0.tgz", + "integrity": "sha512-hq7iH6Cgldgmnjs9FVSZeKWRpi0/ZR+iJ1arzeD2VXGxxgk1mAm/cz1Tx0TYgegZI+FvvrRl0UhKEx7sLnIxIg==", + "requires": { + "@apollo/utils.keyvaluecache": "^1.0.1", + "@apollo/utils.logger": "^1.0.0", + "@apollo/utils.usagereporting": "^1.0.0", + "@apollographql/apollo-tools": "^0.5.3", + "@apollographql/graphql-playground-html": "1.6.29", + "@graphql-tools/mock": "^8.1.2", + "@graphql-tools/schema": "^8.0.0", + "@josephg/resolvable": "^1.0.0", + "apollo-datasource": "^3.3.2", + "apollo-reporting-protobuf": "^3.4.0", + "apollo-server-env": "^4.2.1", + "apollo-server-errors": "^3.3.1", + "apollo-server-plugin-base": "^3.7.2", + "apollo-server-types": "^3.8.0", + "async-retry": "^1.2.1", + "fast-json-stable-stringify": "^2.1.0", + "graphql-tag": "^2.11.0", + "loglevel": "^1.6.8", + "lru-cache": "^6.0.0", + "node-abort-controller": "^3.0.1", + "sha.js": "^2.4.11", + "uuid": "^9.0.0", + "whatwg-mimetype": "^3.0.0" + }, + "dependencies": { + "@graphql-tools/merge": { + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-8.3.1.tgz", + "integrity": "sha512-BMm99mqdNZbEYeTPK3it9r9S6rsZsQKtlqJsSBknAclXq2pGEfOxjcIZi+kBSkHZKPKCRrYDd5vY0+rUmIHVLg==", + "requires": { + "@graphql-tools/utils": "8.9.0", + "tslib": "^2.4.0" + } + }, + "@graphql-tools/schema": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-8.5.1.tgz", + "integrity": "sha512-0Esilsh0P/qYcB5DKQpiKeQs/jevzIadNTaT0jeWklPMwNbT7yMX4EqZany7mbeRRlSRwMzNzL5olyFdffHBZg==", + "requires": { + "@graphql-tools/merge": "8.3.1", + "@graphql-tools/utils": "8.9.0", + "tslib": "^2.4.0", + "value-or-promise": "1.0.11" + } + }, + "@graphql-tools/utils": { + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.9.0.tgz", + "integrity": "sha512-pjJIWH0XOVnYGXCqej8g/u/tsfV4LvLlj0eATKQu5zwnxd/TiTHq7Cg313qUPTFFHZ3PP5wJ15chYVtLDwaymg==", + "requires": { + "tslib": "^2.4.0" + } + }, + "value-or-promise": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/value-or-promise/-/value-or-promise-1.0.11.tgz", + "integrity": "sha512-41BrgH+dIbCFXClcSapVs5M6GkENd3gQOJpEfPDNa71LsUGMXDL0jMWpI/Rh7WhX+Aalfz2TTS3Zt5pUsbnhLg==" + } + } + }, + "apollo-server-env": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/apollo-server-env/-/apollo-server-env-4.2.1.tgz", + "integrity": "sha512-vm/7c7ld+zFMxibzqZ7SSa5tBENc4B0uye9LTfjJwGoQFY5xsUPH5FpO5j0bMUDZ8YYNbrF9SNtzc5Cngcr90g==", "requires": { - "color-convert": "^2.0.1" + "node-fetch": "^2.6.7" } }, - "any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", - "dev": true + "apollo-server-errors": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/apollo-server-errors/-/apollo-server-errors-3.3.1.tgz", + "integrity": "sha512-xnZJ5QWs6FixHICXHxUfm+ZWqqxrNuPlQ+kj5m6RtEgIpekOPssH/SD9gf2B4HuWV0QozorrygwZnux8POvyPA==", + "requires": {} }, - "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, + "apollo-server-express": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/apollo-server-express/-/apollo-server-express-3.12.0.tgz", + "integrity": "sha512-m8FaGPUfDOEGSm7QRWRmUUGjG/vqvpQoorkId9/FXkC57fz/A59kEdrzkMt9538Xgsa5AV+X4MEWLJhTvlW3LQ==", + "requires": { + "@types/accepts": "^1.3.5", + "@types/body-parser": "1.19.2", + "@types/cors": "2.8.12", + "@types/express": "4.17.14", + "@types/express-serve-static-core": "4.17.31", + "accepts": "^1.3.5", + "apollo-server-core": "^3.12.0", + "apollo-server-types": "^3.8.0", + "body-parser": "^1.19.0", + "cors": "^2.8.5", + "parseurl": "^1.3.3" + }, + "dependencies": { + "@types/express": { + "version": "4.17.14", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.14.tgz", + "integrity": "sha512-TEbt+vaPFQ+xpxFLFssxUDXj5cWCxZJjIcB7Yg0k0GMHGtgtQgpvx/MUQUeAkNbA9AAGrwkAsoeItdTgS7FMyg==", + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.18", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.17.31", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.31.tgz", + "integrity": "sha512-DxMhY+NAsTwMMFHBTtJFNp5qiHKJ7TeqOo23zVEM9alT1Ml27Q3xcTH0xwxn7Q0BbMcVEJOs/7aQtUWupUQN3Q==", + "requires": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + } + } + }, + "apollo-server-plugin-base": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/apollo-server-plugin-base/-/apollo-server-plugin-base-3.7.2.tgz", + "integrity": "sha512-wE8dwGDvBOGehSsPTRZ8P/33Jan6/PmL0y0aN/1Z5a5GcbFhDaaJCjK5cav6npbbGL2DPKK0r6MPXi3k3N45aw==", "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" + "apollo-server-types": "^3.8.0" + } + }, + "apollo-server-types": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/apollo-server-types/-/apollo-server-types-3.8.0.tgz", + "integrity": "sha512-ZI/8rTE4ww8BHktsVpb91Sdq7Cb71rdSkXELSwdSR0eXu600/sY+1UXhTWdiJvk+Eq5ljqoHLwLbY2+Clq2b9A==", + "requires": { + "@apollo/utils.keyvaluecache": "^1.0.1", + "@apollo/utils.logger": "^1.0.0", + "apollo-reporting-protobuf": "^3.4.0", + "apollo-server-env": "^4.2.1" } }, "aproba": { @@ -12369,19 +14130,46 @@ "requires": { "delegates": "^1.0.0", "readable-stream": "^3.6.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + } } }, - "arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, "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 + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "array-buffer-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", + "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "is-array-buffer": "^3.0.1" + } }, "array-flatten": { "version": "1.1.1", @@ -12437,6 +14225,21 @@ "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", "dev": true }, + "asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "dev": true + }, "astral-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", @@ -12452,6 +14255,14 @@ "tslib": "^2.3.1" } }, + "async-retry": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", + "integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==", + "requires": { + "retry": "0.13.1" + } + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -12464,6 +14275,18 @@ "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", "dev": true }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "dev": true + }, + "aws4": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", + "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==", + "dev": true + }, "babel-jest": { "version": "29.5.0", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.5.0.tgz", @@ -12554,6 +14377,20 @@ "node-addon-api": "^5.0.0" } }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" + }, "bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", @@ -12563,15 +14400,37 @@ "buffer": "^5.5.0", "inherits": "^2.0.4", "readable-stream": "^3.4.0" + }, + "dependencies": { + "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, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + } } }, "body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", "requires": { "bytes": "3.1.2", - "content-type": "~1.0.4", + "content-type": "~1.0.5", "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", @@ -12579,7 +14438,7 @@ "iconv-lite": "0.4.24", "on-finished": "2.4.1", "qs": "6.11.0", - "raw-body": "2.5.1", + "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" }, @@ -12618,7 +14477,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, "requires": { "fill-range": "^7.0.1" } @@ -12654,9 +14512,15 @@ } }, "bson": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/bson/-/bson-5.0.1.tgz", - "integrity": "sha512-y09gBGusgHtinMon/GVbv1J6FrXhnr/+6hqLlSmEFzkz6PodqF6TxjyvfvY3AfO+oG1mgUtbC86xSbOlwvM62Q==" + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-5.1.0.tgz", + "integrity": "sha512-FEecNHkhYRBe7X9KDkdG12xNuz5VHGeH6mCE0B5sBmYtiR/Ux/9vUH/v4NUoBCDr6NuEhvahjoLiiRogptVW0A==" + }, + "bson-objectid": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/bson-objectid/-/bson-objectid-2.0.4.tgz", + "integrity": "sha512-vgnKAUzcDoa+AeyYwXCoHyF2q6u/8H46dxu5JN+4/TZeq/Dlinn0K6GvxsCLb3LHUJl0m/TLiEK31kUwtgocMQ==", + "dev": true }, "buffer": { "version": "5.7.1", @@ -12690,6 +14554,7 @@ "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", "dev": true, + "peer": true, "requires": { "semver": "^7.0.0" } @@ -12721,9 +14586,15 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001460", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001460.tgz", - "integrity": "sha512-Bud7abqjvEjipUkpLs4D7gR0l8hBYBHoa+tGtKJHvT2AYzLp1z7EmVkUT4ERpVUfca8S2HGIVs883D8pUH1ZzQ==", + "version": "1.0.30001469", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001469.tgz", + "integrity": "sha512-Rcp7221ScNqQPP3W+lVOYDyjdR6dC+neEQCttoNr5bAyz54AboB4iwpnWgyi8P4YUsPybVzT4LgWiBbI3drL4g==", + "dev": true + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", "dev": true }, "chalk": { @@ -12742,6 +14613,31 @@ "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.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" + }, + "dependencies": { + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "requires": { + "is-glob": "^4.0.1" + } + } + } + }, "chownr": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", @@ -12785,13 +14681,13 @@ } }, "cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "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, "requires": { "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", + "strip-ansi": "^6.0.0", "wrap-ansi": "^7.0.0" }, "dependencies": { @@ -12930,12 +14826,49 @@ "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==", "dev": true }, - "create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "copyfiles": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/copyfiles/-/copyfiles-2.4.1.tgz", + "integrity": "sha512-fereAvAvxDrQDOXybk3Qu3dPbOoKoysFMWtkY3mv5BsL8//OSZVL5DCLYqgRfY5cWirgRzlC+WSrxp6Bo3eNZg==", + "dev": true, + "requires": { + "glob": "^7.0.5", + "minimatch": "^3.0.3", + "mkdirp": "^1.0.4", + "noms": "0.0.0", + "through2": "^2.0.1", + "untildify": "^4.0.0", + "yargs": "^16.1.0" + } + }, + "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 }, + "cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "requires": { + "object-assign": "^4", + "vary": "^1" + } + }, + "coveralls": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.1.1.tgz", + "integrity": "sha512-+dxnG2NHncSD1NrqbSM3dn/lE57O6Qf/koe9+I7c+wzkqRmEvcp0kgJdxKInzYzkICKkFMZsX3Vct3++tsF9ww==", + "dev": true, + "requires": { + "js-yaml": "^3.13.1", + "lcov-parse": "^1.0.0", + "log-driver": "^1.2.7", + "minimist": "^1.2.5", + "request": "^2.88.2" + } + }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -12947,6 +14880,20 @@ "which": "^2.0.1" } }, + "cssfilter": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/cssfilter/-/cssfilter-0.0.10.tgz", + "integrity": "sha512-FAaLDaplstoRsDR8XGYH51znUN0UY7nMc6Z9/fvE8EXGwvJE9hu7W2vHwx1+bd6gCYnln9nLbzxFTrcO9YQDZw==" + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -12968,9 +14915,9 @@ "dev": true }, "deepmerge": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.0.tgz", - "integrity": "sha512-z2wJZXrmeHdvYJp/Ux55wIjqo81G5Bp4c+oELTW+7ar6SogWHajt5a9gO3s3IDaGSAXjDk0vlQKN3rms8ab3og==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "dev": true }, "define-properties": { @@ -13035,12 +14982,6 @@ "underscore": "*" } }, - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true - }, "diff-sequences": { "version": "29.4.3", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", @@ -13071,6 +15012,16 @@ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "dev": true }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, "ecdsa-sig-formatter": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", @@ -13085,9 +15036,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "electron-to-chromium": { - "version": "1.4.320", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.320.tgz", - "integrity": "sha512-h70iRscrNluMZPVICXYl5SSB+rBKo22XfuIS1ER0OQxQZpKTnFpuS6coj7wY9M/3trv7OR88rRMOlKmRvDty7Q==", + "version": "1.4.334", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.334.tgz", + "integrity": "sha512-laZ1odk+TRen6q0GeyQx/JEkpD3iSZT7ewopCpKqg9bTjP1l8XRfU3Bg20CFjNPZkp5+NDBl3iqd4o/kPO+Vew==", "dev": true }, "emittery": { @@ -13126,18 +15077,18 @@ } }, "es-abstract": { - "version": "1.21.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.1.tgz", - "integrity": "sha512-QudMsPOz86xYz/1dG1OuGBKOELjCh99IIWHLzy5znUB6j8xG2yMA7bfTV86VSqKF+Y/H08vQPR+9jyXpuC6hfg==", + "version": "1.21.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.2.tgz", + "integrity": "sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg==", "dev": true, "requires": { + "array-buffer-byte-length": "^1.0.0", "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", "es-set-tostringtag": "^2.0.1", "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.1.3", + "get-intrinsic": "^1.2.0", "get-symbol-description": "^1.0.0", "globalthis": "^1.0.3", "gopd": "^1.0.1", @@ -13145,8 +15096,8 @@ "has-property-descriptors": "^1.0.0", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", - "internal-slot": "^1.0.4", - "is-array-buffer": "^3.0.1", + "internal-slot": "^1.0.5", + "is-array-buffer": "^3.0.2", "is-callable": "^1.2.7", "is-negative-zero": "^2.0.2", "is-regex": "^1.1.4", @@ -13154,11 +15105,12 @@ "is-string": "^1.0.7", "is-typed-array": "^1.1.10", "is-weakref": "^1.0.2", - "object-inspect": "^1.12.2", + "object-inspect": "^1.12.3", "object-keys": "^1.1.1", "object.assign": "^4.1.4", "regexp.prototype.flags": "^1.4.3", "safe-regex-test": "^1.0.0", + "string.prototype.trim": "^1.2.7", "string.prototype.trimend": "^1.0.6", "string.prototype.trimstart": "^1.0.6", "typed-array-length": "^1.0.4", @@ -13215,13 +15167,15 @@ "dev": true }, "eslint": { - "version": "8.35.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.35.0.tgz", - "integrity": "sha512-BxAf1fVL7w+JLRQhWl2pzGeSiGqbWumV4WNvc9Rhp6tiCtm4oHnyPBSEtMGZwrQgudFQ+otqzWoPB7x+hxoWsw==", + "version": "8.36.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.36.0.tgz", + "integrity": "sha512-Y956lmS7vDqomxlaaQAHVmeb4tNMp2FWIvU/RnU5BD3IKMD/MJPr76xdyr68P8tV1iNMvN2mRK0yy3c+UjL+bw==", "dev": true, "requires": { - "@eslint/eslintrc": "^2.0.0", - "@eslint/js": "8.35.0", + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.4.0", + "@eslint/eslintrc": "^2.0.1", + "@eslint/js": "8.36.0", "@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -13232,9 +15186,8 @@ "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", "eslint-visitor-keys": "^3.3.0", - "espree": "^9.4.0", + "espree": "^9.5.0", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -13256,12 +15209,17 @@ "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.1", - "regexpp": "^3.2.0", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" }, "dependencies": { + "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 + }, "eslint-scope": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", @@ -13277,6 +15235,15 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } } } }, @@ -13288,12 +15255,12 @@ "requires": {} }, "eslint-config-standard-with-typescript": { - "version": "34.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-standard-with-typescript/-/eslint-config-standard-with-typescript-34.0.0.tgz", - "integrity": "sha512-zhCsI4/A0rJ1ma8sf3RLXYc0gc7yPmdTWRVXMh9dtqeUx3yBQyALH0wosHhk1uQ9QyItynLdNOtcHKNw8G7lQw==", + "version": "34.0.1", + "resolved": "https://registry.npmjs.org/eslint-config-standard-with-typescript/-/eslint-config-standard-with-typescript-34.0.1.tgz", + "integrity": "sha512-J7WvZeLtd0Vr9F+v4dZbqJCLD16cbIy4U+alJMq4MiXdpipdBM3U5NkXaGUjePc4sb1ZE01U9g6VuTBpHHz1fg==", "dev": true, "requires": { - "@typescript-eslint/parser": "^5.0.0", + "@typescript-eslint/parser": "^5.43.0", "eslint-config-standard": "17.0.0" } }, @@ -13344,6 +15311,7 @@ "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-4.1.0.tgz", "integrity": "sha512-GILhQTnjYE2WorX5Jyi5i4dz5ALWxBIdQECVQavL6s7cI76IZTDWleTHkxz/QT3kvcs2QlGHvKLYsSlPOlPXnQ==", "dev": true, + "peer": true, "requires": { "eslint-utils": "^2.0.0", "regexpp": "^3.0.0" @@ -13354,6 +15322,7 @@ "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, + "peer": true, "requires": { "eslint-visitor-keys": "^1.1.0" } @@ -13362,7 +15331,8 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true + "dev": true, + "peer": true } } }, @@ -13420,6 +15390,7 @@ "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-15.6.1.tgz", "integrity": "sha512-R9xw9OtCRxxaxaszTQmQAlPgM+RdGjaL1akWuY/Fv9fRAi8Wj4CUKc6iYVG8QNRjRuo8/BqVYIpfqberJUEacA==", "dev": true, + "peer": true, "requires": { "builtins": "^5.0.1", "eslint-plugin-es": "^4.1.0", @@ -13431,6 +15402,53 @@ "semver": "^7.3.8" } }, + "eslint-plugin-node": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", + "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", + "dev": true, + "requires": { + "eslint-plugin-es": "^3.0.0", + "eslint-utils": "^2.0.0", + "ignore": "^5.1.1", + "minimatch": "^3.0.4", + "resolve": "^1.10.1", + "semver": "^6.1.0" + }, + "dependencies": { + "eslint-plugin-es": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", + "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", + "dev": true, + "requires": { + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" + } + }, + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, "eslint-plugin-promise": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz", @@ -13438,6 +15456,13 @@ "dev": true, "requires": {} }, + "eslint-plugin-standard": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-5.0.0.tgz", + "integrity": "sha512-eSIXPc9wBM4BrniMzJRBm2uoVuXz2EPa+NXPk2+itrVt+r5SbKFERx/IgrK/HmfjddyKVz2f+j+7gBRvu19xLg==", + "dev": true, + "requires": {} + }, "eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", @@ -13453,6 +15478,7 @@ "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", "dev": true, + "peer": true, "requires": { "eslint-visitor-keys": "^2.0.0" }, @@ -13461,7 +15487,8 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true + "dev": true, + "peer": true } } }, @@ -13472,9 +15499,9 @@ "dev": true }, "espree": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", - "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.0.tgz", + "integrity": "sha512-JPbJGhKc47++oo4JkEoTe2wjy4fmMwvFpgJT9cQzmfXKp22Dr6Hf1tdCteLz1h0P3t+mGvWZ+4Uankvh8+c6zw==", "dev": true, "requires": { "acorn": "^8.8.0", @@ -13613,6 +15640,25 @@ "vary": "~1.1.2" }, "dependencies": { + "body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "requires": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + } + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -13625,9 +15671,38 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "requires": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } } } }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "dev": true + }, + "faker": { + "version": "6.6.6", + "resolved": "https://registry.npmjs.org/faker/-/faker-6.6.6.tgz", + "integrity": "sha512-9tCqYEDHI5RYFQigXFwF1hnCwcWCOJl/hmll0lr5D2Ljjb0o4wphb69wikeJDz5qCEzXCoPvG6ss5SDP6IfOdg==", + "dev": true + }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -13661,8 +15736,7 @@ "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 + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" }, "fast-levenshtein": { "version": "2.0.6", @@ -13725,7 +15799,6 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, "requires": { "to-regex-range": "^5.0.1" } @@ -13816,14 +15889,20 @@ "is-callable": "^1.1.3" } }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "dev": true + }, "form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", "dev": true, "requires": { "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", + "combined-stream": "^1.0.6", "mime-types": "^2.1.12" } }, @@ -13869,12 +15948,7 @@ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", "requires": { "yallist": "^4.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } } } }, @@ -13887,7 +15961,6 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, "optional": true }, "function-bind": { @@ -14001,6 +16074,15 @@ "get-intrinsic": "^1.1.1" } }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, "git-commit-msg-linter": { "version": "4.9.2", "resolved": "https://registry.npmjs.org/git-commit-msg-linter/-/git-commit-msg-linter-4.9.2.tgz", @@ -14145,9 +16227,9 @@ } }, "graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true }, "grapheme-splitter": { @@ -14156,6 +16238,43 @@ "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", "dev": true }, + "graphql": { + "version": "16.6.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.6.0.tgz", + "integrity": "sha512-KPIBPDlW7NxrbT/eh4qPXz5FiFdL5UbaA0XUNz2Rp3Z3hqBSkbj0GVjwFDztsWVauZUWsbKHgMg++sk8UX0bkw==" + }, + "graphql-scalars": { + "version": "1.20.4", + "resolved": "https://registry.npmjs.org/graphql-scalars/-/graphql-scalars-1.20.4.tgz", + "integrity": "sha512-/hDzWcphV/aV4MEx2pqVMMekBLi9VXYD/HrJSclpOCLkSB/dE3Rb5VVZBXsQhgBxqeCsE7K0PEO2/cWAUzQsrQ==", + "requires": { + "tslib": "~2.5.0" + } + }, + "graphql-tag": { + "version": "2.12.6", + "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.6.tgz", + "integrity": "sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==", + "requires": { + "tslib": "^2.1.0" + } + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", + "dev": true + }, + "har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "dev": true, + "requires": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + } + }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -14234,6 +16353,17 @@ "toidentifier": "1.0.1" } }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, "https-proxy-agent": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", @@ -14275,6 +16405,11 @@ "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", "dev": true }, + "ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==" + }, "import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -14368,6 +16503,14 @@ "has-bigints": "^1.0.1" } }, + "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==", + "requires": { + "binary-extensions": "^2.0.0" + } + }, "is-boolean-object": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", @@ -14405,8 +16548,7 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" }, "is-fullwidth-code-point": { "version": "4.0.0", @@ -14424,7 +16566,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, "requires": { "is-extglob": "^2.1.1" } @@ -14438,8 +16579,7 @@ "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 + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" }, "is-number-object": { "version": "1.0.7", @@ -14512,6 +16652,12 @@ "has-tostringtag": "^1.0.0" } }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true + }, "is-weakref": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", @@ -14521,12 +16667,24 @@ "call-bind": "^1.0.2" } }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "dev": true + }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", + "dev": true + }, "istanbul-lib-coverage": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", @@ -14654,6 +16812,57 @@ "jest-validate": "^29.5.0", "prompts": "^2.0.1", "yargs": "^17.3.1" + }, + "dependencies": { + "cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + } + }, + "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 + }, + "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 + }, + "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, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "yargs": { + "version": "17.7.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", + "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", + "dev": true, + "requires": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + } + } } }, "jest-config": { @@ -15028,14 +17237,21 @@ "dev": true }, "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, "requires": { - "argparse": "^2.0.1" + "argparse": "^1.0.7", + "esprima": "^4.0.0" } }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", + "dev": true + }, "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -15048,6 +17264,12 @@ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, + "json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "dev": true + }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -15060,6 +17282,12 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true + }, "json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -15077,6 +17305,18 @@ "semver": "^7.3.8" } }, + "jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + } + }, "jwa": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", @@ -15102,6 +17342,12 @@ "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", "dev": true }, + "lcov-parse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-1.0.0.tgz", + "integrity": "sha512-aprLII/vPzuQvYZnDRU78Fns9I2Ag3gi4Ipga/hxnVMCZC8DnR2nI7XBqrPoywGfxqIx/DgarGvDJZAD3YBTgQ==", + "dev": true + }, "leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -15164,9 +17410,9 @@ "dev": true }, "execa": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-7.0.0.tgz", - "integrity": "sha512-tQbH0pH/8LHTnwTrsKWideqi6rFB/QNUawEwrn+WHyz7PX1Tuz2u7wfTvbaNBdP5JD5LVWxNo8/A8CHNZ3bV6g==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-7.1.1.tgz", + "integrity": "sha512-wH0eMf/UXckdUYnO21+HDztteVv05rq2GXksxT4fCGeHkBhw1DROXh40wcjMcRqDOWE7iPJ4n3M7e2+YFP+76Q==", "dev": true, "requires": { "cross-spawn": "^7.0.3", @@ -15181,9 +17427,9 @@ } }, "human-signals": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.0.tgz", - "integrity": "sha512-zyzVyMjpGBX2+6cDVZeFPCdtOtdsxOeseRhB9tkQ6xXmGUNrcnBzdEKPy3VPNYz+4gy1oukVOXcrJCunSyc6QQ==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz", + "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==", "dev": true }, "is-stream": { @@ -15231,9 +17477,9 @@ } }, "listr2": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-5.0.7.tgz", - "integrity": "sha512-MD+qXHPmtivrHIDRwPYdfNkrzqDiuaKU/rfBcec3WMyMF3xylQj3jMq344OtvQxz7zaCFViRAeqlr2AFhPvXHw==", + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-5.0.8.tgz", + "integrity": "sha512-mC73LitKHj9w6v30nLNGPetZIlfpUniNSsxxrbaPcWOjDb92SHPzJPi/t+v1YC/lxKz/AJ9egOjww0qUuFxBpA==", "dev": true, "requires": { "cli-truncate": "^2.1.0", @@ -15318,6 +17564,17 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==" + }, + "log-driver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", + "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==", + "dev": true + }, "log-update": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", @@ -15377,13 +17634,22 @@ } } }, + "loglevel": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.8.1.tgz", + "integrity": "sha512-tCRIJM51SHjAayKwC+QAg8hT8vg6z7GSgLJKGvzuPb1Wc+hLzqtuVLxp6/HzSPOozuK+8ErAhy7U/sVzw8Dgfg==" + }, + "long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "requires": { - "yallist": "^3.0.2" + "yallist": "^4.0.0" } }, "make-dir": { @@ -15504,9 +17770,9 @@ "dev": true }, "minipass": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.4.tgz", - "integrity": "sha512-lwycX3cBMTvcejsHITUgYj6Gy6A7Nh4Q6h9NP4sTHY1ccJlC7yKzDmiShEHsJ16Jf1nKGDEaiHxiltsJEvk0nQ==" + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.5.tgz", + "integrity": "sha512-+yQl7SX3bIT83Lhb4BVorMAHVuqsskxRdlmO9kTpyukp8vsm2Sn/fUOV9xlnG8/a5JsypJzap21lz/y3FBMJ8Q==" }, "minizlib": { "version": "2.1.2", @@ -15524,11 +17790,6 @@ "requires": { "yallist": "^4.0.0" } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } } }, @@ -15548,6 +17809,11 @@ "resolved": "https://registry.npmjs.org/module-alias/-/module-alias-2.2.2.tgz", "integrity": "sha512-A/78XjoX2EmNvppVWEhM2oGk3x4lLxnkEA4jTbaK97QKSDjkIoOsKQlfylt/d3kKKi596Qy3NP5XrXJ6fZIC9Q==" }, + "mongo-round": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mongo-round/-/mongo-round-1.0.0.tgz", + "integrity": "sha512-lwvLJv827Uks+3HnTOt1I/Qr78Avke3du1oMaFqFpTwtRKtOposNOKkfpGXQN4ZGpRN3XAS8fEppIJ4TUj0xQw==" + }, "mongodb": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-5.1.0.tgz", @@ -15569,65 +17835,13 @@ } }, "mongodb-memory-server": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/mongodb-memory-server/-/mongodb-memory-server-8.12.0.tgz", - "integrity": "sha512-F5BLfliNiLK4FwpXbh4+F3UjvIHVq/G9GPob+xJMLWywRfSfH23cLPEmPuqqqPpOI/ROztUdaeAz8sn6U74kuQ==", + "version": "8.11.5", + "resolved": "https://registry.npmjs.org/mongodb-memory-server/-/mongodb-memory-server-8.11.5.tgz", + "integrity": "sha512-/yiw3L2TIMpi9I6GXg379k6d+RG3k+9V9o24kK5h+NBTtYLNuWa5iEvtce/O3jqhg6yo31T5XG2e/Hm4UwBM1A==", "dev": true, "requires": { - "mongodb-memory-server-core": "8.12.0", - "tslib": "^2.5.0" - }, - "dependencies": { - "bson": { - "version": "4.7.2", - "resolved": "https://registry.npmjs.org/bson/-/bson-4.7.2.tgz", - "integrity": "sha512-Ry9wCtIZ5kGqkJoi6aD8KjxFZEx78guTQDnpXWiNthsxzrxAK/i8E6pCHAIZTbaEFWcOCvbecMukfK7XUvyLpQ==", - "dev": true, - "requires": { - "buffer": "^5.6.0" - } - }, - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true - }, - "mongodb": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-4.14.0.tgz", - "integrity": "sha512-coGKkWXIBczZPr284tYKFLg+KbGPPLlSbdgfKAb6QqCFt5bo5VFZ50O3FFzsw4rnkqjwT6D8Qcoo9nshYKM7Mg==", - "dev": true, - "requires": { - "@aws-sdk/credential-providers": "^3.186.0", - "bson": "^4.7.0", - "mongodb-connection-string-url": "^2.5.4", - "saslprep": "^1.0.3", - "socks": "^2.7.1" - } - }, - "mongodb-memory-server-core": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/mongodb-memory-server-core/-/mongodb-memory-server-core-8.12.0.tgz", - "integrity": "sha512-p+4DbwMJAUqwv15w+WSFkFsGI9zjaUT0BJ1xkQd7sNkO8c9+3Ch5ZCH9AoTzbnNcvqHXj4rpj3VRJb8EZNMT3g==", - "dev": true, - "requires": { - "async-mutex": "^0.3.2", - "camelcase": "^6.3.0", - "debug": "^4.3.4", - "find-cache-dir": "^3.3.2", - "get-port": "^5.1.1", - "https-proxy-agent": "^5.0.1", - "md5-file": "^5.0.0", - "mongodb": "^4.13.0", - "new-find-package-json": "^2.0.0", - "semver": "^7.3.8", - "tar-stream": "^2.1.4", - "tslib": "^2.5.0", - "uuid": "^9.0.0", - "yauzl": "^2.10.0" - } - } + "mongodb-memory-server-core": "8.11.5", + "tslib": "^2.4.1" } }, "mongodb-memory-server-core": { @@ -15684,84 +17898,11 @@ } } }, - "mongodb-memory-server-global": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/mongodb-memory-server-global/-/mongodb-memory-server-global-8.12.0.tgz", - "integrity": "sha512-xNr6nMhQHFVWmciIoA9m5GAiETScEKoh+HFHEqYgLwc9/sfmF8fcvZNgQFVTUY4H9Ud0rQdUeUUkkfBzqqM82w==", - "dev": true, - "requires": { - "mongodb-memory-server-core": "8.12.0", - "tslib": "^2.5.0" - }, - "dependencies": { - "bson": { - "version": "4.7.2", - "resolved": "https://registry.npmjs.org/bson/-/bson-4.7.2.tgz", - "integrity": "sha512-Ry9wCtIZ5kGqkJoi6aD8KjxFZEx78guTQDnpXWiNthsxzrxAK/i8E6pCHAIZTbaEFWcOCvbecMukfK7XUvyLpQ==", - "dev": true, - "requires": { - "buffer": "^5.6.0" - } - }, - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true - }, - "mongodb": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-4.14.0.tgz", - "integrity": "sha512-coGKkWXIBczZPr284tYKFLg+KbGPPLlSbdgfKAb6QqCFt5bo5VFZ50O3FFzsw4rnkqjwT6D8Qcoo9nshYKM7Mg==", - "dev": true, - "requires": { - "@aws-sdk/credential-providers": "^3.186.0", - "bson": "^4.7.0", - "mongodb-connection-string-url": "^2.5.4", - "saslprep": "^1.0.3", - "socks": "^2.7.1" - } - }, - "mongodb-memory-server-core": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/mongodb-memory-server-core/-/mongodb-memory-server-core-8.12.0.tgz", - "integrity": "sha512-p+4DbwMJAUqwv15w+WSFkFsGI9zjaUT0BJ1xkQd7sNkO8c9+3Ch5ZCH9AoTzbnNcvqHXj4rpj3VRJb8EZNMT3g==", - "dev": true, - "requires": { - "async-mutex": "^0.3.2", - "camelcase": "^6.3.0", - "debug": "^4.3.4", - "find-cache-dir": "^3.3.2", - "get-port": "^5.1.1", - "https-proxy-agent": "^5.0.1", - "md5-file": "^5.0.0", - "mongodb": "^4.13.0", - "new-find-package-json": "^2.0.0", - "semver": "^7.3.8", - "tar-stream": "^2.1.4", - "tslib": "^2.5.0", - "uuid": "^9.0.0", - "yauzl": "^2.10.0" - } - } - } - }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, - "mz": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "dev": true, - "requires": { - "any-promise": "^1.0.0", - "object-assign": "^4.0.1", - "thenify-all": "^1.0.0" - } - }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -15788,6 +17929,11 @@ "debug": "^4.3.4" } }, + "node-abort-controller": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", + "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==" + }, "node-addon-api": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", @@ -15811,28 +17957,83 @@ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, - "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + } + } + }, + "node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true + }, + "node-releases": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz", + "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==", + "dev": true + }, + "nodemon": { + "version": "2.0.21", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.21.tgz", + "integrity": "sha512-djN/n2549DUtY33S7o1djRCd7dEm0kBnj9c7S9XVXqRUbuggN1MZH/Nqa+5RFQr63Fbefq37nFXAE9VU86yL1A==", + "requires": { + "chokidar": "^3.5.2", + "debug": "^3.2.7", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.1.2", + "pstree.remy": "^1.1.8", + "semver": "^5.7.1", + "simple-update-notifier": "^1.0.7", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "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==" + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" + "has-flag": "^3.0.0" } } } }, - "node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "dev": true - }, - "node-releases": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz", - "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==", - "dev": true + "noms": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/noms/-/noms-0.0.0.tgz", + "integrity": "sha512-lNDU9VJaOPxUmXcLb+HQFeUgQQPtMI24Gt6hgfuMHRJgMRHMF/qZ4HJD3GDru4sSw9IQl2jPjAYnQrdIeLbwow==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "~1.0.31" + } }, "nopt": { "version": "5.0.0", @@ -15845,8 +18046,7 @@ "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 + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" }, "npm-run-path": { "version": "4.0.1", @@ -15868,6 +18068,12 @@ "set-blocking": "^2.0.0" } }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -16063,6 +18269,12 @@ "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", "dev": true }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "dev": true + }, "picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -16072,8 +18284,7 @@ "picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" }, "pidtree": { "version": "0.6.0", @@ -16160,6 +18371,12 @@ } } }, + "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 + }, "prompts": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", @@ -16179,15 +18396,26 @@ "ipaddr.js": "1.9.1" } }, + "psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", + "dev": true + }, + "pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==" + }, "punycode": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==" }, "pure-rand": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.0.tgz", - "integrity": "sha512-rLSBxJjP+4DQOgcJAx6RZHT2he2pkhQdSnofG5VWyVl6GRq/K02ISOuOLcsMOrtKDIJb8JN2zm3FFzWNbezdPw==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.1.tgz", + "integrity": "sha512-t+x1zEHDjBwkDGY5v5ApnZ/utcd4XYDiJsaQQoptTXgUXX95sDg1elCdJghzicm7n2mbCBJ3uYWr6M22SO19rg==", "dev": true }, "qs": { @@ -16210,9 +18438,9 @@ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" }, "raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", "requires": { "bytes": "3.1.2", "http-errors": "2.0.0", @@ -16227,13 +18455,23 @@ "dev": true }, "readable-stream": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.1.tgz", - "integrity": "sha512-+rQmrWMYGA90yenhTYsLWAsLsqVC8osOw6PKE1HDYiO0gdPeKe/xDHNzIAIn4C91YQ6oenEhfYqqc1883qHbjQ==", + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", + "dev": true, "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "requires": { + "picomatch": "^2.2.1" } }, "regexp.prototype.flags": { @@ -16253,6 +18491,48 @@ "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "dev": true + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + } + } + }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -16309,6 +18589,11 @@ "signal-exit": "^3.0.2" } }, + "retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==" + }, "reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -16340,9 +18625,9 @@ } }, "glob": { - "version": "9.2.1", - "resolved": "https://registry.npmjs.org/glob/-/glob-9.2.1.tgz", - "integrity": "sha512-Pxxgq3W0HyA3XUvSXcFhRSs+43Jsx0ddxcFrbjxNGkL2Ak5BAUBxLqI5G6ADDeCHLfzzXFhe0b1yYcctGmytMA==", + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.1.tgz", + "integrity": "sha512-qERvJb7IGsnkx6YYmaaGvDpf77c951hICMdWaFXyH3PlVob8sbPJJyJX0kWkiCWyXUzoy9UOTNjGg0RbD8bYIw==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -16416,21 +18701,6 @@ "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "requires": { "lru-cache": "^6.0.0" - }, - "dependencies": { - "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==", - "requires": { - "yallist": "^4.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - } } }, "send": { @@ -16496,6 +18766,15 @@ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -16526,6 +18805,21 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, + "simple-update-notifier": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz", + "integrity": "sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==", + "requires": { + "semver": "~7.0.0" + }, + "dependencies": { + "semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==" + } + } + }, "sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", @@ -16601,6 +18895,23 @@ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, + "sshpk": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", + "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", + "dev": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, "stack-utils": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", @@ -16624,12 +18935,10 @@ "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" }, "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", + "dev": true }, "string-argv": { "version": "0.3.1", @@ -16675,6 +18984,17 @@ } } }, + "string.prototype.trim": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz", + "integrity": "sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + } + }, "string.prototype.trimend": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", @@ -16729,42 +19049,6 @@ "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==", "optional": true }, - "sucrase": { - "version": "3.29.0", - "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.29.0.tgz", - "integrity": "sha512-bZPAuGA5SdFHuzqIhTAqt9fvNEo9rESqXIG3oiKdF8K4UmkQxC4KlNL3lVyAErXp+mPvUqZ5l13qx6TrDIGf3A==", - "dev": true, - "requires": { - "commander": "^4.0.0", - "glob": "7.1.6", - "lines-and-columns": "^1.1.6", - "mz": "^2.7.0", - "pirates": "^4.0.1", - "ts-interface-checker": "^0.1.9" - }, - "dependencies": { - "commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "dev": true - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, "superagent": { "version": "8.0.9", "resolved": "https://registry.npmjs.org/superagent/-/superagent-8.0.9.tgz", @@ -16783,6 +19067,17 @@ "semver": "^7.3.8" }, "dependencies": { + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, "mime": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", @@ -16840,13 +19135,6 @@ "minizlib": "^2.1.1", "mkdirp": "^1.0.3", "yallist": "^4.0.0" - }, - "dependencies": { - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - } } }, "tar-stream": { @@ -16860,6 +19148,28 @@ "fs-constants": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.1.1" + }, + "dependencies": { + "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, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + } } }, "test-exclude": { @@ -16879,30 +19189,60 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, - "thenify": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", - "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "dev": true, - "requires": { - "any-promise": "^1.0.0" - } - }, - "thenify-all": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", - "dev": true, - "requires": { - "thenify": ">= 3.1.0 < 4" - } - }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "dev": true }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "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, + "requires": { + "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" + } + }, + "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 + }, + "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, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, "tmp": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", @@ -16939,7 +19279,6 @@ "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, "requires": { "is-number": "^7.0.0" } @@ -16949,6 +19288,34 @@ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" }, + "touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "requires": { + "nopt": "~1.0.10" + }, + "dependencies": { + "nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", + "requires": { + "abbrev": "1" + } + } + } + }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, "tr46": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", @@ -16957,12 +19324,6 @@ "punycode": "^2.1.1" } }, - "ts-interface-checker": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", - "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", - "dev": true - }, "ts-jest": { "version": "29.0.5", "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.0.5.tgz", @@ -16979,27 +19340,6 @@ "yargs-parser": "^21.0.1" } }, - "ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", - "dev": true, - "requires": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - } - }, "tsconfig-paths": { "version": "3.14.2", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", @@ -17032,8 +19372,7 @@ "tslib": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", - "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==", - "devOptional": true + "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==" }, "tsutils": { "version": "3.21.0", @@ -17052,6 +19391,21 @@ } } }, + "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, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", + "dev": true + }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -17094,9 +19448,9 @@ } }, "typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.2.tgz", + "integrity": "sha512-wVORMBGO/FAs/++blGNeAVdbNKtIh1rbBL2EyQ1+J9lClJ93KiiKe8PmFIVdXhHcyv44SL9oglmfeSsndo0jRw==", "dev": true }, "unbox-primitive": { @@ -17111,6 +19465,11 @@ "which-boxed-primitive": "^1.0.2" } }, + "undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==" + }, "underscore": { "version": "1.13.6", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", @@ -17122,6 +19481,12 @@ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" }, + "untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "dev": true + }, "update-browserslist-db": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", @@ -17154,14 +19519,7 @@ "uuid": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", - "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", - "dev": true - }, - "v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==" }, "v8-to-istanbul": { "version": "9.1.0", @@ -17187,11 +19545,35 @@ "resolved": "https://registry.npmjs.org/validator/-/validator-13.9.0.tgz", "integrity": "sha512-B+dGG8U3fdtM0/aNK4/X8CXq/EcxU2WPrPEkJGslb47qyHsxmbggTWK0yEA4qnYVNF+nxNlN88o14hIcPmSIEA==" }, + "value-or-promise": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/value-or-promise/-/value-or-promise-1.0.12.tgz", + "integrity": "sha512-Z6Uz+TYwEqE7ZN50gwn+1LCVo9ZVrpxRPOhOLnncYkY1ZzOYtrX8Fwf/rFktZ8R5mJms6EZf5TqNOMeZmnPq9Q==" + }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + }, + "dependencies": { + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "dev": true + } + } + }, "walker": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", @@ -17206,6 +19588,11 @@ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==" }, + "whatwg-mimetype": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", + "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==" + }, "whatwg-url": { "version": "11.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", @@ -17338,6 +19725,28 @@ "signal-exit": "^3.0.7" } }, + "xss": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/xss/-/xss-1.0.14.tgz", + "integrity": "sha512-og7TEJhXvn1a7kzZGQ7ETjdQVS2UfZyTlsEdDOqvQF7GoxNfY+0YLCzBy1kPdsDDx4QuNAonQPddpsn6Xl/7sw==", + "requires": { + "commander": "^2.20.3", + "cssfilter": "0.0.10" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + } + } + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true + }, "y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -17345,10 +19754,9 @@ "dev": true }, "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "yaml": { "version": "2.2.1", @@ -17357,18 +19765,18 @@ "dev": true }, "yargs": { - "version": "17.7.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", - "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "requires": { - "cliui": "^8.0.1", + "cliui": "^7.0.2", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "string-width": "^4.2.3", + "string-width": "^4.2.0", "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" + "yargs-parser": "^20.2.2" }, "dependencies": { "emoji-regex": { @@ -17393,6 +19801,12 @@ "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } + }, + "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 } } }, @@ -17412,12 +19826,6 @@ "fd-slicer": "~1.1.0" } }, - "yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true - }, "yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index 5de3351..f71df8d 100644 --- a/package.json +++ b/package.json @@ -4,64 +4,79 @@ "description": "NodeJs Rest API and GraphQL using TDD, Clean Architecture, Typescript and Design Patterns", "main": "index.js", "scripts": { - "start": "node dist/main/server.ts", + "start": "node dist/main/server.js", + "debug": "nodemon -L --watchAll ./dist --inspect=0.0.0.0:9222 --nolazy ./dist/main/server.js", "build": "rimraf dist && tsc -p tsconfig-build.json", + "build:watch": "rimraf dist && tsc -p tsconfig-build.json -w", + "postbuild": "copyfiles -u 1 public/**/* dist/static", "dev": "sucrase-node src/main/server.ts", "check": "npm-check -s -u", "test": "jest --passWithNoTests --runInBand --no-cache", - "test:unit": "npm test -- --watch -c jest-unit-config.js", "test:verbose": "jest --passWithNoTests --runInBand", - "test:integration": "npm test -- --watch -c jest-integration-config.js", + "test:unit": "npm test -- --watchAll -c jest-unit-config.js", + "test:integration": "npm test -- --watchAll -c jest-integration-config.js", "test:staged": "npm test -- --findRelatedTests", "test:ci": "npm test -- --coverage", + "test:coveralls": "npm run test:ci && coveralls < coverage/lcov.info", "prepare": "husky install" }, "keywords": [], "author": "Gilberto Mossmann", "license": "GPL-3.0-or-later", "devDependencies": { + "@faker-js/faker": "^7.6.0", "@shelf/jest-mongodb": "^4.1.7", "@types/bcrypt": "^5.0.0", "@types/express": "^4.17.17", - "@types/jest": "^29.4.0", + "@types/express-serve-static-core": "^4.17.33", + "@types/faker": "^6.6.9", + "@types/graphql": "^14.5.0", + "@types/graphql-iso-date": "^3.4.0", + "@types/jest": "^29.5.0", "@types/jsonwebtoken": "^9.0.1", "@types/mongodb": "^4.0.7", - "@types/node": "^18.15.0", + "@types/node": "^18.15.5", "@types/supertest": "^2.0.12", "@types/swagger-ui-express": "^4.1.3", - "@types/validator": "^13.7.13", - "@typescript-eslint/eslint-plugin": "^5.54.0", - "eslint": "^8.35.0", - "eslint-config-standard-with-typescript": "^34.0.0", + "@types/validator": "^13.7.14", + "@typescript-eslint/eslint-plugin": "^5.56.0", + "bson-objectid": "^2.0.4", + "copyfiles": "^2.4.1", + "coveralls": "^3.1.1", + "eslint": "^8.36.0", + "eslint-config-standard-with-typescript": "^34.0.1", "eslint-plugin-import": "^2.27.5", - "eslint-plugin-n": "^15.6.1", + "eslint-plugin-node": "^11.1.0", "eslint-plugin-promise": "^6.1.1", + "eslint-plugin-standard": "^5.0.0", "git-commit-msg-linter": "^4.9.2", "husky": "^8.0.3", "jest": "^29.5.0", "lint-staged": "^13.2.0", "mockdate": "^3.0.5", - "mongodb-memory-server": "^8.12.0", - "mongodb-memory-server-global": "^8.12.0", "rimraf": "^4.4.0", - "sucrase": "^3.29.0", "supertest": "^6.3.3", "ts-jest": "^29.0.5", - "ts-node": "^10.9.1", - "tslib": "^2.5.0", - "typescript": "^4.9.5" + "typescript": "^5.0.2" }, "dependencies": { + "@graphql-tools/schema": "^9.0.17", + "@graphql-tools/utils": "^9.2.1", + "apollo-server-express": "^3.12.0", "bcrypt": "^5.1.0", "express": "^4.18.2", + "graphql": "^16.6.0", + "graphql-scalars": "^1.20.4", "jsonwebtoken": "^9.0.0", "module-alias": "^2.2.2", + "mongo-round": "^1.0.0", "mongodb": "^5.1.0", + "nodemon": "^2.0.21", "swagger-ui-express": "^4.6.2", "validator": "^13.9.0" }, "engines": { - "node": "16.x" + "node": "18.x" }, "_moduleAliases": { "@": "dist" diff --git a/public/img/logo-angular.png b/public/img/logo-angular.png new file mode 100644 index 0000000..278ff96 Binary files /dev/null and b/public/img/logo-angular.png differ diff --git a/public/img/logo-ember.png b/public/img/logo-ember.png new file mode 100644 index 0000000..e14d68c Binary files /dev/null and b/public/img/logo-ember.png differ diff --git a/public/img/logo-flutter.png b/public/img/logo-flutter.png new file mode 100644 index 0000000..b68cfac Binary files /dev/null and b/public/img/logo-flutter.png differ diff --git a/public/img/logo-ionic.png b/public/img/logo-ionic.png new file mode 100644 index 0000000..4ff1abb Binary files /dev/null and b/public/img/logo-ionic.png differ diff --git a/public/img/logo-jquery.png b/public/img/logo-jquery.png new file mode 100644 index 0000000..eadf0d7 Binary files /dev/null and b/public/img/logo-jquery.png differ diff --git a/public/img/logo-js.png b/public/img/logo-js.png new file mode 100644 index 0000000..3be8e4f Binary files /dev/null and b/public/img/logo-js.png differ diff --git a/public/img/logo-knockout.png b/public/img/logo-knockout.png new file mode 100644 index 0000000..24361de Binary files /dev/null and b/public/img/logo-knockout.png differ diff --git a/public/img/logo-native-script.png b/public/img/logo-native-script.png new file mode 100644 index 0000000..b1272f2 Binary files /dev/null and b/public/img/logo-native-script.png differ diff --git a/public/img/logo-nativo.png b/public/img/logo-nativo.png new file mode 100644 index 0000000..f8589ec Binary files /dev/null and b/public/img/logo-nativo.png differ diff --git a/public/img/logo-npm.png b/public/img/logo-npm.png new file mode 100644 index 0000000..7c1e379 Binary files /dev/null and b/public/img/logo-npm.png differ diff --git a/public/img/logo-phonegap.png b/public/img/logo-phonegap.png new file mode 100644 index 0000000..40c3d4f Binary files /dev/null and b/public/img/logo-phonegap.png differ diff --git a/public/img/logo-polymer.png b/public/img/logo-polymer.png new file mode 100644 index 0000000..6182cbd Binary files /dev/null and b/public/img/logo-polymer.png differ diff --git a/public/img/logo-react.png b/public/img/logo-react.png new file mode 100644 index 0000000..e0fdb91 Binary files /dev/null and b/public/img/logo-react.png differ diff --git a/public/img/logo-riot.png b/public/img/logo-riot.png new file mode 100644 index 0000000..243beb2 Binary files /dev/null and b/public/img/logo-riot.png differ diff --git a/public/img/logo-svelte.png b/public/img/logo-svelte.png new file mode 100644 index 0000000..0c32fea Binary files /dev/null and b/public/img/logo-svelte.png differ diff --git a/public/img/logo-titanium.png b/public/img/logo-titanium.png new file mode 100644 index 0000000..8ccded5 Binary files /dev/null and b/public/img/logo-titanium.png differ diff --git a/public/img/logo-ts.png b/public/img/logo-ts.png new file mode 100644 index 0000000..afd7769 Binary files /dev/null and b/public/img/logo-ts.png differ diff --git a/public/img/logo-vue.png b/public/img/logo-vue.png new file mode 100644 index 0000000..21ac4a6 Binary files /dev/null and b/public/img/logo-vue.png differ diff --git a/public/img/logo-xamarin.png b/public/img/logo-xamarin.png new file mode 100644 index 0000000..f120719 Binary files /dev/null and b/public/img/logo-xamarin.png differ diff --git a/public/img/logo-yarn.png b/public/img/logo-yarn.png new file mode 100644 index 0000000..4330815 Binary files /dev/null and b/public/img/logo-yarn.png differ diff --git a/src/data/protocols/cryptography/decrypter.ts b/src/data/protocols/cryptography/decrypter.ts index 462aa74..ed66294 100644 --- a/src/data/protocols/cryptography/decrypter.ts +++ b/src/data/protocols/cryptography/decrypter.ts @@ -1,3 +1,3 @@ export interface Decrypter { - decrypt: (value: string) => Promise + decrypt: (ciphertext: string) => Promise } diff --git a/src/data/protocols/cryptography/encrypter.ts b/src/data/protocols/cryptography/encrypter.ts index 5a0c7c3..4de0534 100644 --- a/src/data/protocols/cryptography/encrypter.ts +++ b/src/data/protocols/cryptography/encrypter.ts @@ -1,3 +1,3 @@ export interface Encrypter { - encrypt: (value: string) => Promise + encrypt: (plaintext: string) => Promise } diff --git a/src/data/protocols/cryptography/hash-comparer.ts b/src/data/protocols/cryptography/hash-comparer.ts index b1c263d..87e8732 100644 --- a/src/data/protocols/cryptography/hash-comparer.ts +++ b/src/data/protocols/cryptography/hash-comparer.ts @@ -1,3 +1,3 @@ export interface HashComparer { - compare: (value: string, hash: string) => Promise + compare: (plaitext: string, digest: string) => Promise } diff --git a/src/data/protocols/cryptography/hasher.ts b/src/data/protocols/cryptography/hasher.ts index 1cccf00..a0e3aa0 100644 --- a/src/data/protocols/cryptography/hasher.ts +++ b/src/data/protocols/cryptography/hasher.ts @@ -1,3 +1,3 @@ export interface Hasher { - hash: (value: string) => Promise + hash: (plaintext: string) => Promise } diff --git a/src/data/protocols/db/account/add-account-repository.ts b/src/data/protocols/db/account/add-account-repository.ts index 780e6cb..3cfae64 100644 --- a/src/data/protocols/db/account/add-account-repository.ts +++ b/src/data/protocols/db/account/add-account-repository.ts @@ -1,6 +1,10 @@ -import { AddAccountParams } from '@/domain/usecases/add-account' -import { AccountModel } from '@/domain/models/account' +import { AddAccount } from '@/domain/usecases' export interface AddAccountRepository { - add: (accountData: AddAccountParams) => Promise + add: (data: AddAccountRepository.Params) => Promise +} + +export namespace AddAccountRepository { + export type Params = AddAccount.Params + export type Result = boolean } diff --git a/src/data/protocols/db/account/check-account-by-email-repository.ts b/src/data/protocols/db/account/check-account-by-email-repository.ts new file mode 100644 index 0000000..9a7823a --- /dev/null +++ b/src/data/protocols/db/account/check-account-by-email-repository.ts @@ -0,0 +1,7 @@ +export interface CheckAccountByEmailRepository { + checkByEmail: (email: string) => Promise +} + +export namespace CheckAccountByEmailRepository { + export type Result = boolean +} diff --git a/src/data/protocols/db/account/index.ts b/src/data/protocols/db/account/index.ts index 2b30a19..58ace17 100644 --- a/src/data/protocols/db/account/index.ts +++ b/src/data/protocols/db/account/index.ts @@ -1,4 +1,5 @@ export * from './add-account-repository' export * from './load-account-by-email-repository' +export * from './check-account-by-email-repository' export * from './load-account-by-token-repository' export * from './update-access-token-repository' diff --git a/src/data/protocols/db/account/load-account-by-email-repository.ts b/src/data/protocols/db/account/load-account-by-email-repository.ts index 375df29..9bb3bfb 100644 --- a/src/data/protocols/db/account/load-account-by-email-repository.ts +++ b/src/data/protocols/db/account/load-account-by-email-repository.ts @@ -1,5 +1,11 @@ -import { AccountModel } from '@/domain/models/account' - export interface LoadAccountByEmailRepository { - loadByEmail: (email: string) => Promise + loadByEmail: (email: string) => Promise +} + +export namespace LoadAccountByEmailRepository { + export type Result = { + id: string + name: string + password: string + } } diff --git a/src/data/protocols/db/account/load-account-by-token-repository.ts b/src/data/protocols/db/account/load-account-by-token-repository.ts index d3536ac..cb93a20 100644 --- a/src/data/protocols/db/account/load-account-by-token-repository.ts +++ b/src/data/protocols/db/account/load-account-by-token-repository.ts @@ -1,5 +1,9 @@ -import { AccountModel } from '@/domain/models/account' - export interface LoadAccountByTokenRepository { - loadByToken: (token: string, role?: string) => Promise + loadByToken: (token: string, role?: string) => Promise +} + +export namespace LoadAccountByTokenRepository { + export type Result = { + id: string + } } diff --git a/src/data/protocols/db/index.ts b/src/data/protocols/db/index.ts new file mode 100644 index 0000000..64ff910 --- /dev/null +++ b/src/data/protocols/db/index.ts @@ -0,0 +1,4 @@ +export * from './account' +export * from './log' +export * from './survey' +export * from './survey-result' diff --git a/src/data/protocols/db/log/index.ts b/src/data/protocols/db/log/index.ts new file mode 100644 index 0000000..3e38ff3 --- /dev/null +++ b/src/data/protocols/db/log/index.ts @@ -0,0 +1 @@ +export * from './log-error-repository' diff --git a/src/data/protocols/db/survey-result/index.ts b/src/data/protocols/db/survey-result/index.ts new file mode 100644 index 0000000..d5c24f1 --- /dev/null +++ b/src/data/protocols/db/survey-result/index.ts @@ -0,0 +1,2 @@ +export * from './load-survey-result-repository' +export * from './save-survey-result-repository' diff --git a/src/data/protocols/db/survey-result/load-survey-result-repository.ts b/src/data/protocols/db/survey-result/load-survey-result-repository.ts new file mode 100644 index 0000000..be23dc0 --- /dev/null +++ b/src/data/protocols/db/survey-result/load-survey-result-repository.ts @@ -0,0 +1,9 @@ +import { SurveyResultModel } from '@/domain/models' + +export interface LoadSurveyResultRepository { + loadBySurveyId: (surveyId: string, accountId: string) => Promise +} + +export namespace LoadSurveyResultRepository { + export type Result = SurveyResultModel +} diff --git a/src/data/protocols/db/survey-result/save-survey-result-repository.ts b/src/data/protocols/db/survey-result/save-survey-result-repository.ts index f10c6cb..6c84f00 100644 --- a/src/data/protocols/db/survey-result/save-survey-result-repository.ts +++ b/src/data/protocols/db/survey-result/save-survey-result-repository.ts @@ -1,6 +1,9 @@ -import { SurveyResultModel } from '@/domain/models/survey-result' -import { SaveSurveyResultParams } from '@/domain/usecases/save-survey-result' +import { SaveSurveyResult } from '@/domain/usecases' export interface SaveSurveyResultRepository { - save: (data: SaveSurveyResultParams) => Promise + save: (data: SaveSurveyResultRepository.Params) => Promise +} + +export namespace SaveSurveyResultRepository { + export type Params = SaveSurveyResult.Params } diff --git a/src/data/protocols/db/survey/add-survey-repository.ts b/src/data/protocols/db/survey/add-survey-repository.ts index 9d35560..b85e413 100644 --- a/src/data/protocols/db/survey/add-survey-repository.ts +++ b/src/data/protocols/db/survey/add-survey-repository.ts @@ -1,5 +1,9 @@ -import { AddSurveyParams } from '@/domain/usecases/add-survey' +import { AddSurvey } from '@/domain/usecases' export interface AddSurveyRepository { - add: (surveyData: AddSurveyParams) => Promise + add: (data: AddSurveyRepository.Params) => Promise +} + +export namespace AddSurveyRepository { + export type Params = AddSurvey.Params } diff --git a/src/data/protocols/db/survey/check-survey-by-id-repository.ts b/src/data/protocols/db/survey/check-survey-by-id-repository.ts new file mode 100644 index 0000000..53a39f8 --- /dev/null +++ b/src/data/protocols/db/survey/check-survey-by-id-repository.ts @@ -0,0 +1,7 @@ +export interface CheckSurveyByIdRepository { + checkById: (id: string) => Promise +} + +export namespace CheckSurveyByIdRepository { + export type Result = boolean +} diff --git a/src/data/protocols/db/survey/index.ts b/src/data/protocols/db/survey/index.ts new file mode 100644 index 0000000..98ae344 --- /dev/null +++ b/src/data/protocols/db/survey/index.ts @@ -0,0 +1,5 @@ +export * from './add-survey-repository' +export * from './load-survey-by-id-repository' +export * from './load-answers-by-survey-repository' +export * from './check-survey-by-id-repository' +export * from './load-surveys-repository' diff --git a/src/data/protocols/db/survey/load-answers-by-survey-repository.ts b/src/data/protocols/db/survey/load-answers-by-survey-repository.ts new file mode 100644 index 0000000..2bd7744 --- /dev/null +++ b/src/data/protocols/db/survey/load-answers-by-survey-repository.ts @@ -0,0 +1,7 @@ +export interface LoadAnswersBySurveyRepository { + loadAnswers: (id: string) => Promise +} + +export namespace LoadAnswersBySurveyRepository { + export type Result = string[] +} diff --git a/src/data/protocols/db/survey/load-survey-by-id-repository.ts b/src/data/protocols/db/survey/load-survey-by-id-repository.ts index c124db1..8d66103 100644 --- a/src/data/protocols/db/survey/load-survey-by-id-repository.ts +++ b/src/data/protocols/db/survey/load-survey-by-id-repository.ts @@ -1,5 +1,9 @@ -import { SurveyModel } from '@/domain/models/survey' +import { SurveyModel } from '@/domain/models' export interface LoadSurveyByIdRepository { - loadById: (id: string) => Promise + loadById: (id: string) => Promise +} + +export namespace LoadSurveyByIdRepository { + export type Result = SurveyModel } diff --git a/src/data/protocols/db/survey/load-surveys-repository.ts b/src/data/protocols/db/survey/load-surveys-repository.ts index 4e6403a..62abfde 100644 --- a/src/data/protocols/db/survey/load-surveys-repository.ts +++ b/src/data/protocols/db/survey/load-surveys-repository.ts @@ -1,5 +1,9 @@ -import { SurveyModel } from '@/domain/models/survey' +import { SurveyModel } from '@/domain/models' export interface LoadSurveysRepository { - loadAll: (accountId: string) => Promise + loadAll: (accountId: string) => Promise +} + +export namespace LoadSurveysRepository { + export type Result = SurveyModel[] } diff --git a/src/data/protocols/index.ts b/src/data/protocols/index.ts new file mode 100644 index 0000000..27896e4 --- /dev/null +++ b/src/data/protocols/index.ts @@ -0,0 +1,2 @@ +export * from './cryptography' +export * from './db' diff --git a/src/data/test/mock-criptography.ts b/src/data/test/mock-criptography.ts deleted file mode 100644 index cec6ad8..0000000 --- a/src/data/test/mock-criptography.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Decrypter, Encrypter, HashComparer, Hasher } from '@/data/protocols/cryptography' - -export const mockHasher = (): Hasher => { - class HasherStub implements Hasher { - async hash (value: string): Promise { - return await Promise.resolve('hashed_password') - } - } - return new HasherStub() -} - -export const mockDecrypter = (): Decrypter => { - class DecrypterStub implements Decrypter { - async decrypt (value: string): Promise { - return await Promise.resolve('any_token') - } - } - return new DecrypterStub() -} - -export const mockEncrypter = (): Encrypter => { - class EncrypterStub implements Encrypter { - async encrypt (value: string): Promise { - return await Promise.resolve('any_token') - } - } - return new EncrypterStub() -} - -export const mockHashComparer = (): HashComparer => { - class HashComparerStub implements HashComparer { - async compare (value: string, hash: string): Promise { - return await Promise.resolve(true) - } - } - return new HashComparerStub() -} diff --git a/src/data/test/mock-db-account.ts b/src/data/test/mock-db-account.ts deleted file mode 100644 index 4a019a1..0000000 --- a/src/data/test/mock-db-account.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { AddAccountRepository, LoadAccountByEmailRepository, LoadAccountByTokenRepository, UpdateAccessTokenRepository } from '@/data/protocols/db/account' -import { AccountModel, AddAccountParams } from '@/data/usecases/add-account/db-add-account-protocols' -import { mockAccountModel } from '@/domain/test' - -export const mockAddAccountRepository = (): AddAccountRepository => { - class AddAccountRepositoryStub implements AddAccountRepository { - async add (accountData: AddAccountParams): Promise { - return await Promise.resolve(mockAccountModel()) - } - } - return new AddAccountRepositoryStub() -} - -export const mockLoadAccountByEmailRepository = (): LoadAccountByEmailRepository => { - class LoadAccountByEmailRepositoryStub implements LoadAccountByEmailRepository { - async loadByEmail (email: string): Promise { - return await Promise.resolve(mockAccountModel()) - } - } - return new LoadAccountByEmailRepositoryStub() -} - -export const mockLoadAccountByTokenRepository = (): LoadAccountByTokenRepository => { - class LoadAccountByTokenRepositoryStub implements LoadAccountByTokenRepository { - async loadByToken (token: string, role?: string): Promise { - return await Promise.resolve(mockAccountModel()) - } - } - return new LoadAccountByTokenRepositoryStub() -} - -export const mockUpdateAccessTokenRepository = (): UpdateAccessTokenRepository => { - class UpdateAccessTokenRepositoryStub implements UpdateAccessTokenRepository { - async updateAccessToken (id: string, token: string): Promise { - await Promise.resolve() - } - } - return new UpdateAccessTokenRepositoryStub() -} diff --git a/src/data/test/mock-db-log.ts b/src/data/test/mock-db-log.ts deleted file mode 100644 index 93fb2b5..0000000 --- a/src/data/test/mock-db-log.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { LogErrorRepository } from '@/data/protocols/db/log/log-error-repository' - -export const mockLogErrorRepository = (): LogErrorRepository => { - class LogErrorRepositoryStub implements LogErrorRepository { - async logError (stack: string): Promise { - await Promise.resolve() - } - } - return new LogErrorRepositoryStub() -} diff --git a/src/data/test/mock-db-survey-result.ts b/src/data/test/mock-db-survey-result.ts deleted file mode 100644 index 598f485..0000000 --- a/src/data/test/mock-db-survey-result.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { SaveSurveyResultRepository } from '@/data/protocols/db/survey-result/save-survey-result-repository' -import { SaveSurveyResultParams, SurveyResultModel } from '@/data/usecases/save-survey-result/db-save-survey-result-protocols' -import { mockSurveyResultModel } from '@/domain/test' - -export const mockSaveSurveyResultRepository = (): SaveSurveyResultRepository => { - class SaveSurveyResultRepositoryStub implements SaveSurveyResultRepository { - async save (data: SaveSurveyResultParams): Promise { - return Promise.resolve(mockSurveyResultModel()) - } - } - return new SaveSurveyResultRepositoryStub() -} diff --git a/src/data/test/mock-db-survey.ts b/src/data/test/mock-db-survey.ts deleted file mode 100644 index 3f63588..0000000 --- a/src/data/test/mock-db-survey.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { AddSurveyRepository } from '@/data/protocols/db/survey/add-survey-repository' -import { LoadSurveyByIdRepository } from '@/data/protocols/db/survey/load-survey-by-id-repository' -import { LoadSurveysRepository } from '@/data/protocols/db/survey/load-surveys-repository' -import { AddSurveyParams } from '@/domain/usecases/add-survey' -import { SurveyModel } from '@/domain/models/survey' -import { mockSurveyModel, mockSurveyModels } from '@/domain/test' - -export const mockAddSurveyRepository = (): AddSurveyRepository => { - class AddSurveyRepositoryStub implements AddSurveyRepository { - async add (surveyData: AddSurveyParams): Promise { - await Promise.resolve() - } - } - return new AddSurveyRepositoryStub() -} - -export const mockLoadSurveyByIdRepository = (): LoadSurveyByIdRepository => { - class LoadSurveyByIdRepositoryStub implements LoadSurveyByIdRepository { - async loadById (id: string): Promise { - return Promise.resolve(mockSurveyModel()) - } - } - return new LoadSurveyByIdRepositoryStub() -} - -export const mockLoadSurveysRepository = (): LoadSurveysRepository => { - class LoadSurveysRepositoryStub implements LoadSurveysRepository { - async loadAll (): Promise { - return Promise.resolve(mockSurveyModels()) - } - } - return new LoadSurveysRepositoryStub() -} diff --git a/src/data/usecases/add-account/db-add-account-protocols.ts b/src/data/usecases/add-account/db-add-account-protocols.ts deleted file mode 100644 index 14b30f7..0000000 --- a/src/data/usecases/add-account/db-add-account-protocols.ts +++ /dev/null @@ -1,5 +0,0 @@ -export * from '@/domain/usecases/add-account' -export * from '@/domain/models/account' -export * from '@/data/protocols/cryptography/hasher' -export * from '@/data/protocols/db/account/add-account-repository' -export * from '@/data/protocols/db/account/load-account-by-email-repository' diff --git a/src/data/usecases/add-account/db-add-account.spec.ts b/src/data/usecases/add-account/db-add-account.spec.ts deleted file mode 100644 index 74bb6bd..0000000 --- a/src/data/usecases/add-account/db-add-account.spec.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { mockAddAccountRepository, mockHasher, mockLoadAccountByEmailRepository } from '@/data/test' -import { Hasher, AddAccountRepository, LoadAccountByEmailRepository } from './db-add-account-protocols' -import { mockAccountModel, mockAddAccountParams, throwError } from '@/domain/test' -import { DbAddAccount } from './db-add-account' - -type SutTypes = { - loadAccountByEmailRepositoryStub: LoadAccountByEmailRepository - sut: DbAddAccount - hasherStub: Hasher - addAccountRepositoryStub: AddAccountRepository -} - -const makeSut = (): SutTypes => { - const loadAccountByEmailRepositoryStub = mockLoadAccountByEmailRepository() - jest.spyOn(loadAccountByEmailRepositoryStub, 'loadByEmail').mockReturnValue(Promise.resolve(null)) - const hasherStub = mockHasher() - const addAccountRepositoryStub = mockAddAccountRepository() - const sut = new DbAddAccount(hasherStub, addAccountRepositoryStub, loadAccountByEmailRepositoryStub) - return { - sut, - hasherStub, - addAccountRepositoryStub, - loadAccountByEmailRepositoryStub - } -} - -describe('DbAddAccount Usecase', () => { - test('Should call Hasher with correct password', async () => { - const { sut, hasherStub } = makeSut() - const hashSpy = jest.spyOn(hasherStub, 'hash') - await sut.add(mockAddAccountParams()) - expect(hashSpy).toHaveBeenCalledWith('any_password') - }) - - test('Should throw if Hasher throws', async () => { - const { sut, hasherStub } = makeSut() - jest.spyOn(hasherStub, 'hash').mockImplementationOnce(throwError) - const promise = sut.add(mockAddAccountParams()) - await expect(promise).rejects.toThrow() - }) - - test('Should call AddAccountRepository with correct values', async () => { - const { sut, addAccountRepositoryStub } = makeSut() - const addSpy = jest.spyOn(addAccountRepositoryStub, 'add') - await sut.add(mockAddAccountParams()) - expect(addSpy).toHaveBeenCalledWith({ - name: 'any_name', - email: 'any_email@example.com', - password: 'any_password' - }) - }) - - test('Should throw if AddAccountRepository throws', async () => { - const { sut, addAccountRepositoryStub } = makeSut() - jest.spyOn(addAccountRepositoryStub, 'add').mockImplementationOnce(throwError) - const promise = sut.add(mockAddAccountParams()) - await expect(promise).rejects.toThrow() - }) - - test('Should return an account on success', async () => { - const { sut } = makeSut() - const account = await sut.add(mockAddAccountParams()) - expect(account).toEqual(mockAccountModel()) - }) - - test('Should return null if LoadAccountByEmailRepository not returns null', async () => { - const { sut, loadAccountByEmailRepositoryStub } = makeSut() - jest.spyOn(loadAccountByEmailRepositoryStub, 'loadByEmail').mockReturnValueOnce(Promise.resolve(mockAccountModel())) - const account = await sut.add(mockAddAccountParams()) - expect(account).toBeNull() - }) - - test('Should call LoadAccountByEmailRepository with correct email', async () => { - const { sut, loadAccountByEmailRepositoryStub } = makeSut() - const loadSpy = jest.spyOn(loadAccountByEmailRepositoryStub, 'loadByEmail') - await sut.add(mockAddAccountParams()) - expect(loadSpy).toHaveBeenCalledWith('any_email@example.com') - }) -}) diff --git a/src/data/usecases/add-account/db-add-account.ts b/src/data/usecases/add-account/db-add-account.ts deleted file mode 100644 index e12e7d5..0000000 --- a/src/data/usecases/add-account/db-add-account.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { AccountModel, AddAccount, AddAccountParams, AddAccountRepository, Hasher, LoadAccountByEmailRepository } from './db-add-account-protocols' - -export class DbAddAccount implements AddAccount { - constructor ( - private readonly hasher: Hasher, - private readonly addAccountRepository: AddAccountRepository, - private readonly loadAccountByEmailRepository: LoadAccountByEmailRepository - ) {} - - async add (accountData: AddAccountParams): Promise { - const account = await this.loadAccountByEmailRepository.loadByEmail(accountData.email) - if (!account) { - const hashedPassword = await this.hasher.hash(accountData.password) - const newAccount = await this.addAccountRepository.add(Object.assign({}, accountData, { password: hashedPassword })) - return newAccount - } - return null - } -} diff --git a/src/data/usecases/add-survey/db-add-survey-protocols.ts b/src/data/usecases/add-survey/db-add-survey-protocols.ts deleted file mode 100644 index a4b1d03..0000000 --- a/src/data/usecases/add-survey/db-add-survey-protocols.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from '@/domain/usecases/add-survey' -export * from '@/data/protocols/survey/add-survey-repository' diff --git a/src/data/usecases/add-survey/db-add-survey.spec.ts b/src/data/usecases/add-survey/db-add-survey.spec.ts deleted file mode 100644 index 562a9aa..0000000 --- a/src/data/usecases/add-survey/db-add-survey.spec.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { DbAddSurvey } from './db-add-survey' -import { AddSurveyRepository } from '@/data/protocols/db/survey/add-survey-repository' -import { mockAddSurveyRepository } from '@/data/test' -import { mockAddSurveyParams, throwError } from '@/domain/test' -import MockDate from 'mockdate' - -type SutTypes = { - sut: DbAddSurvey - addSurveyRepositoryStub: AddSurveyRepository -} - -const makeSut = (): SutTypes => { - const addSurveyRepositoryStub = mockAddSurveyRepository() - const sut = new DbAddSurvey(addSurveyRepositoryStub) - return { - sut, - addSurveyRepositoryStub - } -} - -describe('DbAddSurvey Usecase', () => { - beforeAll(() => { - MockDate.set(new Date()) - }) - - afterAll(() => { - MockDate.reset() - }) - - test('Should call AddSurveyRepository with correct values', async () => { - const { sut, addSurveyRepositoryStub } = makeSut() - const addSpy = jest.spyOn(addSurveyRepositoryStub, 'add') - const surveyData = mockAddSurveyParams() - await sut.add(surveyData) - expect(addSpy).toHaveBeenCalledWith(surveyData) - }) - - test('Should throws if AddSurveyRepository throws', async () => { - const { sut, addSurveyRepositoryStub } = makeSut() - jest.spyOn(addSurveyRepositoryStub, 'add').mockImplementationOnce(throwError) - const promise = sut.add(mockAddSurveyParams()) - await expect(promise).rejects.toThrow() - }) -}) diff --git a/src/data/usecases/add-survey/db-add-survey.ts b/src/data/usecases/add-survey/db-add-survey.ts deleted file mode 100644 index 6b6b6e1..0000000 --- a/src/data/usecases/add-survey/db-add-survey.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { AddSurveyRepository } from '@/data/protocols/db/survey/add-survey-repository' -import { AddSurvey, AddSurveyParams } from './db-add-survey-protocols' - -export class DbAddSurvey implements AddSurvey { - constructor (private readonly addSurveyRepository: AddSurveyRepository) {} - - async add (data: AddSurveyParams): Promise { - await this.addSurveyRepository.add(data) - } -} diff --git a/src/data/usecases/authentication/db-authentication-protocols.ts b/src/data/usecases/authentication/db-authentication-protocols.ts deleted file mode 100644 index b688c42..0000000 --- a/src/data/usecases/authentication/db-authentication-protocols.ts +++ /dev/null @@ -1,6 +0,0 @@ -export * from '@/domain/models/account' -export * from '@/domain/usecases/authentication' -export * from '@/data/protocols/db/account/load-account-by-email-repository' -export * from '@/data/protocols/db/account/update-access-token-repository' -export * from '@/data/protocols/cryptography/hash-compar' -export * from '@/data/protocols/cryptography/encrypter' diff --git a/src/data/usecases/authentication/db-authentication.spec.ts b/src/data/usecases/authentication/db-authentication.spec.ts deleted file mode 100644 index 53c2f86..0000000 --- a/src/data/usecases/authentication/db-authentication.spec.ts +++ /dev/null @@ -1,111 +0,0 @@ -import { HashComparer } from '@/data/protocols/cryptography' -import { mockEncrypter, mockHashComparer, mockLoadAccountByEmailRepository, mockUpdateAccessTokenRepository } from '@/data/test' -import { mockAuthentication, throwError } from '@/domain/test' -import { DbAuthentication } from './db-authentication' -import { Encrypter, UpdateAccessTokenRepository, LoadAccountByEmailRepository } from './db-authentication-protocols' - -type SutTypes = { - sut: DbAuthentication - loadAccountByEmailRepositoryStub: LoadAccountByEmailRepository - hashComparerStub: HashComparer - encrypterStub: Encrypter - updateAccessTokenRepositoryStub: UpdateAccessTokenRepository -} - -const makeSut = (): SutTypes => { - const loadAccountByEmailRepositoryStub = mockLoadAccountByEmailRepository() - const hashComparerStub = mockHashComparer() - const encrypterStub = mockEncrypter() - const updateAccessTokenRepositoryStub = mockUpdateAccessTokenRepository() - const sut = new DbAuthentication( - loadAccountByEmailRepositoryStub, - hashComparerStub, - encrypterStub, - updateAccessTokenRepositoryStub - ) - return { - sut, - loadAccountByEmailRepositoryStub, - hashComparerStub, - encrypterStub, - updateAccessTokenRepositoryStub - } -} - -describe('DbAuthentication UseCase', () => { - test('Should call LoadAccountByEmailRepository with correct email', async () => { - const { sut, loadAccountByEmailRepositoryStub } = makeSut() - const loadSpy = jest.spyOn(loadAccountByEmailRepositoryStub, 'loadByEmail') - await sut.auth(mockAuthentication()) - expect(loadSpy).toHaveBeenCalledWith('any_email@example.com') - }) - - test('Should throw LoadAccountByEmailRepository throws', async () => { - const { sut, loadAccountByEmailRepositoryStub } = makeSut() - jest.spyOn(loadAccountByEmailRepositoryStub, 'loadByEmail').mockImplementationOnce(throwError) - const promise = sut.auth(mockAuthentication()) - await expect(promise).rejects.toThrow() - }) - - test('Should return null if LoadAccountByEmailRepository returns null', async () => { - const { sut, loadAccountByEmailRepositoryStub } = makeSut() - jest.spyOn(loadAccountByEmailRepositoryStub, 'loadByEmail').mockReturnValueOnce(null) - const accessToken = await sut.auth(mockAuthentication()) - expect(accessToken).toBeNull() - }) - - test('Should call HashComparer with correct values', async () => { - const { sut, hashComparerStub } = makeSut() - const compareSpy = jest.spyOn(hashComparerStub, 'compare') - await sut.auth(mockAuthentication()) - expect(compareSpy).toHaveBeenCalledWith('any_password', 'any_password') - }) - - test('Should throw HashComparer throws', async () => { - const { sut, hashComparerStub } = makeSut() - jest.spyOn(hashComparerStub, 'compare').mockImplementationOnce(throwError) - const promise = sut.auth(mockAuthentication()) - await expect(promise).rejects.toThrow() - }) - - test('Should return null if HashComparer returns false', async () => { - const { sut, hashComparerStub } = makeSut() - jest.spyOn(hashComparerStub, 'compare').mockReturnValueOnce(Promise.resolve(false)) - const accessToken = await sut.auth(mockAuthentication()) - expect(accessToken).toBeNull() - }) - - test('Should call Encrypter with correct id', async () => { - const { sut, encrypterStub } = makeSut() - const encryptSpy = jest.spyOn(encrypterStub, 'encrypt') - await sut.auth(mockAuthentication()) - expect(encryptSpy).toHaveBeenCalledWith('any_id') - }) - - test('Should throw Encrypter throws', async () => { - const { sut, encrypterStub } = makeSut() - jest.spyOn(encrypterStub, 'encrypt').mockImplementationOnce(throwError) - const promise = sut.auth(mockAuthentication()) - await expect(promise).rejects.toThrow() - }) - - test('Should return a token on success', async () => { - const { sut } = makeSut() - const accessToken = await sut.auth(mockAuthentication()) - expect(accessToken).toBe('any_token') - }) - - test('Should call UpdateAccessTokenRepository with correct values', async () => { - const { sut, updateAccessTokenRepositoryStub } = makeSut() - const updateSpy = jest.spyOn(updateAccessTokenRepositoryStub, 'updateAccessToken') - await sut.auth(mockAuthentication()) - expect(updateSpy).toHaveBeenCalledWith('any_id', 'any_token') - }) - - test('Should throw UpdateAccessTokenRepository throws', async () => { - const { sut, updateAccessTokenRepositoryStub } = makeSut() - jest.spyOn(updateAccessTokenRepositoryStub, 'updateAccessToken').mockImplementationOnce(throwError) - const promise = sut.auth(mockAuthentication()) - await expect(promise).rejects.toThrow() - }) -}) diff --git a/src/data/usecases/db-add-account.ts b/src/data/usecases/db-add-account.ts new file mode 100644 index 0000000..698fe10 --- /dev/null +++ b/src/data/usecases/db-add-account.ts @@ -0,0 +1,20 @@ +import { AddAccount } from '@/domain/usecases' +import { Hasher, AddAccountRepository, CheckAccountByEmailRepository } from '@/data/protocols' + +export class DbAddAccount implements AddAccount { + constructor ( + private readonly hasher: Hasher, + private readonly addAccountRepository: AddAccountRepository, + private readonly checkAccountByEmailRepository: CheckAccountByEmailRepository + ) {} + + async add (accountData: AddAccount.Params): Promise { + const exists = await this.checkAccountByEmailRepository.checkByEmail(accountData.email) + let isValid = false + if (!exists) { + const hashedPassword = await this.hasher.hash(accountData.password) + isValid = await this.addAccountRepository.add({ ...accountData, password: hashedPassword }) + } + return isValid + } +} diff --git a/src/data/usecases/db-add-survey.ts b/src/data/usecases/db-add-survey.ts new file mode 100644 index 0000000..4f2dd7a --- /dev/null +++ b/src/data/usecases/db-add-survey.ts @@ -0,0 +1,10 @@ +import { AddSurvey } from '@/domain/usecases' +import { AddSurveyRepository } from '@/data/protocols' + +export class DbAddSurvey implements AddSurvey { + constructor (private readonly addSurveyRepository: AddSurveyRepository) {} + + async add (data: AddSurvey.Params): Promise { + await this.addSurveyRepository.add(data) + } +} diff --git a/src/data/usecases/authentication/db-authentication.ts b/src/data/usecases/db-authentication.ts similarity index 62% rename from src/data/usecases/authentication/db-authentication.ts rename to src/data/usecases/db-authentication.ts index dd88e46..b3f7ea9 100644 --- a/src/data/usecases/authentication/db-authentication.ts +++ b/src/data/usecases/db-authentication.ts @@ -1,5 +1,5 @@ -import { HashComparer } from '@/data/protocols/cryptography' -import { Authentication, AuthenticationParams, Encrypter, LoadAccountByEmailRepository, UpdateAccessTokenRepository } from './db-authentication-protocols' +import { Authentication } from '@/domain/usecases' +import { HashComparer, Encrypter, LoadAccountByEmailRepository, UpdateAccessTokenRepository } from '@/data/protocols' export class DbAuthentication implements Authentication { constructor ( @@ -9,14 +9,17 @@ export class DbAuthentication implements Authentication { private readonly updateAccessTokenRepository: UpdateAccessTokenRepository ) {} - async auth (authentication: AuthenticationParams): Promise { - const account = await this.loadAccountByEmailRepository.loadByEmail(authentication.email) + async auth (authenticationParams: Authentication.Params): Promise { + const account = await this.loadAccountByEmailRepository.loadByEmail(authenticationParams.email) if (account) { - const isValid = await this.hashComparer.compare(authentication.password, account.password) + const isValid = await this.hashComparer.compare(authenticationParams.password, account.password) if (isValid) { const accessToken = await this.encrypter.encrypt(account.id) await this.updateAccessTokenRepository.updateAccessToken(account.id, accessToken) - return accessToken + return { + accessToken, + name: account.name + } } } return null diff --git a/src/data/usecases/db-check-survey-by-id.ts b/src/data/usecases/db-check-survey-by-id.ts new file mode 100644 index 0000000..8ba740d --- /dev/null +++ b/src/data/usecases/db-check-survey-by-id.ts @@ -0,0 +1,10 @@ +import { CheckSurveyById } from '@/domain/usecases' +import { CheckSurveyByIdRepository } from '@/data/protocols' + +export class DbCheckSurveyById implements CheckSurveyById { + constructor (private readonly checkSurveyByIdRepository: CheckSurveyByIdRepository) {} + + async checkById (id: string): Promise { + return this.checkSurveyByIdRepository.checkById(id) + } +} diff --git a/src/data/usecases/db-load-account-by-token.ts b/src/data/usecases/db-load-account-by-token.ts new file mode 100644 index 0000000..10934ed --- /dev/null +++ b/src/data/usecases/db-load-account-by-token.ts @@ -0,0 +1,25 @@ +import { LoadAccountByToken } from '@/domain/usecases' +import { Decrypter, LoadAccountByTokenRepository } from '@/data/protocols' + +export class DbLoadAccountByToken implements LoadAccountByToken { + constructor ( + private readonly decrypter: Decrypter, + private readonly loadAccountByTokenRepository: LoadAccountByTokenRepository + ) {} + + async load (accessToken: string, role?: string): Promise { + let token: string + try { + token = await this.decrypter.decrypt(accessToken) + } catch (error) { + return null + } + if (token) { + const account = await this.loadAccountByTokenRepository.loadByToken(accessToken, role) + if (account) { + return account + } + } + return null + } +} diff --git a/src/data/usecases/db-load-answers-by-survey.ts b/src/data/usecases/db-load-answers-by-survey.ts new file mode 100644 index 0000000..869ac03 --- /dev/null +++ b/src/data/usecases/db-load-answers-by-survey.ts @@ -0,0 +1,10 @@ +import { LoadAnswersBySurvey } from '@/domain/usecases' +import { LoadAnswersBySurveyRepository } from '@/data/protocols' + +export class DbLoadAnswersBySurvey implements LoadAnswersBySurvey { + constructor (private readonly loadAnswersBySurveyRepository: LoadAnswersBySurveyRepository) {} + + async loadAnswers (id: string): Promise { + return this.loadAnswersBySurveyRepository.loadAnswers(id) + } +} diff --git a/src/data/usecases/db-load-survey-result.ts b/src/data/usecases/db-load-survey-result.ts new file mode 100644 index 0000000..4a644f8 --- /dev/null +++ b/src/data/usecases/db-load-survey-result.ts @@ -0,0 +1,33 @@ +import { LoadSurveyResult } from '@/domain/usecases' +import { SurveyModel, SurveyResultModel } from '@/domain/models' +import { LoadSurveyResultRepository, LoadSurveyByIdRepository } from '@/data/protocols' + +export class DbLoadSurveyResult implements LoadSurveyResult { + constructor ( + private readonly loadSurveyResultRepository: LoadSurveyResultRepository, + private readonly loadSurveyByIdRepository: LoadSurveyByIdRepository + ) {} + + async load (surveyId: string, accountId: string): Promise { + let surveyResult = await this.loadSurveyResultRepository.loadBySurveyId(surveyId, accountId) + if (!surveyResult) { + const survey = await this.loadSurveyByIdRepository.loadById(surveyId) + surveyResult = this.makeEmptyResult(survey) + } + return surveyResult + } + + private makeEmptyResult (survey: SurveyModel): SurveyResultModel { + return { + surveyId: survey.id, + question: survey.question, + date: survey.date, + answers: survey.answers.map(answer => ({ + ...answer, + count: 0, + percent: 0, + isCurrentAccountAnswer: false + })) + } + } +} diff --git a/src/data/usecases/db-load-surveys.ts b/src/data/usecases/db-load-surveys.ts new file mode 100644 index 0000000..32c599a --- /dev/null +++ b/src/data/usecases/db-load-surveys.ts @@ -0,0 +1,10 @@ +import { LoadSurveys } from '@/domain/usecases' +import { LoadSurveysRepository } from '@/data/protocols' + +export class DbLoadSurveys implements LoadSurveys { + constructor (private readonly loadSurveysRepository: LoadSurveysRepository) {} + + async load (accountId: string): Promise { + return this.loadSurveysRepository.loadAll(accountId) + } +} diff --git a/src/data/usecases/db-save-survey-result.ts b/src/data/usecases/db-save-survey-result.ts new file mode 100644 index 0000000..04f2d05 --- /dev/null +++ b/src/data/usecases/db-save-survey-result.ts @@ -0,0 +1,14 @@ +import { SaveSurveyResult } from '@/domain/usecases' +import { SaveSurveyResultRepository, LoadSurveyResultRepository } from '@/data/protocols' + +export class DbSaveSurveyResult implements SaveSurveyResult { + constructor ( + private readonly saveSurveyResultRepository: SaveSurveyResultRepository, + private readonly loadSurveyResultRepository: LoadSurveyResultRepository + ) {} + + async save (data: SaveSurveyResult.Params): Promise { + await this.saveSurveyResultRepository.save(data) + return this.loadSurveyResultRepository.loadBySurveyId(data.surveyId, data.accountId) + } +} diff --git a/src/data/usecases/index.ts b/src/data/usecases/index.ts new file mode 100644 index 0000000..b304729 --- /dev/null +++ b/src/data/usecases/index.ts @@ -0,0 +1,9 @@ +export * from './db-add-account' +export * from './db-add-survey' +export * from './db-authentication' +export * from './db-load-account-by-token' +export * from './db-load-answers-by-survey' +export * from './db-check-survey-by-id' +export * from './db-load-survey-result' +export * from './db-load-surveys' +export * from './db-save-survey-result' diff --git a/src/data/usecases/load-account-by-token/db-load-account-by-token-protocols.ts b/src/data/usecases/load-account-by-token/db-load-account-by-token-protocols.ts deleted file mode 100644 index 1a1fa22..0000000 --- a/src/data/usecases/load-account-by-token/db-load-account-by-token-protocols.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from '@/data/protocols/cryptography/decrypter' -export * from '@/domain/usecases/load-account-by-token' -export * from '@/data/usecases/add-account/db-add-account-protocols' -export * from '@/data/protocols/db/account/load-Account-by-token-repository' diff --git a/src/data/usecases/load-account-by-token/db-load-account-by-token.spec.ts b/src/data/usecases/load-account-by-token/db-load-account-by-token.spec.ts deleted file mode 100644 index b9d0910..0000000 --- a/src/data/usecases/load-account-by-token/db-load-account-by-token.spec.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { LoadAccountByTokenRepository } from '@/data/protocols/db/account' -import { mockDecrypter, mockLoadAccountByTokenRepository } from '@/data/test' -import { mockAccountModel } from '@/domain/test' -import { DbLoadAccountByToken } from './db-load-account-by-token' -import { Decrypter } from './db-load-account-by-token-protocols' - -type SutTypes = { - sut: DbLoadAccountByToken - decrypterStub: Decrypter - loadAccountByTokenRepositoryStub: LoadAccountByTokenRepository -} - -const makeSut = (): SutTypes => { - const decrypterStub = mockDecrypter() - const loadAccountByTokenRepositoryStub = mockLoadAccountByTokenRepository() - const sut = new DbLoadAccountByToken(decrypterStub, loadAccountByTokenRepositoryStub) - return { - sut, - decrypterStub, - loadAccountByTokenRepositoryStub - } -} - -describe('DbLoadAccountByToken Usecase', () => { - describe('decrypt()', () => { - test('Should call Decrypter with correct values', async () => { - const { sut, decrypterStub } = makeSut() - const decryptSpy = jest.spyOn(decrypterStub, 'decrypt') - await sut.load('any_token', 'any_role') - expect(decryptSpy).toHaveBeenCalledWith('any_token') - }) - - test('Should return null if Decrypter returns null', async () => { - const { sut, decrypterStub } = makeSut() - jest.spyOn(decrypterStub, 'decrypt').mockReturnValueOnce(Promise.resolve(null)) - const account = await sut.load('any_token', 'any_role') - expect(account).toBeNull() - }) - - test('Should return an account on success', async () => { - const { sut } = makeSut() - const account = await sut.load('any_token', 'any_role') - expect(account).toEqual(mockAccountModel()) - }) - - test('Should throw if Decrypter throws', async () => { - const { sut, decrypterStub } = makeSut() - jest.spyOn(decrypterStub, 'decrypt').mockReturnValueOnce(Promise.reject(new Error())) - const promise = sut.load('any_token', 'any_role') - await expect(promise).rejects.toThrow() - }) - }) - - describe('loadByToken()', () => { - test('Should call LoadAccountByTokenRepository with correct values', async () => { - const { sut, loadAccountByTokenRepositoryStub } = makeSut() - const loadByTokenSpy = jest.spyOn(loadAccountByTokenRepositoryStub, 'loadByToken') - await sut.load('any_token', 'any_role') - expect(loadByTokenSpy).toHaveBeenCalledWith('any_token', 'any_role') - }) - - test('Should return null if LoadAccountByTokenRepository returns null', async () => { - const { sut, loadAccountByTokenRepositoryStub } = makeSut() - jest.spyOn(loadAccountByTokenRepositoryStub, 'loadByToken').mockReturnValueOnce(Promise.resolve(null)) - const account = await sut.load('any_token', 'any_role') - expect(account).toBeNull() - }) - - test('Should throw if LoadAccountByTokenRepository throws', async () => { - const { sut, loadAccountByTokenRepositoryStub } = makeSut() - jest.spyOn(loadAccountByTokenRepositoryStub, 'loadByToken').mockReturnValueOnce(Promise.reject(new Error())) - const promise = sut.load('any_token', 'any_role') - await expect(promise).rejects.toThrow() - }) - }) -}) diff --git a/src/data/usecases/load-account-by-token/db-load-account-by-token.ts b/src/data/usecases/load-account-by-token/db-load-account-by-token.ts deleted file mode 100644 index ff927f7..0000000 --- a/src/data/usecases/load-account-by-token/db-load-account-by-token.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { LoadAccountByTokenRepository } from '@/data/protocols/db/account' -import { AccountModel, Decrypter, LoadAccountByToken } from './db-load-account-by-token-protocols' - -export class DbLoadAccountByToken implements LoadAccountByToken { - constructor ( - private readonly decrypter: Decrypter, - private readonly loadAccountByTokenRepository: LoadAccountByTokenRepository - ) {} - - async load (accessToken: string, role?: string): Promise { - const token = await this.decrypter.decrypt(accessToken) - if (token) { - const account = await this.loadAccountByTokenRepository.loadByToken(token, role) - if (account) { - return account - } - } - return null - } -} diff --git a/src/data/usecases/load-survey-by-id/db-load-survey-by-id-protocols.ts b/src/data/usecases/load-survey-by-id/db-load-survey-by-id-protocols.ts deleted file mode 100644 index e6b590e..0000000 --- a/src/data/usecases/load-survey-by-id/db-load-survey-by-id-protocols.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from '@/data/protocols/db/survey/load-survey-by-id-repository' -export * from '@/domain/models/survey' -export * from '@/domain/usecases/load-survey-by-id' diff --git a/src/data/usecases/load-survey-by-id/db-load-survey-by-id.spec.ts b/src/data/usecases/load-survey-by-id/db-load-survey-by-id.spec.ts deleted file mode 100644 index 66a9475..0000000 --- a/src/data/usecases/load-survey-by-id/db-load-survey-by-id.spec.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { DbLoadSurveyById } from './db-load-survey-by-id' -import { LoadSurveyByIdRepository } from './db-load-survey-by-id-protocols' -import { mockLoadSurveyByIdRepository } from '@/data/test' -import { mockSurveyModel, throwError } from '@/domain/test' -import MockDate from 'mockdate' - -type SutTypes = { - sut: DbLoadSurveyById - loadSurveyByIdRepositoryStub: LoadSurveyByIdRepository -} - -const makeSut = (): SutTypes => { - const loadSurveyByIdRepositoryStub = mockLoadSurveyByIdRepository() - const sut = new DbLoadSurveyById(loadSurveyByIdRepositoryStub) - return { - sut, - loadSurveyByIdRepositoryStub - } -} - -describe('DbLoadSurveyById', () => { - beforeAll(() => { - MockDate.set(new Date()) - }) - - afterAll(() => { - MockDate.reset() - }) - - test('Should call LoadSurveyByIdRepository with correct id', async () => { - const { sut, loadSurveyByIdRepositoryStub } = makeSut() - const loadByIdSpy = jest.spyOn(loadSurveyByIdRepositoryStub, 'loadById') - await sut.loadById('any_id') - expect(loadByIdSpy).toHaveBeenCalledWith('any_id') - }) - - test('Should return a list of Surveys on success', async () => { - const { sut } = makeSut() - const survey = await sut.loadById('any_id') - expect(survey).toEqual(mockSurveyModel()) - }) - - test('Should throw if LoadSurveysRepository throws', async () => { - const { sut, loadSurveyByIdRepositoryStub } = makeSut() - jest.spyOn(loadSurveyByIdRepositoryStub, 'loadById').mockImplementationOnce(throwError) - const promise = sut.loadById('any_id') - await expect(promise).rejects.toThrow() - }) -}) diff --git a/src/data/usecases/load-survey-by-id/db-load-survey-by-id.ts b/src/data/usecases/load-survey-by-id/db-load-survey-by-id.ts deleted file mode 100644 index 926bdb2..0000000 --- a/src/data/usecases/load-survey-by-id/db-load-survey-by-id.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { LoadSurveyByIdRepository } from '@/data/protocols/db/survey/load-survey-by-id-repository' -import { LoadSurveyById, SurveyModel } from './db-load-survey-by-id-protocols' - -export class DbLoadSurveyById implements LoadSurveyById { - constructor (private readonly loadSurveyByIdRepository: LoadSurveyByIdRepository) {} - - async loadById (id: string): Promise { - const survey = await this.loadSurveyByIdRepository.loadById(id) - return survey - } -} diff --git a/src/data/usecases/load-surveys/db-load-surveys-protocols.ts b/src/data/usecases/load-surveys/db-load-surveys-protocols.ts deleted file mode 100644 index 46d2d0b..0000000 --- a/src/data/usecases/load-surveys/db-load-surveys-protocols.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from '@/data/protocols/survey/load-surveys-repository' -export * from '@/domain/models/survey' -export * from '@/domain/usecases/load-surveys' diff --git a/src/data/usecases/load-surveys/db-load-surveys.spec.ts b/src/data/usecases/load-surveys/db-load-surveys.spec.ts deleted file mode 100644 index 02503e2..0000000 --- a/src/data/usecases/load-surveys/db-load-surveys.spec.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { DbLoadSurveys } from './db-load-surveys' -import { LoadSurveysRepository } from '@/data/protocols/db/survey/load-surveys-repository' -import { mockLoadSurveysRepository } from '@/data/test' -import { mockSurveyModels } from '@/domain/test' -import MockDate from 'mockdate' - -type SutTypes = { - sut: DbLoadSurveys - loadSurveysRepositoryStub: LoadSurveysRepository -} - -const makeSut = (): SutTypes => { - const loadSurveysRepositoryStub = mockLoadSurveysRepository() - const sut = new DbLoadSurveys(loadSurveysRepositoryStub) - return { - sut, - loadSurveysRepositoryStub - } -} - -describe('DbLoadSurveys', () => { - beforeAll(() => { - MockDate.set(new Date()) - }) - - afterAll(() => { - MockDate.reset() - }) - - test('Should call LoadSurveysRepository', async () => { - const { sut, loadSurveysRepositoryStub } = makeSut() - const loadAllSpy = jest.spyOn(loadSurveysRepositoryStub, 'loadAll') - await sut.load() - expect(loadAllSpy).toHaveBeenCalled() - }) - - test('Should return a list of Surveys on success', async () => { - const { sut } = makeSut() - const surveys = await sut.load() - expect(surveys).toEqual(mockSurveyModels()) - }) - - test('Should throw if LoadSurveysRepository throws', async () => { - const { sut, loadSurveysRepositoryStub } = makeSut() - jest.spyOn(loadSurveysRepositoryStub, 'loadAll').mockReturnValueOnce(Promise.reject(new Error())) - const promise = sut.load() - await expect(promise).rejects.toThrow() - }) -}) diff --git a/src/data/usecases/load-surveys/db-load-surveys.ts b/src/data/usecases/load-surveys/db-load-surveys.ts deleted file mode 100644 index ede1f88..0000000 --- a/src/data/usecases/load-surveys/db-load-surveys.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { LoadSurveysRepository } from '@/data/protocols/db/survey/load-surveys-repository' -import { LoadSurveys, SurveyModel } from './db-load-surveys-protocols' - -export class DbLoadSurveys implements LoadSurveys { - constructor (private readonly loadSurveysRepository: LoadSurveysRepository) {} - - async load (): Promise { - const surveys = await this.loadSurveysRepository.loadAll() - return surveys - } -} diff --git a/src/data/usecases/save-survey-result/db-save-survey-result-protocols.ts b/src/data/usecases/save-survey-result/db-save-survey-result-protocols.ts deleted file mode 100644 index 351aa2f..0000000 --- a/src/data/usecases/save-survey-result/db-save-survey-result-protocols.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from '@/data/protocols/survey/save-survey-result-repository' -export * from '@/domain/models/survey-result' -export * from '@/domain/usecases/save-survey-result' diff --git a/src/data/usecases/save-survey-result/db-save-survey-result.spec.ts b/src/data/usecases/save-survey-result/db-save-survey-result.spec.ts deleted file mode 100644 index b0ef099..0000000 --- a/src/data/usecases/save-survey-result/db-save-survey-result.spec.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { DbSaveSurveyResult } from './db-save-survey-result' -import { SaveSurveyResultRepository } from '@/data/protocols/db/survey-result/save-survey-result-repository' -import { mockSaveSurveyResultRepository } from '@/data/test' -import { throwError , mockSurveyResultModel, mockSaveSurveyResultParams } from '@/domain/test' -import MockDate from 'mockdate' - -type SutTypes = { - sut: DbSaveSurveyResult - saveSurveyResultRepositoryStub: SaveSurveyResultRepository -} - -const makeSut = (): SutTypes => { - const saveSurveyResultRepositoryStub = mockSaveSurveyResultRepository() - const sut = new DbSaveSurveyResult(saveSurveyResultRepositoryStub) - return { - sut, - saveSurveyResultRepositoryStub - } -} - -describe('DbSaveSurveyResult Usecase', () => { - beforeAll(() => { - MockDate.set(new Date()) - }) - - afterAll(() => { - MockDate.reset() - }) - - test('Should call SaveSurveyResultRepository with correct values', async () => { - const { sut, saveSurveyResultRepositoryStub } = makeSut() - const saveSpy = jest.spyOn(saveSurveyResultRepositoryStub, 'save') - const surveyResultData = mockSaveSurveyResultParams() - await sut.save(surveyResultData) - expect(saveSpy).toHaveBeenCalledWith(surveyResultData) - }) - - test('Should throws if SaveSurveyResultRepository throws', async () => { - const { sut, saveSurveyResultRepositoryStub } = makeSut() - jest.spyOn(saveSurveyResultRepositoryStub, 'save').mockImplementationOnce(throwError) - const promise = sut.save(mockSaveSurveyResultParams()) - await expect(promise).rejects.toThrow() - }) - - test('Should return a list of SurveyResult on success', async () => { - const { sut } = makeSut() - const surveyResult = await sut.save(mockSaveSurveyResultParams()) - expect(surveyResult).toEqual(mockSurveyResultModel()) - }) -}) diff --git a/src/data/usecases/save-survey-result/db-save-survey-result.ts b/src/data/usecases/save-survey-result/db-save-survey-result.ts deleted file mode 100644 index 85a16be..0000000 --- a/src/data/usecases/save-survey-result/db-save-survey-result.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { SaveSurveyResultRepository } from '@/data/protocols/db/survey-result/save-survey-result-repository' -import { SaveSurveyResult, SaveSurveyResultParams, SurveyResultModel } from './db-save-survey-result-protocols' - -export class DbSaveSurveyResult implements SaveSurveyResult { - constructor (private readonly saveSurveyResultRepository: SaveSurveyResultRepository) {} - - async save (data: SaveSurveyResultParams): Promise { - const surveyResult = await this.saveSurveyResultRepository.save(data) - return surveyResult - } -} diff --git a/src/domain/models/account.ts b/src/domain/models/account.ts deleted file mode 100644 index 3522403..0000000 --- a/src/domain/models/account.ts +++ /dev/null @@ -1,6 +0,0 @@ -export type AccountModel = { - id: string - name: string - email: string - password: string -} diff --git a/src/domain/models/index.ts b/src/domain/models/index.ts new file mode 100644 index 0000000..1664da4 --- /dev/null +++ b/src/domain/models/index.ts @@ -0,0 +1,2 @@ +export * from './survey' +export * from './survey-result' diff --git a/src/domain/models/survey-result.ts b/src/domain/models/survey-result.ts index 3334350..ab7afee 100644 --- a/src/domain/models/survey-result.ts +++ b/src/domain/models/survey-result.ts @@ -1,7 +1,14 @@ export type SurveyResultModel = { - id: string surveyId: string - accountId: string - answer: string + question: string + answers: SurveyResultAnswerModel[] date: Date } + +type SurveyResultAnswerModel = { + image?: string + answer: string + count: number + percent: number + isCurrentAccountAnswer: boolean +} diff --git a/src/domain/models/survey.ts b/src/domain/models/survey.ts index 592be00..83f6e4b 100644 --- a/src/domain/models/survey.ts +++ b/src/domain/models/survey.ts @@ -3,9 +3,10 @@ export type SurveyModel = { question: string answers: SurveyAnswerModel[] date: Date + didAnswer?: boolean } -export type SurveyAnswerModel = { +type SurveyAnswerModel = { image?: string answer: string } diff --git a/src/domain/test/mock-account.ts b/src/domain/test/mock-account.ts deleted file mode 100644 index c2d67e4..0000000 --- a/src/domain/test/mock-account.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { AccountModel } from '@/domain/models/account' -import { AddAccountParams } from '@/domain/usecases/add-account' -import { AuthenticationParams } from '@/domain/usecases/authentication' - -export const mockAddAccountParams = (): AddAccountParams => ({ - name: 'any_name', - email: 'any_email@example.com', - password: 'any_password' -}) - -export const mockAccountModel = (): AccountModel => Object.assign({}, mockAddAccountParams(), { id: 'any_id' }) - -export const mockAuthentication = (): AuthenticationParams => ({ - email: 'any_email@example.com', - password: 'any_password' -}) diff --git a/src/domain/test/mock-survey-result.ts b/src/domain/test/mock-survey-result.ts deleted file mode 100644 index f53be96..0000000 --- a/src/domain/test/mock-survey-result.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { SurveyResultModel } from '@/domain/models/survey-result' -import { SaveSurveyResultParams } from '@/domain/usecases/save-survey-result' - -export const mockSaveSurveyResultParams = (): SaveSurveyResultParams => ({ - accountId: 'any_account_id', - surveyId: 'any_survey_id', - answer: 'any_answer', - date: new Date() -}) - -export const mockSurveyResultModel = (): SurveyResultModel => Object.assign({}, mockSaveSurveyResultParams(), { - id: 'any_id' -}) diff --git a/src/domain/test/mock-survey.ts b/src/domain/test/mock-survey.ts deleted file mode 100644 index c35bbf7..0000000 --- a/src/domain/test/mock-survey.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { SurveyModel } from '@/domain/models/survey' -import { AddSurveyParams } from '@/domain/usecases/add-survey' - -export const mockSurveyModel = (): SurveyModel => { - return { - id: 'any_id', - question: 'any_question', - answers: [{ - image: 'any_image', - answer: 'any_answer' - }], - date: new Date() - } -} - -export const mockSurveyModels = (): SurveyModel[] => { - return [{ - id: 'any_id', - question: 'any_question', - answers: [{ - image: 'any_image', - answer: 'any_answer' - }], - date: new Date() - }, { - id: 'other_id', - question: 'other_question', - answers: [{ - image: 'other_image', - answer: 'other_answer' - }], - date: new Date() - }] -} - -export const mockAddSurveyParams = (): AddSurveyParams => ({ - question: 'any_question', - answers: [{ - image: 'any_image', - answer: 'any_answer' - }], - date: new Date() -}) diff --git a/src/domain/usecases/add-account.ts b/src/domain/usecases/add-account.ts index 80ca3b1..d7633c0 100644 --- a/src/domain/usecases/add-account.ts +++ b/src/domain/usecases/add-account.ts @@ -1,11 +1,13 @@ -import { AccountModel } from '@/domain/models/account' - -export type AddAccountParams = { - name: string - email: string - password: string +export interface AddAccount { + add: (account: AddAccount.Params) => Promise } -export interface AddAccount { - add: (account: AddAccountParams) => Promise +export namespace AddAccount { + export type Params = { + name: string + email: string + password: string + } + + export type Result = boolean } diff --git a/src/domain/usecases/add-survey.ts b/src/domain/usecases/add-survey.ts index 7db60a2..96b1de5 100644 --- a/src/domain/usecases/add-survey.ts +++ b/src/domain/usecases/add-survey.ts @@ -1,11 +1,9 @@ -import { SurveyResultModel } from '../models/survey-result' +import { SurveyModel } from '@/domain/models' -export type AddSurveyParams = { - question: string - answers: SurveyResultModel[] - date: Date +export interface AddSurvey { + add: (data: AddSurvey.Params) => Promise } -export interface AddSurvey { - add: (data: AddSurveyParams) => Promise +export namespace AddSurvey { + export type Params = Omit } diff --git a/src/domain/usecases/authentication.ts b/src/domain/usecases/authentication.ts index 94b3c6f..67c00b6 100644 --- a/src/domain/usecases/authentication.ts +++ b/src/domain/usecases/authentication.ts @@ -1,8 +1,15 @@ -export type AuthenticationParams = { - email: string - password: string +export interface Authentication { + auth: (authenticationParams: Authentication.Params) => Promise } -export interface Authentication { - auth: (authentication: AuthenticationParams) => Promise +export namespace Authentication { + export type Params = { + email: string + password: string + } + + export type Result = { + accessToken: string + name: string + } } diff --git a/src/domain/usecases/check-survey-by-id.ts b/src/domain/usecases/check-survey-by-id.ts new file mode 100644 index 0000000..1dcb316 --- /dev/null +++ b/src/domain/usecases/check-survey-by-id.ts @@ -0,0 +1,7 @@ +export interface CheckSurveyById { + checkById: (id: string) => Promise +} + +export namespace CheckSurveyById { + export type Result = boolean +} diff --git a/src/domain/usecases/index.ts b/src/domain/usecases/index.ts new file mode 100644 index 0000000..515e272 --- /dev/null +++ b/src/domain/usecases/index.ts @@ -0,0 +1,9 @@ +export * from './add-account' +export * from './authentication' +export * from './load-account-by-token' +export * from './add-survey' +export * from './load-answers-by-survey' +export * from './check-survey-by-id' +export * from './load-surveys' +export * from './load-survey-result' +export * from './save-survey-result' diff --git a/src/domain/usecases/load-account-by-token.ts b/src/domain/usecases/load-account-by-token.ts index 69bdc4b..c98b6c1 100644 --- a/src/domain/usecases/load-account-by-token.ts +++ b/src/domain/usecases/load-account-by-token.ts @@ -1,5 +1,9 @@ -import { AccountModel } from '../models/account' - export interface LoadAccountByToken { - load: (accessToken: string, role?: string) => Promise + load: (accessToken: string, role?: string) => Promise +} + +export namespace LoadAccountByToken { + export type Result = { + id: string + } } diff --git a/src/domain/usecases/load-answers-by-survey.ts b/src/domain/usecases/load-answers-by-survey.ts new file mode 100644 index 0000000..c2183ce --- /dev/null +++ b/src/domain/usecases/load-answers-by-survey.ts @@ -0,0 +1,7 @@ +export interface LoadAnswersBySurvey { + loadAnswers: (id: string) => Promise +} + +export namespace LoadAnswersBySurvey { + export type Result = string[] +} diff --git a/src/domain/usecases/load-survey-by-id.ts b/src/domain/usecases/load-survey-by-id.ts deleted file mode 100644 index dbcd7a3..0000000 --- a/src/domain/usecases/load-survey-by-id.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { SurveyModel } from '../models/survey' - -export interface LoadSurveyById { - loadById: (id: string) => Promise -} diff --git a/src/domain/usecases/load-survey-result.ts b/src/domain/usecases/load-survey-result.ts new file mode 100644 index 0000000..146ed8b --- /dev/null +++ b/src/domain/usecases/load-survey-result.ts @@ -0,0 +1,9 @@ +import { SurveyResultModel } from '@/domain/models' + +export interface LoadSurveyResult { + load: (surveyId: string, accountId: string) => Promise +} + +export namespace LoadSurveyResult { + export type Result = SurveyResultModel +} diff --git a/src/domain/usecases/load-surveys.ts b/src/domain/usecases/load-surveys.ts index aaba43c..46b0631 100644 --- a/src/domain/usecases/load-surveys.ts +++ b/src/domain/usecases/load-surveys.ts @@ -1,5 +1,9 @@ -import { SurveyModel } from '../models/survey' +import { SurveyModel } from '@/domain/models' export interface LoadSurveys { - load: () => Promise + load: (accountId: string) => Promise +} + +export namespace LoadSurveys { + export type Result = SurveyModel[] } diff --git a/src/domain/usecases/save-survey-result.ts b/src/domain/usecases/save-survey-result.ts index 85410c7..e608cf3 100644 --- a/src/domain/usecases/save-survey-result.ts +++ b/src/domain/usecases/save-survey-result.ts @@ -1,12 +1,16 @@ -import { SurveyResultModel } from '../models/survey-result' +import { SurveyResultModel } from '@/domain/models' -export type SaveSurveyResultParams = { - surveyId: string - accountId: string - answer: string - date: Date +export interface SaveSurveyResult { + save: (data: SaveSurveyResult.Params) => Promise } -export interface SaveSurveyResult { - save: (data: SaveSurveyResultParams) => Promise +export namespace SaveSurveyResult { + export type Params = { + surveyId: string + accountId: string + answer: string + date: Date + } + + export type Result = SurveyResultModel } diff --git a/src/infra/cryptography/bcrypt-adapter.ts b/src/infra/cryptography/bcrypt-adapter.ts new file mode 100644 index 0000000..0170b78 --- /dev/null +++ b/src/infra/cryptography/bcrypt-adapter.ts @@ -0,0 +1,15 @@ +import { Hasher, HashComparer } from '@/data/protocols' + +import bcrypt from 'bcrypt' + +export class BcryptAdapter implements Hasher, HashComparer { + constructor (private readonly salt: number) {} + + async hash (plaintext: string): Promise { + return bcrypt.hash(plaintext, this.salt) + } + + async compare (plaintext: string, digest: string): Promise { + return bcrypt.compare(plaintext, digest) + } +} diff --git a/src/infra/cryptography/bcrypt-adapter/bcrypt-adapter.ts b/src/infra/cryptography/bcrypt-adapter/bcrypt-adapter.ts deleted file mode 100644 index 4d62bb1..0000000 --- a/src/infra/cryptography/bcrypt-adapter/bcrypt-adapter.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { HashComparer } from '@/data/protocols/cryptography' -import { Hasher } from '@/data/protocols/cryptography/hasher' -import bcrypt from 'bcrypt' - -export class BcryptAdapter implements Hasher, HashComparer { - constructor (private readonly salt: number) {} - - async hash (value: string): Promise { - const hash = await bcrypt.hash(value, this.salt) - return hash - } - - async compare (value: string, hash: string): Promise { - const isValid = await bcrypt.compare(value, hash) - return isValid - } -} diff --git a/src/infra/cryptography/index.ts b/src/infra/cryptography/index.ts new file mode 100644 index 0000000..7067a93 --- /dev/null +++ b/src/infra/cryptography/index.ts @@ -0,0 +1,2 @@ +export * from './bcrypt-adapter' +export * from './jwt-adapter' diff --git a/src/infra/cryptography/jwt-adapter.ts b/src/infra/cryptography/jwt-adapter.ts new file mode 100644 index 0000000..13a7a24 --- /dev/null +++ b/src/infra/cryptography/jwt-adapter.ts @@ -0,0 +1,15 @@ +import { Encrypter, Decrypter } from '@/data/protocols' + +import jwt from 'jsonwebtoken' + +export class JwtAdapter implements Encrypter, Decrypter { + constructor (private readonly secret: string) {} + + async encrypt (plaintext: string): Promise { + return jwt.sign({ id: plaintext }, this.secret) + } + + async decrypt (ciphertext: string): Promise { + return jwt.verify(ciphertext, this.secret) as any + } +} diff --git a/src/infra/cryptography/jwt-adapter/jwt-adapter.ts b/src/infra/cryptography/jwt-adapter/jwt-adapter.ts deleted file mode 100644 index eec8d2a..0000000 --- a/src/infra/cryptography/jwt-adapter/jwt-adapter.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Decrypter } from '@/data/protocols/cryptography/decrypter' -import { Encrypter } from '@/data/protocols/cryptography/encrypter' -import Jwt from 'jsonwebtoken' - -export class JwtAdapter implements Encrypter, Decrypter { - constructor (private readonly secret: string) {} - - async encrypt (value: string): Promise { - const accessToken = Jwt.sign({ id: value }, this.secret) - return accessToken - } - - async decrypt (token: string): Promise { - const value: any = Jwt.verify(token, this.secret) - return value - } -} diff --git a/src/infra/db/index.ts b/src/infra/db/index.ts new file mode 100644 index 0000000..31b0e7b --- /dev/null +++ b/src/infra/db/index.ts @@ -0,0 +1 @@ +export * from './mongodb' diff --git a/src/infra/db/mongodb/account-mongo-repository.ts b/src/infra/db/mongodb/account-mongo-repository.ts new file mode 100644 index 0000000..bf5e132 --- /dev/null +++ b/src/infra/db/mongodb/account-mongo-repository.ts @@ -0,0 +1,64 @@ +import { MongoHelper } from '@/infra/db' +import type { AddAccountRepository, LoadAccountByEmailRepository, UpdateAccessTokenRepository, LoadAccountByTokenRepository, CheckAccountByEmailRepository } from '@/data/protocols/db' + +export class AccountMongoRepository implements AddAccountRepository, LoadAccountByEmailRepository, UpdateAccessTokenRepository, LoadAccountByTokenRepository, CheckAccountByEmailRepository { + async add (data: AddAccountRepository.Params): Promise { + const accountCollection = MongoHelper.getCollection('accounts') + const result = await accountCollection.insertOne(data) + return result.insertedId !== null + } + + async loadByEmail (email: string): Promise { + const accountCollection = MongoHelper.getCollection('accounts') + const account = await accountCollection.findOne({ + email + }, { + projection: { + _id: 1, + name: 1, + password: 1 + } + }) + return account && MongoHelper.map(account) + } + + async checkByEmail (email: string): Promise { + const accountCollection = MongoHelper.getCollection('accounts') + const account = await accountCollection.findOne({ + email + }, { + projection: { + _id: 1 + } + }) + return account !== null + } + + async updateAccessToken (id: string, token: string): Promise { + const accountCollection = MongoHelper.getCollection('accounts') + await accountCollection.updateOne({ + _id: id as any + }, { + $set: { + accessToken: token + } + }) + } + + async loadByToken (token: string, role?: string): Promise { + const accountCollection = MongoHelper.getCollection('accounts') + const account = await accountCollection.findOne({ + accessToken: token, + $or: [{ + role + }, { + role: 'admin' + }] + }, { + projection: { + _id: 1 + } + }) + return account && MongoHelper.map(account) + } +} diff --git a/src/infra/db/mongodb/account/account-mongo-repository.spec.ts b/src/infra/db/mongodb/account/account-mongo-repository.spec.ts deleted file mode 100644 index 133bf92..0000000 --- a/src/infra/db/mongodb/account/account-mongo-repository.spec.ts +++ /dev/null @@ -1,139 +0,0 @@ -import { AccountMongoRepository } from './account-mongo-repository' -import { MongoHelper } from '../helpers/mongo-helper' -import { mockAddAccountParams } from '@/domain/test' -import { Collection } from 'mongodb' - -let accountCollection: Collection - -describe('Account Mongo Repository', () => { - beforeAll(async () => { - await MongoHelper.connect(process.env.MONGO_URL) - }) - - afterAll(async () => { - await MongoHelper.disconnect() - }) - - beforeEach(async () => { - accountCollection = MongoHelper.getCollection('accounts') - await accountCollection.deleteMany({}) - }) - - const makeSut = (): AccountMongoRepository => { - return new AccountMongoRepository() - } - - describe('add()', () => { - test('Should return an account on add success', async () => { - const sut = makeSut() - const account = await sut.add(mockAddAccountParams()) - expect(account).toBeTruthy() - expect(account.id).toBeTruthy() - expect(account.name).toBe('any_name') - expect(account.email).toBe('any_email@mail.com') - expect(account.password).toBe('any_password') - }) - }) - - describe('loadByEmail()', () => { - test('Should return an account on loadByEmail success', async () => { - const sut = makeSut() - await accountCollection.insertOne(mockAddAccountParams()) - const account = await sut.loadByEmail('any_email@mail.com') - expect(account).toBeTruthy() - expect(account.id).toBeTruthy() - expect(account.name).toBe('any_name') - expect(account.email).toBe('any_email@mail.com') - expect(account.password).toBe('any_password') - }) - - test('Should return null if loadByEmail fails', async () => { - const sut = makeSut() - const account = await sut.loadByEmail('any_email@mail.com') - expect(account).toBeFalsy() - }) - }) - - describe('updateAccessToken()', () => { - test('Should update the account accessToken on success', async () => { - const sut = makeSut() - const res = await accountCollection.insertOne(mockAddAccountParams()) - const fakeAccount = await accountCollection.findOne({ _id: res.insertedId }) - expect(fakeAccount.accessToken).toBeFalsy() - await sut.updateAccessToken(fakeAccount._id.toString(), 'any_token') - const account = await accountCollection.findOne({ _id: fakeAccount._id }) - expect(account).toBeTruthy() - expect(account.accessToken).toBe('any_token') - }) - }) - - describe('loadByToken()', () => { - test('Should return an account on loadByToken without role', async () => { - const sut = makeSut() - await accountCollection.insertOne({ - name: 'any_name', - email: 'any_email@mail.com', - password: 'any_password', - accessToken: 'any_token' - }) - const account = await sut.loadByToken('any_token') - expect(account).toBeTruthy() - expect(account.id).toBeTruthy() - expect(account.name).toBe('any_name') - expect(account.email).toBe('any_email@mail.com') - expect(account.password).toBe('any_password') - }) - - test('Should return an account on loadByToken with admin role', async () => { - const sut = makeSut() - await accountCollection.insertOne({ - name: 'any_name', - email: 'any_email@mail.com', - password: 'any_password', - accessToken: 'any_token', - role: 'admin' - }) - const account = await sut.loadByToken('any_token', 'admin') - expect(account).toBeTruthy() - expect(account.id).toBeTruthy() - expect(account.name).toBe('any_name') - expect(account.email).toBe('any_email@mail.com') - expect(account.password).toBe('any_password') - }) - - test('Should return null on loadByToken with invalid role', async () => { - const sut = makeSut() - await accountCollection.insertOne({ - name: 'any_name', - email: 'any_email@mail.com', - password: 'any_password', - accessToken: 'any_token' - }) - const account = await sut.loadByToken('any_token', 'admin') - expect(account).toBeFalsy() - }) - - test('Should return an account on loadByToken with if user is admin', async () => { - const sut = makeSut() - await accountCollection.insertOne({ - name: 'any_name', - email: 'any_email@mail.com', - password: 'any_password', - accessToken: 'any_token', - role: 'admin' - }) - const account = await sut.loadByToken('any_token') - expect(account).toBeTruthy() - expect(account.id).toBeTruthy() - expect(account.name).toBe('any_name') - expect(account.email).toBe('any_email@mail.com') - expect(account.password).toBe('any_password') - }) - - test('Should return null if loadByToken fails', async () => { - const sut = makeSut() - const account = await sut.loadByToken('any_token') - expect(account).toBeFalsy() - }) - }) -}) diff --git a/src/infra/db/mongodb/account/account-mongo-repository.ts b/src/infra/db/mongodb/account/account-mongo-repository.ts deleted file mode 100644 index 021d0b5..0000000 --- a/src/infra/db/mongodb/account/account-mongo-repository.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { MongoHelper } from '../helpers/mongo-helper' -import { AddAccountParams } from '@/domain/usecases/add-account' -import { AccountModel } from '@/domain/models/account' -import { AddAccountRepository } from '@/data/protocols/db/account/add-account-repository' -import { LoadAccountByEmailRepository } from '@/data/protocols/db/account/load-account-by-email-repository' -import { UpdateAccessTokenRepository } from '@/data/protocols/db/account/update-access-token-repository' -import { ObjectId } from 'mongodb' -import { LoadAccountByTokenRepository } from '@/data/protocols/db/account' - -export class AccountMongoRepository implements AddAccountRepository, LoadAccountByEmailRepository, UpdateAccessTokenRepository, LoadAccountByTokenRepository { - async add (accountData: AddAccountParams): Promise { - const accountCollection = MongoHelper.getCollection('accounts') - const result = await accountCollection.insertOne(accountData) - const insertedId = result?.insertedId?.toString() // verifica se o _id está definido - return MongoHelper.map({ ...accountData, id: insertedId }) - } - - async loadByEmail (email: string): Promise { - const accountCollection = MongoHelper.getCollection('accounts') - const account = await accountCollection.findOne({ email }) - return account && MongoHelper.map(account) - } - - async updateAccessToken (id: string, token: string): Promise { - const accountCollection = MongoHelper.getCollection('accounts') - await accountCollection.updateOne({ - _id: new ObjectId(id) - }, { - $set: { - accessToken: token - } - }) - } - - async loadByToken (token: string, role?: string): Promise { - const accountCollection = MongoHelper.getCollection('accounts') - const account = await accountCollection.findOne({ - accessToken: token, - $or: [{ - role - }, { - role: 'admin' - }] - }) - return account && MongoHelper.map(account) - } -} diff --git a/src/infra/db/mongodb/helpers/mongo-helper.spec.ts b/src/infra/db/mongodb/helpers/mongo-helper.spec.ts deleted file mode 100644 index bc76cbc..0000000 --- a/src/infra/db/mongodb/helpers/mongo-helper.spec.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { MongoHelper as sut } from './mongo-helper' - -describe('Mongo Helper', () => { - beforeAll(async () => { - await sut.connect(process.env.MONGO_URL) - }) - - afterAll(async () => { - await sut.disconnect() - }) - - test('Should reconnect if mongodb is down', async () => { - let accountCollection = sut.getCollection('accounts') - expect(accountCollection).toBeTruthy() - await sut.disconnect() - accountCollection = sut.getCollection('accounts') - expect(accountCollection).toBeTruthy() - }) -}) diff --git a/src/infra/db/mongodb/index.ts b/src/infra/db/mongodb/index.ts new file mode 100644 index 0000000..dbebd40 --- /dev/null +++ b/src/infra/db/mongodb/index.ts @@ -0,0 +1,6 @@ +export * from './account-mongo-repository' +export * from './log-mongo-repository' +export * from './mongo-helper' +export * from './query-builder' +export * from './survey-mongo-repository' +export * from './survey-result-mongo-repository' diff --git a/src/infra/db/mongodb/log/log-mongo-repository.ts b/src/infra/db/mongodb/log-mongo-repository.ts similarity index 66% rename from src/infra/db/mongodb/log/log-mongo-repository.ts rename to src/infra/db/mongodb/log-mongo-repository.ts index 90d9843..fc4af62 100644 --- a/src/infra/db/mongodb/log/log-mongo-repository.ts +++ b/src/infra/db/mongodb/log-mongo-repository.ts @@ -1,5 +1,5 @@ -import { MongoHelper } from '../helpers/mongo-helper' -import { LogErrorRepository } from '@/data/protocols/db/log/log-error-repository' +import { MongoHelper } from '@/infra/db' +import { LogErrorRepository } from '@/data/protocols/db' export class LogMongoRepository implements LogErrorRepository { async logError (stack: string): Promise { diff --git a/src/infra/db/mongodb/helpers/mongo-helper.ts b/src/infra/db/mongodb/mongo-helper.ts similarity index 91% rename from src/infra/db/mongodb/helpers/mongo-helper.ts rename to src/infra/db/mongodb/mongo-helper.ts index f3ae6c2..206c588 100644 --- a/src/infra/db/mongodb/helpers/mongo-helper.ts +++ b/src/infra/db/mongodb/mongo-helper.ts @@ -1,4 +1,4 @@ -import { MongoClient, Collection } from 'mongodb' +import { MongoClient, type Collection } from 'mongodb' export const MongoHelper = { client: null as MongoClient, diff --git a/src/infra/db/mongodb/query-builder.ts b/src/infra/db/mongodb/query-builder.ts new file mode 100644 index 0000000..e89093e --- /dev/null +++ b/src/infra/db/mongodb/query-builder.ts @@ -0,0 +1,38 @@ +export class QueryBuilder { + private readonly query = [] + + private addStep (step: string, data: object): QueryBuilder { + this.query.push({ + [step]: data + }) + return this + } + + match (data: object): QueryBuilder { + return this.addStep('$match', data) + } + + group (data: object): QueryBuilder { + return this.addStep('$group', data) + } + + sort (data: object): QueryBuilder { + return this.addStep('$sort', data) + } + + unwind (data: object): QueryBuilder { + return this.addStep('$unwind', data) + } + + lookup (data: object): QueryBuilder { + return this.addStep('$lookup', data) + } + + project (data: object): QueryBuilder { + return this.addStep('$project', data) + } + + build (): object[] { + return this.query + } +} diff --git a/src/infra/db/mongodb/survey-mongo-repository.ts b/src/infra/db/mongodb/survey-mongo-repository.ts new file mode 100644 index 0000000..ce0f63a --- /dev/null +++ b/src/infra/db/mongodb/survey-mongo-repository.ts @@ -0,0 +1,77 @@ +import { MongoHelper, QueryBuilder } from '@/infra/db' +import { AddSurveyRepository, LoadSurveysRepository, LoadSurveyByIdRepository, CheckSurveyByIdRepository, LoadAnswersBySurveyRepository } from '@/data/protocols/db' + +import { ObjectId } from 'mongodb' + +export class SurveyMongoRepository implements AddSurveyRepository, LoadSurveysRepository, LoadSurveyByIdRepository, CheckSurveyByIdRepository, LoadAnswersBySurveyRepository { + async add (data: AddSurveyRepository.Params): Promise { + const surveyCollection = MongoHelper.getCollection('surveys') + await surveyCollection.insertOne(data) + } + + async loadAll (accountId: string): Promise { + const surveyCollection = MongoHelper.getCollection('surveys') + const query = new QueryBuilder() + .lookup({ + from: 'surveyResults', + foreignField: 'surveyId', + localField: '_id', + as: 'result' + }) + .project({ + _id: 1, + question: 1, + answers: 1, + date: 1, + didAnswer: { + $gte: [{ + $size: { + $filter: { + input: '$result', + as: 'item', + cond: { + $eq: ['$$item.accountId', new ObjectId(accountId)] + } + } + } + }, 1] + } + }) + .build() + const surveys = await surveyCollection.aggregate(query).toArray() + return MongoHelper.mapCollection(surveys) + } + + async loadById (id: string): Promise { + const surveyCollection = MongoHelper.getCollection('surveys') + const survey = await surveyCollection.findOne({ _id: new ObjectId(id) }) + return survey && MongoHelper.map(survey) + } + + async loadAnswers (id: string): Promise { + const surveyCollection = MongoHelper.getCollection('surveys') + const query = new QueryBuilder() + .match({ + _id: new ObjectId(id) + }) + .project({ + _id: 0, + answers: '$answers.answer' + }) + .build() + const surveys = await surveyCollection.aggregate(query).toArray() + return surveys[0]?.answers || [] + } + + async checkById (id: string): Promise { + const surveyCollection = MongoHelper.getCollection('surveys') + const survey = await surveyCollection.findOne({ + _id: new ObjectId(id) + }, { + projection: { + _id: 1 + } + }) + return survey !== null + } +} diff --git a/src/infra/db/mongodb/survey-result-mongo-repository.ts b/src/infra/db/mongodb/survey-result-mongo-repository.ts new file mode 100644 index 0000000..8eeea2a --- /dev/null +++ b/src/infra/db/mongodb/survey-result-mongo-repository.ts @@ -0,0 +1,201 @@ +import { MongoHelper, QueryBuilder } from '@/infra/db' +import { SaveSurveyResultRepository, LoadSurveyResultRepository } from '@/data/protocols/db' + +import { ObjectId } from 'mongodb' +import round from 'mongo-round' +import { SurveyResultModel } from '@/domain/models' + +export class SurveyResultMongoRepository implements SaveSurveyResultRepository, LoadSurveyResultRepository { + async save (data: SaveSurveyResultRepository.Params): Promise { + const surveyResultCollection = MongoHelper.getCollection('surveyResults') + await surveyResultCollection.findOneAndUpdate({ + surveyId: new ObjectId(data.surveyId), + accountId: new ObjectId(data.accountId) + }, { + $set: { + answer: data.answer, + date: data.date + } + }, { + upsert: true + }) + } + + async loadBySurveyId (surveyId: string, accountId: string): Promise { + const surveyResultCollection = MongoHelper.getCollection('surveyResults') + const query = new QueryBuilder() + .match({ + surveyId: new ObjectId(surveyId) + }) + .group({ + _id: 0, + data: { + $push: '$$ROOT' + }, + total: { + $sum: 1 + } + }) + .unwind({ + path: '$data' + }) + .lookup({ + from: 'surveys', + foreignField: '_id', + localField: 'data.surveyId', + as: 'survey' + }) + .unwind({ + path: '$survey' + }) + .group({ + _id: { + surveyId: '$survey._id', + question: '$survey.question', + date: '$survey.date', + total: '$total', + answer: '$data.answer', + answers: '$survey.answers' + }, + count: { + $sum: 1 + }, + currentAccountAnswer: { + $push: { + $cond: [{ $eq: ['$data.accountId', new ObjectId(accountId)] }, '$data.answer', '$invalid'] + } + } + }) + .project({ + _id: 0, + surveyId: '$_id.surveyId', + question: '$_id.question', + date: '$_id.date', + answers: { + $map: { + input: '$_id.answers', + as: 'item', + in: { + $mergeObjects: ['$$item', { + count: { + $cond: { + if: { + $eq: ['$$item.answer', '$_id.answer'] + }, + then: '$count', + else: 0 + } + }, + percent: { + $cond: { + if: { + $eq: ['$$item.answer', '$_id.answer'] + }, + then: { + $multiply: [{ + $divide: ['$count', '$_id.total'] + }, 100] + }, + else: 0 + } + }, + isCurrentAccountAnswerCount: { + $cond: [{ + $eq: ['$$item.answer', { + $arrayElemAt: ['$currentAccountAnswer', 0] + }] + }, 1, 0] + } + }] + } + } + } + }) + .group({ + _id: { + surveyId: '$surveyId', + question: '$question', + date: '$date' + }, + answers: { + $push: '$answers' + } + }) + .project({ + _id: 0, + surveyId: '$_id.surveyId', + question: '$_id.question', + date: '$_id.date', + answers: { + $reduce: { + input: '$answers', + initialValue: [], + in: { + $concatArrays: ['$$value', '$$this'] + } + } + } + }) + .unwind({ + path: '$answers' + }) + .group({ + _id: { + surveyId: '$surveyId', + question: '$question', + date: '$date', + answer: '$answers.answer', + image: '$answers.image' + }, + count: { + $sum: '$answers.count' + }, + percent: { + $sum: '$answers.percent' + }, + isCurrentAccountAnswerCount: { + $sum: '$answers.isCurrentAccountAnswerCount' + } + }) + .project({ + _id: 0, + surveyId: '$_id.surveyId', + question: '$_id.question', + date: '$_id.date', + answer: { + answer: '$_id.answer', + image: '$_id.image', + count: round('$count'), + percent: round('$percent'), + isCurrentAccountAnswer: { + $eq: ['$isCurrentAccountAnswerCount', 1] + } + } + }) + .sort({ + 'answer.count': -1 + }) + .group({ + _id: { + surveyId: '$surveyId', + question: '$question', + date: '$date' + }, + answers: { + $push: '$answer' + } + }) + .project({ + _id: 0, + surveyId: { + $toString: '$_id.surveyId' + }, + question: '$_id.question', + date: '$_id.date', + answers: '$answers' + }) + .build() + const surveyResult = await surveyResultCollection.aggregate(query).toArray() + return surveyResult.length ? surveyResult[0] : null + } +} diff --git a/src/infra/db/mongodb/survey-result/survey-result-mongo-repository.spec.ts b/src/infra/db/mongodb/survey-result/survey-result-mongo-repository.spec.ts deleted file mode 100644 index 9aceba3..0000000 --- a/src/infra/db/mongodb/survey-result/survey-result-mongo-repository.spec.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { SurveyResultMongoRepository } from './survey-result-mongo-repository' -import { MongoHelper } from '../helpers/mongo-helper' -import { SurveyModel } from '@/domain/models/survey' -import { Collection, ObjectId } from 'mongodb' - -let surveyCollection: Collection -let surveyResultCollection: Collection -let accountCollection: Collection - -const makeSut = (): SurveyResultMongoRepository => { - return new SurveyResultMongoRepository() -} - -const makeSurvey = async (): Promise => { - const res = await surveyCollection.insertOne({ - question: 'any_question', - answers: [{ - image: 'any_image', - answer: 'any_answer' - }, { - answer: 'other_answer' - }], - date: new Date() - }) - const survey = await surveyCollection.findOne({ _id: res.insertedId }) - return MongoHelper.map(survey) -} - -const makeAccountId = async (): Promise => { - const res = await accountCollection.insertOne(makeSurvey()) - return res.insertedId.toHexString() -} - -describe('Survey Mongo Repository', () => { - beforeAll(async () => { - await MongoHelper.connect(process.env.MONGO_URL) - }) - - afterAll(async () => { - await MongoHelper.disconnect() - }) - - beforeEach(async () => { - surveyCollection = MongoHelper.getCollection('surveys') - await surveyCollection.deleteMany({}) - surveyResultCollection = MongoHelper.getCollection('surveyResults') - await surveyResultCollection.deleteMany({}) - accountCollection = MongoHelper.getCollection('accounts') - await accountCollection.deleteMany({}) - }) - - describe('save()', () => { - test('Should add a survey result if its new', async () => { - const survey = await makeSurvey() - const accountId = await makeAccountId() - const sut = makeSut() - await sut.save({ - surveyId: survey.id, - accountId, - answer: survey.answers[0].answer, - date: new Date() - }) - const surveyResult = await surveyResultCollection.findOne({ - surveyId: new ObjectId(survey.id), - accountId: new ObjectId(accountId) - }) - expect(surveyResult).toBeTruthy() - }) - - test('Should update survey result if its not new', async () => { - const survey = await makeSurvey() - const accountId = await makeAccountId() - await surveyResultCollection.insertOne({ - surveyId: new ObjectId(survey.id), - accountId: new ObjectId(accountId), - answer: survey.answers[0].answer, - date: new Date() - }) - const sut = makeSut() - await sut.save({ - surveyId: survey.id, - accountId, - answer: survey.answers[1].answer, - date: new Date() - }) - const surveyResult = await surveyResultCollection - .find({ - surveyId: new ObjectId(survey.id), - accountId: new ObjectId(accountId) - }) - .toArray() - expect(surveyResult).toBeTruthy() - expect(surveyResult.length).toBe(1) - }) - }) -}) diff --git a/src/infra/db/mongodb/survey-result/survey-result-mongo-repository.ts b/src/infra/db/mongodb/survey-result/survey-result-mongo-repository.ts deleted file mode 100644 index a87427b..0000000 --- a/src/infra/db/mongodb/survey-result/survey-result-mongo-repository.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { MongoHelper } from '../helpers/mongo-helper' -import { SurveyResultModel } from '@/domain/models/survey-result' -import { SaveSurveyResultParams } from '@/domain/usecases/save-survey-result' -import { SaveSurveyResultRepository } from '@/data/protocols/db/survey-result/save-survey-result-repository' - -export class SurveyResultMongoRepository implements SaveSurveyResultRepository { - async save (data: SaveSurveyResultParams): Promise { - const surveyResultCollection = MongoHelper.getCollection('surveyResults') - const res = await surveyResultCollection.findOneAndUpdate({ - surveyId: data.surveyId, - accountId: data.accountId - }, { - $set: { - answer: data.answer, - date: data.date - } - }, { - upsert: true - }) - return MongoHelper.map(res.value) - } -} diff --git a/src/infra/db/mongodb/survey/survey-mongo-repository.spec.ts b/src/infra/db/mongodb/survey/survey-mongo-repository.spec.ts deleted file mode 100644 index 47a8eba..0000000 --- a/src/infra/db/mongodb/survey/survey-mongo-repository.spec.ts +++ /dev/null @@ -1,92 +0,0 @@ -import { SurveyMongoRepository } from './survey-mongo-repository' -import { MongoHelper } from '../helpers/mongo-helper' -import { Collection } from 'mongodb' - -let surveyCollection: Collection - -describe('Survey Mongo Repository', () => { - beforeAll(async () => { - await MongoHelper.connect(process.env.MONGO_URL) - }) - - afterAll(async () => { - await MongoHelper.disconnect() - }) - - beforeEach(async () => { - surveyCollection = MongoHelper.getCollection('surveys') - await surveyCollection.deleteMany({}) - }) - - const makeSut = (): SurveyMongoRepository => { - return new SurveyMongoRepository() - } - describe('add()', () => { - test('Should add a survey on success', async () => { - const sut = makeSut() - await sut.add({ - question: 'any_question', - answers: [{ - image: 'any_image', - answer: 'any_answer' - }, { - answer: 'other_answer' - }], - date: new Date() - }) - const survey = await surveyCollection.findOne({ question: 'any_question' }) - expect(survey).toBeTruthy() - }) - }) - - describe('loadAll()', () => { - test('Should load all survey on success', async () => { - await surveyCollection.insertMany([{ - question: 'any_question', - answers: [{ - image: 'any_image', - answer: 'any_answer' - }], - date: new Date() - }, { - question: 'other_question', - answers: [{ - image: 'other_image', - answer: 'other_answer' - }], - date: new Date() - }]) - const sut = makeSut() - const surveys = await sut.loadAll() - expect(surveys.length).toBe(2) - expect(surveys[0].id).toBeTruthy() - expect(surveys[0].question).toBe('any_question') - expect(surveys[1].question).toBe('other_question') - }) - - test('Should load empty list', async () => { - const sut = makeSut() - const surveys = await sut.loadAll() - expect(surveys.length).toBe(0) - }) - }) - - describe('loadById()', () => { - test('Should load survey by id on success', async () => { - const res = await surveyCollection.insertOne({ - question: 'any_question', - answers: [{ - image: 'any_image', - answer: 'any_answer' - }, { - answer: 'other_answer' - }], - date: new Date() - }) - const sut = makeSut() - const survey = await sut.loadById(res.insertedId.toHexString()) - expect(survey).toBeTruthy() - expect(survey.id).toBeTruthy() - }) - }) -}) diff --git a/src/infra/db/mongodb/survey/survey-mongo-repository.ts b/src/infra/db/mongodb/survey/survey-mongo-repository.ts deleted file mode 100644 index bd1fba6..0000000 --- a/src/infra/db/mongodb/survey/survey-mongo-repository.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { AddSurveyRepository } from '@/data/protocols/db/survey/add-survey-repository' -import { LoadSurveyByIdRepository } from '@/data/protocols/db/survey/load-survey-by-id-repository' -import { LoadSurveysRepository } from '@/data/protocols/db/survey/load-surveys-repository' -import { SurveyModel } from '@/domain/models/survey' -import { AddSurveyParams } from '@/domain/usecases/add-survey' -import { ObjectId } from 'mongodb' -import { MongoHelper } from '../helpers/mongo-helper' - -export class SurveyMongoRepository implements AddSurveyRepository, LoadSurveysRepository, LoadSurveyByIdRepository { - async add (surveyData: AddSurveyParams): Promise { - const surveyCollection = MongoHelper.getCollection('surveys') - await surveyCollection.insertOne(surveyData) - } - - async loadAll (): Promise { - const surveyCollection = MongoHelper.getCollection('surveys') - const surveys = await surveyCollection.find().toArray() - return MongoHelper.mapCollection(surveys) - } - - async loadById (id: string): Promise { - const surveyCollection = MongoHelper.getCollection('surveys') - const survey = await surveyCollection.findOne({ _id: new ObjectId(id) }) - return survey && MongoHelper.map(survey) - } -} diff --git a/src/infra/validators/email-validator-adapter.ts b/src/infra/validators/email-validator-adapter.ts index 1283e46..bbcd90b 100644 --- a/src/infra/validators/email-validator-adapter.ts +++ b/src/infra/validators/email-validator-adapter.ts @@ -1,4 +1,5 @@ -import { EmailValidator } from '@/validation/protocols/email-validator' +import { EmailValidator } from '@/validation/protocols' + import validator from 'validator' export class EmailValidatorAdapter implements EmailValidator { diff --git a/src/infra/validators/index.ts b/src/infra/validators/index.ts new file mode 100644 index 0000000..40606c0 --- /dev/null +++ b/src/infra/validators/index.ts @@ -0,0 +1 @@ +export * from './email-validator-adapter' diff --git a/src/main/adapters/apollo-server-resolver-adapter.ts b/src/main/adapters/apollo-server-resolver-adapter.ts new file mode 100644 index 0000000..89d90b6 --- /dev/null +++ b/src/main/adapters/apollo-server-resolver-adapter.ts @@ -0,0 +1,19 @@ +import { Controller } from '@/presentation/protocols' + +import { UserInputError, AuthenticationError, ForbiddenError, ApolloError } from 'apollo-server-express' + +export const adaptResolver = async (controller: Controller, args?: any, context?: any): Promise => { + const request = { + ...(args || {}), + accountId: context?.req?.accountId + } + const httpResponse = await controller.handle(request) + switch (httpResponse.statusCode) { + case 200: + case 204: return httpResponse.body + case 400: throw new UserInputError(httpResponse.body.message) + case 401: throw new AuthenticationError(httpResponse.body.message) + case 403: throw new ForbiddenError(httpResponse.body.message) + default: throw new ApolloError(httpResponse.body.message) + } +} diff --git a/src/main/adapters/express-middleware-adapter.ts b/src/main/adapters/express-middleware-adapter.ts index 03f370f..57447a6 100644 --- a/src/main/adapters/express-middleware-adapter.ts +++ b/src/main/adapters/express-middleware-adapter.ts @@ -1,12 +1,14 @@ -import { HttpRequest, Middleware } from '@/presentation/protocols' -import { NextFunction, Request, Response } from 'express' +import { Middleware } from '@/presentation/protocols' + +import { Request, Response, NextFunction } from 'express' export const adaptMiddleware = (middleware: Middleware) => { return async (req: Request, res: Response, next: NextFunction) => { - const httpRequest: HttpRequest = { - headers: req.headers + const request = { + accessToken: req.headers?.['x-access-token'], + ...(req.headers || {}) } - const httpResponse = await middleware.handle(httpRequest) + const httpResponse = await middleware.handle(request) if (httpResponse.statusCode === 200) { Object.assign(req, httpResponse.body) next() diff --git a/src/main/adapters/express-route-adapter.ts b/src/main/adapters/express-route-adapter.ts index b693fa0..52c9d58 100644 --- a/src/main/adapters/express-route-adapter.ts +++ b/src/main/adapters/express-route-adapter.ts @@ -1,14 +1,15 @@ -import { Controller, HttpRequest } from '@/presentation/protocols' +import { Controller } from '@/presentation/protocols' + import { Request, Response } from 'express' export const adaptRoute = (controller: Controller) => { return async (req: Request, res: Response) => { - const httpRequest: HttpRequest = { - body: req.body, - params: req.params, + const request = { + ...(req.body || {}), + ...(req.params || {}), accountId: req.accountId } - const httpResponse = await controller.handle(httpRequest) + const httpResponse = await controller.handle(request) if (httpResponse.statusCode >= 200 && httpResponse.statusCode <= 299) { res.status(httpResponse.statusCode).json(httpResponse.body) } else { diff --git a/src/main/adapters/index.ts b/src/main/adapters/index.ts new file mode 100644 index 0000000..4502029 --- /dev/null +++ b/src/main/adapters/index.ts @@ -0,0 +1,3 @@ +export * from './express-middleware-adapter' +export * from './express-route-adapter' +export * from './apollo-server-resolver-adapter' diff --git a/src/main/config/app.ts b/src/main/config/app.ts index 6105f4e..bbffa42 100644 --- a/src/main/config/app.ts +++ b/src/main/config/app.ts @@ -1,10 +1,19 @@ -import setupMiddlewares from './middlewares' -import setupRoutes from './routes' -import setupSwagger from './config-swagger' -import express from 'express' +import setupMiddlewares from '@/main/config/middlewares' +import setupRoutes from '@/main/config/routes' +import setupStaticFiles from '@/main/config/static-files' +import setupSwagger from '@/main/config/swagger' +import { setupApolloServer } from '@/main/graphql/apollo' -const app = express() -setupSwagger(app) -setupMiddlewares(app) -setupRoutes(app) -export default app +import express, { Express } from 'express' + +export const setupApp = async (): Promise => { + const app = express() + setupStaticFiles(app) + setupSwagger(app) + setupMiddlewares(app) + setupRoutes(app) + const server = setupApolloServer() + await server.start() + server.applyMiddleware({ app }) + return app +} diff --git a/src/main/config/env.ts b/src/main/config/env.ts index c25fc4d..f9b6e16 100644 --- a/src/main/config/env.ts +++ b/src/main/config/env.ts @@ -1,5 +1,5 @@ export default { mongoUrl: process.env.MONGO_URL || 'mongodb://localhost:27017/node-clean-api', port: process.env.PORT || 5050, - jwtSecret: process.env.JWT_SECRET || 'tj654=*5BM' + jwtSecret: process.env.JWT_SECRET || 'tj67O==5H' } diff --git a/src/main/config/middlewares.ts b/src/main/config/middlewares.ts index 04e4d4b..2f58d7e 100644 --- a/src/main/config/middlewares.ts +++ b/src/main/config/middlewares.ts @@ -1,5 +1,6 @@ +import { bodyParser, cors, contentType } from '@/main/middlewares' + import { Express } from 'express' -import { bodyParser, contentType, cors } from '../middlewares' export default (app: Express): void => { app.use(bodyParser) diff --git a/src/main/config/routes.ts b/src/main/config/routes.ts index c375923..c69a818 100644 --- a/src/main/config/routes.ts +++ b/src/main/config/routes.ts @@ -1,12 +1,12 @@ -/* eslint-disable n/no-path-concat */ import { Express, Router } from 'express' import { readdirSync } from 'fs' +import { join } from 'path' export default (app: Express): void => { const router = Router() app.use('/api', router) - readdirSync(`${__dirname}/../routes`).map(async file => { - if (!file.includes('.test.') && !file.endsWith('.map')) { + readdirSync(join(__dirname, '../routes')).map(async file => { + if (!file.endsWith('.map')) { (await import(`../routes/${file}`)).default(router) } }) diff --git a/src/main/config/static-files.ts b/src/main/config/static-files.ts new file mode 100644 index 0000000..89ac1ea --- /dev/null +++ b/src/main/config/static-files.ts @@ -0,0 +1,6 @@ +import express, { Express } from 'express' +import { resolve } from 'path' + +export default (app: Express): void => { + app.use('/static', express.static(resolve(__dirname, '../../static'))) +} diff --git a/src/main/config/config-swagger.ts b/src/main/config/swagger.ts similarity index 82% rename from src/main/config/config-swagger.ts rename to src/main/config/swagger.ts index cea1544..ce96d7e 100644 --- a/src/main/config/config-swagger.ts +++ b/src/main/config/swagger.ts @@ -1,5 +1,6 @@ import swaggerConfig from '@/main/docs' -import { noCache } from '../middlewares/no-cache' +import { noCache } from '@/main/middlewares' + import { serve, setup } from 'swagger-ui-express' import { Express } from 'express' diff --git a/src/main/decorators/index.ts b/src/main/decorators/index.ts new file mode 100644 index 0000000..0b2d5a1 --- /dev/null +++ b/src/main/decorators/index.ts @@ -0,0 +1 @@ +export * from './log-controller-decorator' diff --git a/src/main/decorators/log-controller-decorator.spec.ts b/src/main/decorators/log-controller-decorator.spec.ts deleted file mode 100644 index 2bd33b6..0000000 --- a/src/main/decorators/log-controller-decorator.spec.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { LogControllerDecorator } from './log-controller-decorator' -import { Controller, HttpRequest, HttpResponse } from '@/presentation/protocols' -import { ok, serverError } from '@/presentation/helpers/http/http-helper' -import { LogErrorRepository } from '@/data/protocols/db/log/log-error-repository' -import { mockAccountModel } from '@/domain/test' -import { mockLogErrorRepository } from '@/data/test' - -const makeController = (): Controller => { - class ControllerStub implements Controller { - async handle (httpRequest: HttpRequest): Promise { - return await Promise.resolve(ok(mockAccountModel())) - } - } - return new ControllerStub() -} - -const makeFakeRequest = (): HttpRequest => ({ - body: { - name: 'any_name', - email: 'any_email@example.com', - password: 'any_password', - passwordConfirmation: 'any_password' - } -}) - -const makeFakeServerError = (): HttpResponse => { - const fakeError = new Error() - fakeError.stack = 'any_stack' - return serverError(fakeError) -} - -type SutTypes = { - sut: LogControllerDecorator - controllerStub: Controller - logErrorRepositoryStub: LogErrorRepository -} - -const makeSut = (): SutTypes => { - const controllerStub = makeController() - const logErrorRepositoryStub = mockLogErrorRepository() - const sut = new LogControllerDecorator(controllerStub, logErrorRepositoryStub) - return { - sut, - controllerStub, - logErrorRepositoryStub - } -} - -describe('LogController Decorator', () => { - test('Should call controller handle', async () => { - const { sut, controllerStub } = makeSut() - const handleSpy = jest.spyOn(controllerStub, 'handle') - await sut.handle(makeFakeRequest()) - expect(handleSpy).toHaveBeenCalledWith(makeFakeRequest()) - }) - - test('Should return the same result of the controller', async () => { - const { sut } = makeSut() - const httpResponse = await sut.handle(makeFakeRequest()) - expect(httpResponse).toEqual(ok(mockAccountModel())) - }) - - test('Should call LogErrorRepository with correct error if controller returns a server error', async () => { - const { sut, controllerStub, logErrorRepositoryStub } = makeSut() - const logSpy = jest.spyOn(logErrorRepositoryStub, 'logError') - jest.spyOn(controllerStub, 'handle').mockReturnValueOnce(Promise.resolve(makeFakeServerError())) - await sut.handle(makeFakeRequest()) - expect(logSpy).toHaveBeenCalledWith('any_stack') - }) -}) diff --git a/src/main/decorators/log-controller-decorator.ts b/src/main/decorators/log-controller-decorator.ts index 7a44717..18f3243 100644 --- a/src/main/decorators/log-controller-decorator.ts +++ b/src/main/decorators/log-controller-decorator.ts @@ -1,5 +1,5 @@ -import { Controller, HttpRequest, HttpResponse } from '@/presentation/protocols' -import { LogErrorRepository } from '@/data/protocols/db/log/log-error-repository' +import { Controller, HttpResponse } from '@/presentation/protocols' +import { LogErrorRepository } from '@/data/protocols/db' export class LogControllerDecorator implements Controller { constructor ( @@ -7,8 +7,8 @@ export class LogControllerDecorator implements Controller { private readonly logErrorRepository: LogErrorRepository ) {} - async handle (httpRequest: HttpRequest): Promise { - const httpResponse = await this.controller.handle(httpRequest) + async handle (request: any): Promise { + const httpResponse = await this.controller.handle(request) if (httpResponse.statusCode === 500) { await this.logErrorRepository.logError(httpResponse.body.stack) } diff --git a/src/main/docs/index.ts b/src/main/docs/index.ts index 717695f..11afb7e 100644 --- a/src/main/docs/index.ts +++ b/src/main/docs/index.ts @@ -5,14 +5,23 @@ import schemas from './schemas' export default { openapi: '3.0.0', info: { - title: 'API Documentation Node Clean', - description: 'API de login e enquetes', + title: '4Dev - Enquetes para Programadores', + description: 'Essa é a documentação da API feita pelo instrutor Rodrigo Manguinho no curso da Udemy de NodeJs usando Typescript, TDD, Clean Architecture e seguindo os princípios do SOLID e Design Patterns.', version: '1.0.0', contact: { - name: 'Gilberto Mossmann', - url: 'https://www.linkedin.com/in/gilbertomossmann' + name: 'Rodrigo Manguinho', + email: 'rodrigo.manguinho@gmail.com', + url: 'https://www.linkedin.com/in/rmanguinho' + }, + license: { + name: 'GPL-3.0-or-later', + url: 'https://spdx.org/licenses/GPL-3.0-or-later.html' } }, + externalDocs: { + description: 'Link para o treinamento completo', + url: 'https://www.udemy.com/course/tdd-com-mango/?referralCode=B53CE5CA2B9AFA5A6FA1' + }, servers: [{ url: '/api', description: 'Servidor Principal' diff --git a/src/main/factories/controllers/add-survey-controller-factory.ts b/src/main/factories/controllers/add-survey-controller-factory.ts new file mode 100644 index 0000000..a8ddd93 --- /dev/null +++ b/src/main/factories/controllers/add-survey-controller-factory.ts @@ -0,0 +1,8 @@ +import { makeAddSurveyValidation, makeLogControllerDecorator, makeDbAddSurvey } from '@/main/factories' +import { Controller } from '@/presentation/protocols' +import { AddSurveyController } from '@/presentation/controllers' + +export const makeAddSurveyController = (): Controller => { + const controller = new AddSurveyController(makeAddSurveyValidation(), makeDbAddSurvey()) + return makeLogControllerDecorator(controller) +} diff --git a/src/main/factories/controllers/survey/add-survey/add-survey-validation-factory.ts b/src/main/factories/controllers/add-survey-validation-factory.ts similarity index 84% rename from src/main/factories/controllers/survey/add-survey/add-survey-validation-factory.ts rename to src/main/factories/controllers/add-survey-validation-factory.ts index a25a20d..2364b81 100644 --- a/src/main/factories/controllers/survey/add-survey/add-survey-validation-factory.ts +++ b/src/main/factories/controllers/add-survey-validation-factory.ts @@ -1,4 +1,4 @@ -import { RequiredFieldValidation, ValidationComposite } from '@/validation/validators' +import { ValidationComposite, RequiredFieldValidation } from '@/validation/validators' import { Validation } from '@/presentation/protocols' export const makeAddSurveyValidation = (): ValidationComposite => { diff --git a/src/main/factories/controllers/index.ts b/src/main/factories/controllers/index.ts new file mode 100644 index 0000000..f399565 --- /dev/null +++ b/src/main/factories/controllers/index.ts @@ -0,0 +1,9 @@ +export * from './add-survey-controller-factory' +export * from './add-survey-validation-factory' +export * from './load-survey-result-controller-factory' +export * from './load-surveys-controller-factory' +export * from './login-validation-factory' +export * from './login-controller-factory' +export * from './save-survey-result-controller-factory' +export * from './signup-controller-factory' +export * from './signup-validation-factory' diff --git a/src/main/factories/controllers/load-survey-result-controller-factory.ts b/src/main/factories/controllers/load-survey-result-controller-factory.ts new file mode 100644 index 0000000..8c84502 --- /dev/null +++ b/src/main/factories/controllers/load-survey-result-controller-factory.ts @@ -0,0 +1,8 @@ +import { makeLogControllerDecorator, makeDbCheckSurveyById, makeDbLoadSurveyResult } from '@/main/factories' +import { Controller } from '@/presentation/protocols' +import { LoadSurveyResultController } from '@/presentation/controllers' + +export const makeLoadSurveyResultController = (): Controller => { + const controller = new LoadSurveyResultController(makeDbCheckSurveyById(), makeDbLoadSurveyResult()) + return makeLogControllerDecorator(controller) +} diff --git a/src/main/factories/controllers/survey/load-surveys/load-survey-controller-factory.ts b/src/main/factories/controllers/load-surveys-controller-factory.ts similarity index 54% rename from src/main/factories/controllers/survey/load-surveys/load-survey-controller-factory.ts rename to src/main/factories/controllers/load-surveys-controller-factory.ts index 38d395c..1e93260 100644 --- a/src/main/factories/controllers/survey/load-surveys/load-survey-controller-factory.ts +++ b/src/main/factories/controllers/load-surveys-controller-factory.ts @@ -1,7 +1,6 @@ +import { makeLogControllerDecorator, makeDbLoadSurveys } from '@/main/factories' import { Controller } from '@/presentation/protocols' -import { makeLogControllerDecorator } from '@/main/factories/decorators/log-controller-decorator-factory' -import { makeDbLoadSurveys } from '@/main/factories/usecases/survey/load-surveys/db-load-surveys' -import { LoadSurveysController } from '@/presentation/controllers/survey/load-surveys/load-surveys-controller' +import { LoadSurveysController } from '@/presentation/controllers' export const makeLoadSurveysController = (): Controller => { const controller = new LoadSurveysController(makeDbLoadSurveys()) diff --git a/src/main/factories/controllers/login-controller-factory.ts b/src/main/factories/controllers/login-controller-factory.ts new file mode 100644 index 0000000..d7b6aa7 --- /dev/null +++ b/src/main/factories/controllers/login-controller-factory.ts @@ -0,0 +1,8 @@ +import { makeDbAuthentication, makeLoginValidation, makeLogControllerDecorator } from '@/main/factories' +import { Controller } from '@/presentation/protocols' +import { LoginController } from '@/presentation/controllers' + +export const makeLoginController = (): Controller => { + const controller = new LoginController(makeDbAuthentication(), makeLoginValidation()) + return makeLogControllerDecorator(controller) +} diff --git a/src/main/factories/controllers/login/login/login-validation-factory.ts b/src/main/factories/controllers/login-validation-factory.ts similarity index 57% rename from src/main/factories/controllers/login/login/login-validation-factory.ts rename to src/main/factories/controllers/login-validation-factory.ts index b81df57..490fe3a 100644 --- a/src/main/factories/controllers/login/login/login-validation-factory.ts +++ b/src/main/factories/controllers/login-validation-factory.ts @@ -1,6 +1,6 @@ -import { EmailValidation, RequiredFieldValidation, ValidationComposite } from '@/validation/validators' -import { Validation } from '@/presentation/protocols/validation' -import { EmailValidatorAdapter } from '@/infra/validators/email-validator-adapter' +import { ValidationComposite, RequiredFieldValidation, EmailValidation } from '@/validation/validators' +import { Validation } from '@/presentation/protocols' +import { EmailValidatorAdapter } from '@/infra/validators' export const makeLoginValidation = (): ValidationComposite => { const validations: Validation[] = [] diff --git a/src/main/factories/controllers/login/login/login-controller-factory.ts b/src/main/factories/controllers/login/login/login-controller-factory.ts deleted file mode 100644 index e76ea45..0000000 --- a/src/main/factories/controllers/login/login/login-controller-factory.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { makeLoginValidation } from './login-validation-factory' -import { Controller } from '@/presentation/protocols' -import { LoginController } from '@/presentation/controllers/login/login/login-controller' -import { makeDbAuthentication } from '@/main/factories/usecases/account/authentication/db-authentication-factory' -import { makeLogControllerDecorator } from '@/main/factories/decorators/log-controller-decorator-factory' - -export const makeLoginController = (): Controller => { - const controller = new LoginController(makeDbAuthentication(), makeLoginValidation()) - return makeLogControllerDecorator(controller) -} diff --git a/src/main/factories/controllers/login/login/login-validation-factory.spec.ts b/src/main/factories/controllers/login/login/login-validation-factory.spec.ts deleted file mode 100644 index 233b544..0000000 --- a/src/main/factories/controllers/login/login/login-validation-factory.spec.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { makeLoginValidation } from './login-validation-factory' -import { ValidationComposite, RequiredFieldValidation, EmailValidation } from '@/validation/validators' -import { EmailValidator } from '@/validation/protocols/email-validator' -import { Validation } from '@/presentation/protocols/validation' - -jest.mock('../../../../../validation/validators/validation-composite') - -const makeEmailValidator = (): EmailValidator => { - class EmailValidatorStub implements EmailValidator { - isValid (email: string): boolean { - return true - } - } - return new EmailValidatorStub() -} - -describe('SignUpValidation Factory', () => { - test('Should call ValidationComposite with all validations', () => { - makeLoginValidation() - const validations: Validation[] = [] - for (const field of ['email', 'password']) { - validations.push(new RequiredFieldValidation(field)) - } - validations.push(new EmailValidation('email', makeEmailValidator())) - expect(ValidationComposite).toHaveBeenCalledWith(validations) - }) -}) diff --git a/src/main/factories/controllers/login/signup/signup-controller-factory.ts b/src/main/factories/controllers/login/signup/signup-controller-factory.ts deleted file mode 100644 index 67233d5..0000000 --- a/src/main/factories/controllers/login/signup/signup-controller-factory.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { makeSignupValidation } from './signup-validation-factory' -import { Controller } from '@/presentation/protocols' -import { SignUpController } from '@/presentation/controllers/login/signup/signup-controller' -import { makeDbAuthentication } from '@/main/factories/usecases/account/authentication/db-authentication-factory' -import { makeDbAddAccount } from '@/main/factories/usecases/account/add-account/db-add-account-factory' -import { makeLogControllerDecorator } from '@/main/factories/decorators/log-controller-decorator-factory' - -export const makeSignupController = (): Controller => { - const controller = new SignUpController(makeDbAddAccount(), makeSignupValidation(), makeDbAuthentication()) - return makeLogControllerDecorator(controller) -} diff --git a/src/main/factories/controllers/save-survey-result-controller-factory.ts b/src/main/factories/controllers/save-survey-result-controller-factory.ts new file mode 100644 index 0000000..28370a3 --- /dev/null +++ b/src/main/factories/controllers/save-survey-result-controller-factory.ts @@ -0,0 +1,8 @@ +import { makeLogControllerDecorator, makeDbLoadAnswersBySurvey, makeDbSaveSurveyResult } from '@/main/factories' +import { Controller } from '@/presentation/protocols' +import { SaveSurveyResultController } from '@/presentation/controllers' + +export const makeSaveSurveyResultController = (): Controller => { + const controller = new SaveSurveyResultController(makeDbLoadAnswersBySurvey(), makeDbSaveSurveyResult()) + return makeLogControllerDecorator(controller) +} diff --git a/src/main/factories/controllers/signup-controller-factory.ts b/src/main/factories/controllers/signup-controller-factory.ts new file mode 100644 index 0000000..3c4270c --- /dev/null +++ b/src/main/factories/controllers/signup-controller-factory.ts @@ -0,0 +1,8 @@ +import { makeDbAuthentication, makeSignUpValidation, makeLogControllerDecorator, makeDbAddAccount } from '@/main/factories' +import { SignUpController } from '@/presentation/controllers' +import { Controller } from '@/presentation/protocols' + +export const makeSignUpController = (): Controller => { + const controller = new SignUpController(makeDbAddAccount(), makeSignUpValidation(), makeDbAuthentication()) + return makeLogControllerDecorator(controller) +} diff --git a/src/main/factories/controllers/login/signup/signup-validation-factory.ts b/src/main/factories/controllers/signup-validation-factory.ts similarity index 71% rename from src/main/factories/controllers/login/signup/signup-validation-factory.ts rename to src/main/factories/controllers/signup-validation-factory.ts index 74a9dbd..f3c82fa 100644 --- a/src/main/factories/controllers/login/signup/signup-validation-factory.ts +++ b/src/main/factories/controllers/signup-validation-factory.ts @@ -1,8 +1,8 @@ import { ValidationComposite, RequiredFieldValidation, CompareFieldsValidation, EmailValidation } from '@/validation/validators' -import { Validation } from '@/presentation/protocols/validation' -import { EmailValidatorAdapter } from '@/infra/validators/email-validator-adapter' +import { Validation } from '@/presentation/protocols' +import { EmailValidatorAdapter } from '@/infra/validators' -export const makeSignupValidation = (): ValidationComposite => { +export const makeSignUpValidation = (): ValidationComposite => { const validations: Validation[] = [] for (const field of ['name', 'email', 'password', 'passwordConfirmation']) { validations.push(new RequiredFieldValidation(field)) diff --git a/src/main/factories/controllers/survey-result/save-survey-result/save-survey-result-controller-factory.ts b/src/main/factories/controllers/survey-result/save-survey-result/save-survey-result-controller-factory.ts deleted file mode 100644 index 6ab70ad..0000000 --- a/src/main/factories/controllers/survey-result/save-survey-result/save-survey-result-controller-factory.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { makeLogControllerDecorator } from '@/main/factories/decorators/log-controller-decorator-factory' -import { makeDbSaveSurveyResult } from '@/main/factories/usecases/survey-result/save-survey-result/db-save-survey-result-factory' -import { makeDbLoadSurveyById } from '@/main/factories/usecases/survey/load-survey-by-id/db-load-survey-by-id-factory' -import { SaveSurveyResultController } from '@/presentation/controllers/survey-result/save-survey-result-controller' -import { Controller } from '@/presentation/protocols' - -export const makeSaveSurveyResultController = (): Controller => { - const controller = new SaveSurveyResultController(makeDbLoadSurveyById(), makeDbSaveSurveyResult()) - return makeLogControllerDecorator(controller) -} diff --git a/src/main/factories/controllers/survey/add-survey/add-survey-controller-factory.ts b/src/main/factories/controllers/survey/add-survey/add-survey-controller-factory.ts deleted file mode 100644 index 1b6816f..0000000 --- a/src/main/factories/controllers/survey/add-survey/add-survey-controller-factory.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { makeAddSurveyValidation } from './add-survey-validation-factory' -import { Controller } from '@/presentation/protocols' -import { AddSurveyController } from '@/presentation/controllers/survey/add-survey/add-survey-controller' -import { makeLogControllerDecorator } from '@/main/factories/decorators/log-controller-decorator-factory' -import { makeDbAddSurvey } from '@/main/factories/usecases/survey/add-survey/db-add-survey-factory' - -export const makeAddSurveyController = (): Controller => { - const controller = new AddSurveyController(makeAddSurveyValidation(), makeDbAddSurvey()) - return makeLogControllerDecorator(controller) -} diff --git a/src/main/factories/decorators/index.ts b/src/main/factories/decorators/index.ts new file mode 100644 index 0000000..7c04ba2 --- /dev/null +++ b/src/main/factories/decorators/index.ts @@ -0,0 +1 @@ +export * from './log-controller-decorator-factory' diff --git a/src/main/factories/decorators/log-controller-decorator-factory.ts b/src/main/factories/decorators/log-controller-decorator-factory.ts index c45e711..1c1210a 100644 --- a/src/main/factories/decorators/log-controller-decorator-factory.ts +++ b/src/main/factories/decorators/log-controller-decorator-factory.ts @@ -1,6 +1,6 @@ +import { LogControllerDecorator } from '@/main/decorators' +import { LogMongoRepository } from '@/infra/db' import { Controller } from '@/presentation/protocols' -import { LogControllerDecorator } from '@/main/decorators/log-controller-decorator' -import { LogMongoRepository } from '@/infra/db/mongodb/log/log-mongo-repository' export const makeLogControllerDecorator = (controller: Controller): Controller => { const logMongoRepository = new LogMongoRepository() diff --git a/src/main/factories/index.ts b/src/main/factories/index.ts new file mode 100644 index 0000000..17c68f0 --- /dev/null +++ b/src/main/factories/index.ts @@ -0,0 +1,4 @@ +export * from './controllers' +export * from './decorators' +export * from './middlewares' +export * from './usecases' diff --git a/src/main/factories/middlewares/auth-middleware-factory.ts b/src/main/factories/middlewares/auth-middleware-factory.ts new file mode 100644 index 0000000..c4b1349 --- /dev/null +++ b/src/main/factories/middlewares/auth-middleware-factory.ts @@ -0,0 +1,7 @@ +import { makeDbLoadAccountByToken } from '@/main/factories' +import { Middleware } from '@/presentation/protocols' +import { AuthMiddleware } from '@/presentation/middlewares' + +export const makeAuthMiddleware = (role?: string): Middleware => { + return new AuthMiddleware(makeDbLoadAccountByToken(), role) +} diff --git a/src/main/factories/middlewares/auth-middleware.factory.ts b/src/main/factories/middlewares/auth-middleware.factory.ts deleted file mode 100644 index 499c555..0000000 --- a/src/main/factories/middlewares/auth-middleware.factory.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { AuthMiddleware } from '@/presentation/middlewares/auth-middleware' -import { Middleware } from '@/presentation/protocols' -import { makeDbLoadAccountByToken } from '../usecases/account/load-account-by-token/db-load-account-by-token-factory' - -export const makeAuthMiddleware = (role?: string): Middleware => { - return new AuthMiddleware(makeDbLoadAccountByToken(), role) -} diff --git a/src/main/factories/middlewares/index.ts b/src/main/factories/middlewares/index.ts new file mode 100644 index 0000000..5a448a1 --- /dev/null +++ b/src/main/factories/middlewares/index.ts @@ -0,0 +1 @@ +export * from './auth-middleware-factory' diff --git a/src/main/factories/usecases/account/add-account/db-add-account-factory.ts b/src/main/factories/usecases/account/add-account/db-add-account-factory.ts deleted file mode 100644 index 9e2a8ad..0000000 --- a/src/main/factories/usecases/account/add-account/db-add-account-factory.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { DbAddAccount } from '@/data/usecases/add-account/db-add-account' -import { AccountMongoRepository } from '@/infra/db/mongodb/account/account-mongo-repository' -import { BcryptAdapter } from '@/infra/cryptography/bcrypt-adapter/bcrypt-adapter' -import { AddAccount } from '@/domain/usecases/add-account' - -export const makeDbAddAccount = (): AddAccount => { - const salt = 12 - const bcryptAdapter = new BcryptAdapter(salt) - const accountMongoRepository = new AccountMongoRepository() - return new DbAddAccount(bcryptAdapter, accountMongoRepository, accountMongoRepository) -} diff --git a/src/main/factories/usecases/account/authentication/db-authentication-factory.ts b/src/main/factories/usecases/account/authentication/db-authentication-factory.ts deleted file mode 100644 index 2155815..0000000 --- a/src/main/factories/usecases/account/authentication/db-authentication-factory.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { DbAuthentication } from '@/data/usecases/authentication/db-authentication' -import { Authentication } from '@/domain/usecases/authentication' -import { AccountMongoRepository } from '@/infra/db/mongodb/account/account-mongo-repository' -import { BcryptAdapter } from '@/infra/cryptography/bcrypt-adapter/bcrypt-adapter' -import { JwtAdapter } from '@/infra/cryptography/jwt-adapter/jwt-adapter' -import env from '@/main/config/env' - -export const makeDbAuthentication = (): Authentication => { - const salt = 12 - const bcryptAdapter = new BcryptAdapter(salt) - const jwtAdapter = new JwtAdapter(env.jwtSecret) - const accountMongoRepository = new AccountMongoRepository() - return new DbAuthentication(accountMongoRepository, bcryptAdapter, jwtAdapter, accountMongoRepository) -} diff --git a/src/main/factories/usecases/account/load-account-by-token/db-load-account-by-token-factory.ts b/src/main/factories/usecases/account/load-account-by-token/db-load-account-by-token-factory.ts deleted file mode 100644 index 0ddcb34..0000000 --- a/src/main/factories/usecases/account/load-account-by-token/db-load-account-by-token-factory.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { DbLoadAccountByToken } from '@/data/usecases/load-account-by-token/db-load-account-by-token' -import { LoadAccountByToken } from '@/domain/usecases/load-account-by-token' -import { JwtAdapter } from '@/infra/cryptography/jwt-adapter/jwt-adapter' -import { AccountMongoRepository } from '@/infra/db/mongodb/account/account-mongo-repository' -import env from '@/main/config/env' - -export const makeDbLoadAccountByToken = (): LoadAccountByToken => { - const jwtAdapter = new JwtAdapter(env.jwtSecret) - const accountMongoRepository = new AccountMongoRepository() - return new DbLoadAccountByToken(jwtAdapter, accountMongoRepository) -} diff --git a/src/main/factories/usecases/add-account-factory.ts b/src/main/factories/usecases/add-account-factory.ts new file mode 100644 index 0000000..f4823f9 --- /dev/null +++ b/src/main/factories/usecases/add-account-factory.ts @@ -0,0 +1,11 @@ +import { DbAddAccount } from '@/data/usecases' +import { AddAccount } from '@/domain/usecases' +import { AccountMongoRepository } from '@/infra/db' +import { BcryptAdapter } from '@/infra/cryptography' + +export const makeDbAddAccount = (): AddAccount => { + const salt = 12 + const bcryptAdapter = new BcryptAdapter(salt) + const accountMongoRepository = new AccountMongoRepository() + return new DbAddAccount(bcryptAdapter, accountMongoRepository, accountMongoRepository) +} diff --git a/src/main/factories/usecases/add-survey-factory.ts b/src/main/factories/usecases/add-survey-factory.ts new file mode 100644 index 0000000..ae54f45 --- /dev/null +++ b/src/main/factories/usecases/add-survey-factory.ts @@ -0,0 +1,8 @@ +import { AddSurvey } from '@/domain/usecases' +import { SurveyMongoRepository } from '@/infra/db' +import { DbAddSurvey } from '@/data/usecases' + +export const makeDbAddSurvey = (): AddSurvey => { + const surveyMongoRepository = new SurveyMongoRepository() + return new DbAddSurvey(surveyMongoRepository) +} diff --git a/src/main/factories/usecases/authentication-factory.ts b/src/main/factories/usecases/authentication-factory.ts new file mode 100644 index 0000000..9d5725e --- /dev/null +++ b/src/main/factories/usecases/authentication-factory.ts @@ -0,0 +1,13 @@ +import env from '@/main/config/env' +import { AccountMongoRepository } from '@/infra/db' +import { BcryptAdapter, JwtAdapter } from '@/infra/cryptography' +import { DbAuthentication } from '@/data/usecases' +import { Authentication } from '@/domain/usecases' + +export const makeDbAuthentication = (): Authentication => { + const salt = 12 + const bcryptAdapter = new BcryptAdapter(salt) + const jwtAdapter = new JwtAdapter(env.jwtSecret) + const accountMongoRepository = new AccountMongoRepository() + return new DbAuthentication(accountMongoRepository, bcryptAdapter, jwtAdapter, accountMongoRepository) +} diff --git a/src/main/factories/usecases/check-survey-by-id-factory.ts b/src/main/factories/usecases/check-survey-by-id-factory.ts new file mode 100644 index 0000000..198fd85 --- /dev/null +++ b/src/main/factories/usecases/check-survey-by-id-factory.ts @@ -0,0 +1,8 @@ +import { SurveyMongoRepository } from '@/infra/db' +import { CheckSurveyById } from '@/domain/usecases' +import { DbCheckSurveyById } from '@/data/usecases' + +export const makeDbCheckSurveyById = (): CheckSurveyById => { + const surveyMongoRepository = new SurveyMongoRepository() + return new DbCheckSurveyById(surveyMongoRepository) +} diff --git a/src/main/factories/usecases/index.ts b/src/main/factories/usecases/index.ts new file mode 100644 index 0000000..45653a4 --- /dev/null +++ b/src/main/factories/usecases/index.ts @@ -0,0 +1,9 @@ +export * from './add-account-factory' +export * from './load-account-by-token-factory' +export * from './authentication-factory' +export * from './add-survey-factory' +export * from './load-answers-by-survey-factory' +export * from './check-survey-by-id-factory' +export * from './load-surveys-factory' +export * from './load-survey-result-factory' +export * from './save-survey-result-factory' diff --git a/src/main/factories/usecases/load-account-by-token-factory.ts b/src/main/factories/usecases/load-account-by-token-factory.ts new file mode 100644 index 0000000..ae31871 --- /dev/null +++ b/src/main/factories/usecases/load-account-by-token-factory.ts @@ -0,0 +1,11 @@ +import env from '@/main/config/env' +import { LoadAccountByToken } from '@/domain/usecases' +import { DbLoadAccountByToken } from '@/data/usecases' +import { AccountMongoRepository } from '@/infra/db' +import { JwtAdapter } from '@/infra/cryptography' + +export const makeDbLoadAccountByToken = (): LoadAccountByToken => { + const jwtAdapter = new JwtAdapter(env.jwtSecret) + const accountMongoRepository = new AccountMongoRepository() + return new DbLoadAccountByToken(jwtAdapter, accountMongoRepository) +} diff --git a/src/main/factories/usecases/load-answers-by-survey-factory.ts b/src/main/factories/usecases/load-answers-by-survey-factory.ts new file mode 100644 index 0000000..fe2e701 --- /dev/null +++ b/src/main/factories/usecases/load-answers-by-survey-factory.ts @@ -0,0 +1,8 @@ +import { SurveyMongoRepository } from '@/infra/db' +import { LoadAnswersBySurvey } from '@/domain/usecases' +import { DbLoadAnswersBySurvey } from '@/data/usecases' + +export const makeDbLoadAnswersBySurvey = (): LoadAnswersBySurvey => { + const surveyMongoRepository = new SurveyMongoRepository() + return new DbLoadAnswersBySurvey(surveyMongoRepository) +} diff --git a/src/main/factories/usecases/load-survey-result-factory.ts b/src/main/factories/usecases/load-survey-result-factory.ts new file mode 100644 index 0000000..e5ee5cd --- /dev/null +++ b/src/main/factories/usecases/load-survey-result-factory.ts @@ -0,0 +1,9 @@ +import { LoadSurveyResult } from '@/domain/usecases' +import { DbLoadSurveyResult } from '@/data/usecases' +import { SurveyResultMongoRepository, SurveyMongoRepository } from '@/infra/db' + +export const makeDbLoadSurveyResult = (): LoadSurveyResult => { + const surveyResultMongoRepository = new SurveyResultMongoRepository() + const surveyMongoRepository = new SurveyMongoRepository() + return new DbLoadSurveyResult(surveyResultMongoRepository, surveyMongoRepository) +} diff --git a/src/main/factories/usecases/load-surveys-factory.ts b/src/main/factories/usecases/load-surveys-factory.ts new file mode 100644 index 0000000..13d73a7 --- /dev/null +++ b/src/main/factories/usecases/load-surveys-factory.ts @@ -0,0 +1,8 @@ +import { SurveyMongoRepository } from '@/infra/db' +import { LoadSurveys } from '@/domain/usecases' +import { DbLoadSurveys } from '@/data/usecases' + +export const makeDbLoadSurveys = (): LoadSurveys => { + const surveyMongoRepository = new SurveyMongoRepository() + return new DbLoadSurveys(surveyMongoRepository) +} diff --git a/src/main/factories/usecases/save-survey-result-factory.ts b/src/main/factories/usecases/save-survey-result-factory.ts new file mode 100644 index 0000000..1905bcd --- /dev/null +++ b/src/main/factories/usecases/save-survey-result-factory.ts @@ -0,0 +1,8 @@ +import { SaveSurveyResult } from '@/domain/usecases' +import { DbSaveSurveyResult } from '@/data/usecases' +import { SurveyResultMongoRepository } from '@/infra/db' + +export const makeDbSaveSurveyResult = (): SaveSurveyResult => { + const surveyResultMongoRepository = new SurveyResultMongoRepository() + return new DbSaveSurveyResult(surveyResultMongoRepository, surveyResultMongoRepository) +} diff --git a/src/main/factories/usecases/survey-result/save-survey-result/db-save-survey-result-factory.ts b/src/main/factories/usecases/survey-result/save-survey-result/db-save-survey-result-factory.ts deleted file mode 100644 index 9beda56..0000000 --- a/src/main/factories/usecases/survey-result/save-survey-result/db-save-survey-result-factory.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { DbSaveSurveyResult } from '@/data/usecases/save-survey-result/db-save-survey-result' -import { SaveSurveyResult } from '@/domain/usecases/save-survey-result' -import { SurveyResultMongoRepository } from '@/infra/db/mongodb/survey-result/survey-result-mongo-repository' - -export const makeDbSaveSurveyResult = (): SaveSurveyResult => { - const surveyResultMongoRepository = new SurveyResultMongoRepository() - return new DbSaveSurveyResult(surveyResultMongoRepository) -} diff --git a/src/main/factories/usecases/survey/add-survey/db-add-survey-factory.ts b/src/main/factories/usecases/survey/add-survey/db-add-survey-factory.ts deleted file mode 100644 index a57f511..0000000 --- a/src/main/factories/usecases/survey/add-survey/db-add-survey-factory.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { DbAddSurvey } from '@/data/usecases/add-survey/db-add-survey' -import { AddSurvey } from '@/domain/usecases/add-survey' -import { SurveyMongoRepository } from '@/infra/db/mongodb/survey/survey-mongo-repository' - -export const makeDbAddSurvey = (): AddSurvey => { - const surveyMongoRepository = new SurveyMongoRepository() - return new DbAddSurvey(surveyMongoRepository) -} diff --git a/src/main/factories/usecases/survey/load-survey-by-id/db-load-survey-by-id-factory.ts b/src/main/factories/usecases/survey/load-survey-by-id/db-load-survey-by-id-factory.ts deleted file mode 100644 index a8e71e4..0000000 --- a/src/main/factories/usecases/survey/load-survey-by-id/db-load-survey-by-id-factory.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { SurveyMongoRepository } from '@/infra/db/mongodb/survey/survey-mongo-repository' -import { LoadSurveyById } from '@/domain/usecases/load-survey-by-id' -import { DbLoadSurveyById } from '@/data/usecases/load-survey-by-id/db-load-survey-by-id' - -export const makeDbLoadSurveyById = (): LoadSurveyById => { - const surveyMongoRepository = new SurveyMongoRepository() - return new DbLoadSurveyById(surveyMongoRepository) -} diff --git a/src/main/factories/usecases/survey/load-surveys/db-load-surveys.ts b/src/main/factories/usecases/survey/load-surveys/db-load-surveys.ts deleted file mode 100644 index 7f8f8c8..0000000 --- a/src/main/factories/usecases/survey/load-surveys/db-load-surveys.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { DbLoadSurveys } from '@/data/usecases/load-surveys/db-load-surveys' -import { LoadSurveys } from '@/domain/usecases/load-surveys' -import { SurveyMongoRepository } from '@/infra/db/mongodb/survey/survey-mongo-repository' - -export const makeDbLoadSurveys = (): LoadSurveys => { - const surveyMongoRepository = new SurveyMongoRepository() - return new DbLoadSurveys(surveyMongoRepository) -} diff --git a/src/main/graphql/apollo/apollo-server.ts b/src/main/graphql/apollo/apollo-server.ts new file mode 100644 index 0000000..dcd76eb --- /dev/null +++ b/src/main/graphql/apollo/apollo-server.ts @@ -0,0 +1,39 @@ +import typeDefs from '@/main/graphql/type-defs' +import resolvers from '@/main/graphql/resolvers' +import { authDirectiveTransformer } from '@/main/graphql/directives' + +import { makeExecutableSchema } from '@graphql-tools/schema' +import { ApolloServer } from 'apollo-server-express' +import { GraphQLError } from 'graphql' + +const handleErrors = (response: any, errors: readonly GraphQLError[]): void => { + errors?.forEach(error => { + response.data = undefined + if (checkError(error, 'UserInputError')) { + response.http.status = 400 + } else if (checkError(error, 'AuthenticationError')) { + response.http.status = 401 + } else if (checkError(error, 'ForbiddenError')) { + response.http.status = 403 + } else { + response.http.status = 500 + } + }) +} + +const checkError = (error: GraphQLError, errorName: string): boolean => { + return [error.name, error.originalError?.name].some(name => name === errorName) +} + +let schema = makeExecutableSchema({ resolvers, typeDefs }) +schema = authDirectiveTransformer(schema) + +export const setupApolloServer = (): ApolloServer => new ApolloServer({ + schema, + context: ({ req }) => ({ req }), + plugins: [{ + requestDidStart: async () => ({ + willSendResponse: async ({ response, errors }) => { handleErrors(response, errors) } + }) + }] +}) diff --git a/src/main/graphql/apollo/index.ts b/src/main/graphql/apollo/index.ts new file mode 100644 index 0000000..5dd2aad --- /dev/null +++ b/src/main/graphql/apollo/index.ts @@ -0,0 +1 @@ +export * from './apollo-server' diff --git a/src/main/graphql/directives/auth-directive.ts b/src/main/graphql/directives/auth-directive.ts new file mode 100644 index 0000000..d8a1a3c --- /dev/null +++ b/src/main/graphql/directives/auth-directive.ts @@ -0,0 +1,29 @@ +import { makeAuthMiddleware } from '@/main/factories' + +import { getDirective, MapperKind, mapSchema } from '@graphql-tools/utils' +import { ForbiddenError } from 'apollo-server-express' +import { GraphQLSchema } from 'graphql' + +export const authDirectiveTransformer = (schema: GraphQLSchema): GraphQLSchema => { + return mapSchema(schema, { + [MapperKind.OBJECT_FIELD]: (fieldConfig) => { + const authDirective = getDirective(schema, fieldConfig, 'auth') + if (authDirective) { + const { resolve } = fieldConfig + fieldConfig.resolve = async (parent, args, context, info) => { + const request = { + accessToken: context?.req?.headers?.['x-access-token'] + } + const httpResponse = await makeAuthMiddleware().handle(request) + if (httpResponse.statusCode === 200) { + Object.assign(context?.req, httpResponse.body) + return resolve.call(this, parent, args, context, info) + } else { + throw new ForbiddenError(httpResponse.body.message) + } + } + } + return fieldConfig + } + }) +} diff --git a/src/main/graphql/directives/index.ts b/src/main/graphql/directives/index.ts new file mode 100644 index 0000000..aa41309 --- /dev/null +++ b/src/main/graphql/directives/index.ts @@ -0,0 +1 @@ +export * from './auth-directive' diff --git a/src/main/graphql/resolvers/base.ts b/src/main/graphql/resolvers/base.ts new file mode 100644 index 0000000..bc6a4ed --- /dev/null +++ b/src/main/graphql/resolvers/base.ts @@ -0,0 +1,5 @@ +import { GraphQLDateTime } from 'graphql-scalars' + +export default { + DateTime: GraphQLDateTime +} diff --git a/src/main/graphql/resolvers/index.ts b/src/main/graphql/resolvers/index.ts new file mode 100644 index 0000000..2b50e67 --- /dev/null +++ b/src/main/graphql/resolvers/index.ts @@ -0,0 +1,6 @@ +import base from './base' +import login from './login' +import survey from './survey' +import surveyResult from './survey-result' + +export default [base, login, survey, surveyResult] diff --git a/src/main/graphql/resolvers/login.ts b/src/main/graphql/resolvers/login.ts new file mode 100644 index 0000000..e0f52b2 --- /dev/null +++ b/src/main/graphql/resolvers/login.ts @@ -0,0 +1,12 @@ +import { adaptResolver } from '@/main/adapters' +import { makeLoginController, makeSignUpController } from '@/main/factories' + +export default { + Query: { + login: async (parent: any, args: any) => adaptResolver(makeLoginController(), args) + }, + + Mutation: { + signUp: async (parent: any, args: any) => adaptResolver(makeSignUpController(), args) + } +} diff --git a/src/main/graphql/resolvers/survey-result.ts b/src/main/graphql/resolvers/survey-result.ts new file mode 100644 index 0000000..b965314 --- /dev/null +++ b/src/main/graphql/resolvers/survey-result.ts @@ -0,0 +1,12 @@ +import { adaptResolver } from '@/main/adapters' +import { makeLoadSurveyResultController, makeSaveSurveyResultController } from '@/main/factories' + +export default { + Query: { + surveyResult: async (parent: any, args: any, context: any) => adaptResolver(makeLoadSurveyResultController(), args, context) + }, + + Mutation: { + saveSurveyResult: async (parent: any, args: any, context: any) => adaptResolver(makeSaveSurveyResultController(), args, context) + } +} diff --git a/src/main/graphql/resolvers/survey.ts b/src/main/graphql/resolvers/survey.ts new file mode 100644 index 0000000..3c318e5 --- /dev/null +++ b/src/main/graphql/resolvers/survey.ts @@ -0,0 +1,8 @@ +import { adaptResolver } from '@/main/adapters' +import { makeLoadSurveysController } from '@/main/factories' + +export default { + Query: { + surveys: async (parent: any, args: any, context: any) => adaptResolver(makeLoadSurveysController(), args, context) + } +} diff --git a/src/main/graphql/type-defs/base.ts b/src/main/graphql/type-defs/base.ts new file mode 100644 index 0000000..074c14a --- /dev/null +++ b/src/main/graphql/type-defs/base.ts @@ -0,0 +1,15 @@ +import { gql } from 'apollo-server-express' + +export default gql` + scalar DateTime + + directive @auth on FIELD_DEFINITION + + type Query { + _: String + } + + type Mutation { + _: String + } +` diff --git a/src/main/graphql/type-defs/index.ts b/src/main/graphql/type-defs/index.ts new file mode 100644 index 0000000..2b50e67 --- /dev/null +++ b/src/main/graphql/type-defs/index.ts @@ -0,0 +1,6 @@ +import base from './base' +import login from './login' +import survey from './survey' +import surveyResult from './survey-result' + +export default [base, login, survey, surveyResult] diff --git a/src/main/graphql/type-defs/login.ts b/src/main/graphql/type-defs/login.ts new file mode 100644 index 0000000..47aae1a --- /dev/null +++ b/src/main/graphql/type-defs/login.ts @@ -0,0 +1,16 @@ +import { gql } from 'apollo-server-express' + +export default gql` + extend type Query { + login (email: String!, password: String!): Account! + } + + extend type Mutation { + signUp (name: String!, email: String!, password: String!, passwordConfirmation: String!): Account! + } + + type Account { + accessToken: String! + name: String! + } +` diff --git a/src/main/graphql/type-defs/survey-result.ts b/src/main/graphql/type-defs/survey-result.ts new file mode 100644 index 0000000..78f9d94 --- /dev/null +++ b/src/main/graphql/type-defs/survey-result.ts @@ -0,0 +1,26 @@ +import { gql } from 'apollo-server-express' + +export default gql` + extend type Query { + surveyResult (surveyId: String!): SurveyResult! @auth + } + + extend type Mutation { + saveSurveyResult (surveyId: String!, answer: String!): SurveyResult! @auth + } + + type SurveyResult { + surveyId: String! + question: String! + answers: [Answer!]! + date: DateTime! + } + + type Answer { + image: String + answer: String! + count: Int! + percent: Int! + isCurrentAccountAnswer: Boolean! + } +` diff --git a/src/main/graphql/type-defs/survey.ts b/src/main/graphql/type-defs/survey.ts new file mode 100644 index 0000000..7904ed3 --- /dev/null +++ b/src/main/graphql/type-defs/survey.ts @@ -0,0 +1,20 @@ +import { gql } from 'apollo-server-express' + +export default gql` + extend type Query { + surveys: [Survey!]! @auth + } + + type Survey { + id: ID! + question: String! + answers: [SurveyAnswer!]! + date: DateTime! + didAnswer: Boolean + } + + type SurveyAnswer { + image: String + answer: String! + } +` diff --git a/src/main/middlewares/admin-auth.ts b/src/main/middlewares/admin-auth.ts index 363425a..afcf019 100644 --- a/src/main/middlewares/admin-auth.ts +++ b/src/main/middlewares/admin-auth.ts @@ -1,4 +1,4 @@ -import { adaptMiddleware } from '../adapters/express-middleware-adapter' -import { makeAuthMiddleware } from '../factories/middlewares/auth-middleware.factory' +import { adaptMiddleware } from '@/main/adapters' +import { makeAuthMiddleware } from '@/main/factories' export const adminAuth = adaptMiddleware(makeAuthMiddleware('admin')) diff --git a/src/main/middlewares/auth.ts b/src/main/middlewares/auth.ts index 19dbf10..8145dd5 100644 --- a/src/main/middlewares/auth.ts +++ b/src/main/middlewares/auth.ts @@ -1,4 +1,4 @@ -import { adaptMiddleware } from '../adapters/express-middleware-adapter' -import { makeAuthMiddleware } from '../factories/middlewares/auth-middleware.factory' +import { adaptMiddleware } from '@/main/adapters' +import { makeAuthMiddleware } from '@/main/factories' export const auth = adaptMiddleware(makeAuthMiddleware()) diff --git a/src/main/middlewares/cors.ts b/src/main/middlewares/cors.ts index 03666a9..f111ba5 100644 --- a/src/main/middlewares/cors.ts +++ b/src/main/middlewares/cors.ts @@ -2,7 +2,7 @@ import { Request, Response, NextFunction } from 'express' export const cors = (req: Request, res: Response, next: NextFunction): void => { res.set('access-control-allow-origin', '*') - res.set('access-control-allow-methods', '*') res.set('access-control-allow-headers', '*') + res.set('access-control-allow-methods', '*') next() } diff --git a/src/main/middlewares/index.ts b/src/main/middlewares/index.ts index 4bb3c02..6cec45a 100644 --- a/src/main/middlewares/index.ts +++ b/src/main/middlewares/index.ts @@ -1,5 +1,6 @@ export * from './body-parser' export * from './content-type' export * from './cors' -export * from './admin-auth' +export * from './no-cache' export * from './auth' +export * from './admin-auth' diff --git a/src/main/routes/login-routes.ts b/src/main/routes/login-routes.ts index 02a3aeb..a49011f 100644 --- a/src/main/routes/login-routes.ts +++ b/src/main/routes/login-routes.ts @@ -1,9 +1,9 @@ -import { adaptRoute } from '@/main/adapters/express-route-adapter' -import { makeLoginController } from '@/main/factories/controllers/login/login/login-controller-factory' -import { makeSignupController } from '@/main/factories/controllers/login/signup/signup-controller-factory' +import { adaptRoute } from '@/main/adapters' +import { makeSignUpController, makeLoginController } from '@/main/factories' + import { Router } from 'express' export default (router: Router): void => { - router.post('/signup', adaptRoute(makeSignupController())) + router.post('/signup', adaptRoute(makeSignUpController())) router.post('/login', adaptRoute(makeLoginController())) } diff --git a/src/main/routes/survey-result-routes.ts b/src/main/routes/survey-result-routes.ts index 23eb256..a5a81e0 100644 --- a/src/main/routes/survey-result-routes.ts +++ b/src/main/routes/survey-result-routes.ts @@ -1,8 +1,10 @@ -import { makeSaveSurveyResultController } from '../factories/controllers/survey-result/save-survey-result/save-survey-result-controller-factory' -import { adaptRoute } from '@/main/adapters/express-route-adapter' -import { auth } from '@/main/middlewares/auth' +import { makeSaveSurveyResultController, makeLoadSurveyResultController } from '@/main/factories' +import { adaptRoute } from '@/main/adapters' +import { auth } from '@/main/middlewares' + import { Router } from 'express' export default (router: Router): void => { router.put('/surveys/:surveyId/results', auth, adaptRoute(makeSaveSurveyResultController())) + router.get('/surveys/:surveyId/results', auth, adaptRoute(makeLoadSurveyResultController())) } diff --git a/src/main/routes/survey-routes.ts b/src/main/routes/survey-routes.ts index 085f33e..86dabdc 100644 --- a/src/main/routes/survey-routes.ts +++ b/src/main/routes/survey-routes.ts @@ -1,8 +1,8 @@ -import { adaptRoute } from '@/main/adapters/express-route-adapter' +import { adaptRoute } from '@/main/adapters' +import { makeAddSurveyController, makeLoadSurveysController } from '@/main/factories' +import { adminAuth, auth } from '@/main/middlewares' + import { Router } from 'express' -import { makeAddSurveyController } from '@/main/factories/controllers/survey/add-survey/add-survey-controller-factory' -import { makeLoadSurveysController } from '../factories/controllers/survey/load-surveys/load-survey-controller-factory' -import { adminAuth, auth } from '../middlewares' export default (router: Router): void => { router.post('/surveys', adminAuth, adaptRoute(makeAddSurveyController())) diff --git a/src/main/server.ts b/src/main/server.ts index 3142e64..4b6b4b2 100644 --- a/src/main/server.ts +++ b/src/main/server.ts @@ -1,10 +1,11 @@ import 'module-alias/register' -import { MongoHelper } from '@/infra/db/mongodb/helpers/mongo-helper' -import env from './config/env' +import env from '@/main/config/env' +import { MongoHelper } from '@/infra/db' MongoHelper.connect(env.mongoUrl) .then(async () => { - const app = (await import('./config/app')).default + const { setupApp } = await import('./config/app') + const app = await setupApp() app.listen(env.port, () => { console.log(`Server running at http://localhost:${env.port}`) }) }) .catch(console.error) diff --git a/src/presentation/controllers/add-survey-controller.ts b/src/presentation/controllers/add-survey-controller.ts new file mode 100644 index 0000000..6888903 --- /dev/null +++ b/src/presentation/controllers/add-survey-controller.ts @@ -0,0 +1,38 @@ +import { Controller, HttpResponse, Validation } from '@/presentation/protocols' +import { badRequest, serverError, noContent } from '@/presentation/helpers' +import { AddSurvey } from '@/domain/usecases' + +export class AddSurveyController implements Controller { + constructor ( + private readonly validation: Validation, + private readonly addSurvey: AddSurvey + ) {} + + async handle (request: AddSurveyController.Request): Promise { + try { + const error = this.validation.validate(request) + if (error) { + return badRequest(error) + } + await this.addSurvey.add({ + ...request, + date: new Date() + }) + return noContent() + } catch (error) { + return serverError(error) + } + } +} + +export namespace AddSurveyController { + export type Request = { + question: string + answers: Answer[] + } + + type Answer = { + image?: string + answer: string + } +} diff --git a/src/presentation/controllers/index.ts b/src/presentation/controllers/index.ts new file mode 100644 index 0000000..32ddf36 --- /dev/null +++ b/src/presentation/controllers/index.ts @@ -0,0 +1,6 @@ +export * from './add-survey-controller' +export * from './load-survey-result-controller' +export * from './load-surveys-controller' +export * from './login-controller' +export * from './save-survey-result-controller' +export * from './signup-controller' diff --git a/src/presentation/controllers/load-survey-result-controller.ts b/src/presentation/controllers/load-survey-result-controller.ts new file mode 100644 index 0000000..caaa00b --- /dev/null +++ b/src/presentation/controllers/load-survey-result-controller.ts @@ -0,0 +1,32 @@ +import { Controller, HttpResponse } from '@/presentation/protocols' +import { forbidden, serverError, ok } from '@/presentation/helpers' +import { InvalidParamError } from '@/presentation/errors' +import { CheckSurveyById, LoadSurveyResult } from '@/domain/usecases' + +export class LoadSurveyResultController implements Controller { + constructor ( + private readonly checkSurveyById: CheckSurveyById, + private readonly loadSurveyResult: LoadSurveyResult + ) {} + + async handle (request: LoadSurveyResultController.Request): Promise { + try { + const { surveyId, accountId } = request + const exists = await this.checkSurveyById.checkById(surveyId) + if (!exists) { + return forbidden(new InvalidParamError('surveyId')) + } + const surveyResult = await this.loadSurveyResult.load(surveyId, accountId) + return ok(surveyResult) + } catch (error) { + return serverError(error) + } + } +} + +export namespace LoadSurveyResultController { + export type Request = { + surveyId: string + accountId: string + } +} diff --git a/src/presentation/controllers/load-surveys-controller.ts b/src/presentation/controllers/load-surveys-controller.ts new file mode 100644 index 0000000..29e2c9d --- /dev/null +++ b/src/presentation/controllers/load-surveys-controller.ts @@ -0,0 +1,22 @@ +import { Controller, HttpResponse } from '@/presentation/protocols' +import { noContent, serverError, ok } from '@/presentation/helpers' +import { LoadSurveys } from '@/domain/usecases' + +export class LoadSurveysController implements Controller { + constructor (private readonly loadSurveys: LoadSurveys) {} + + async handle (request: LoadSurveysController.Request): Promise { + try { + const surveys = await this.loadSurveys.load(request.accountId) + return surveys.length ? ok(surveys) : noContent() + } catch (error) { + return serverError(error) + } + } +} + +export namespace LoadSurveysController { + export type Request = { + accountId: string + } +} diff --git a/src/presentation/controllers/login-controller.ts b/src/presentation/controllers/login-controller.ts new file mode 100644 index 0000000..7e63e93 --- /dev/null +++ b/src/presentation/controllers/login-controller.ts @@ -0,0 +1,33 @@ +import { Controller, HttpResponse, Validation } from '@/presentation/protocols' +import { badRequest, serverError, unauthorized, ok } from '@/presentation/helpers' +import { Authentication } from '@/domain/usecases' + +export class LoginController implements Controller { + constructor ( + private readonly authentication: Authentication, + private readonly validation: Validation + ) {} + + async handle (request: LoginController.Request): Promise { + try { + const error = this.validation.validate(request) + if (error) { + return badRequest(error) + } + const authenticationModel = await this.authentication.auth(request) + if (!authenticationModel) { + return unauthorized() + } + return ok(authenticationModel) + } catch (error) { + return serverError(error) + } + } +} + +export namespace LoginController { + export type Request = { + email: string + password: string + } +} diff --git a/src/presentation/controllers/login/login/login-controller-protocols.ts b/src/presentation/controllers/login/login/login-controller-protocols.ts deleted file mode 100644 index 3d64d65..0000000 --- a/src/presentation/controllers/login/login/login-controller-protocols.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from '@/presentation/protocols' -export * from '@/domain/usecases/authentication' diff --git a/src/presentation/controllers/login/login/login-controller.spec.ts b/src/presentation/controllers/login/login/login-controller.spec.ts deleted file mode 100644 index 9120572..0000000 --- a/src/presentation/controllers/login/login/login-controller.spec.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { LoginController } from './login-controller' -import { HttpRequest, Validation, Authentication } from './login-controller-protocols' -import { MissingParamError } from '@/presentation/errors' -import { badRequest, ok, serverError, unauthorized } from '@/presentation/helpers/http/http-helper' -import { mockAuthentication, mockValidation } from '@/presentation/test' -import { throwError } from '@/domain/test' - -const mockRequest = (): HttpRequest => ({ - body: { - email: 'any_email@example.com', - password: 'any_password' - } -}) - -type SutTypes = { - sut: LoginController - authenticationStub: Authentication - validationStub: Validation -} - -const makeSut = (): SutTypes => { - const authenticationStub = mockAuthentication() - const validationStub = mockValidation() - const sut = new LoginController(authenticationStub, validationStub) - return { - sut, - authenticationStub, - validationStub - } -} - -describe('Login Controller', () => { - test('Should call Authentication with correct values', async () => { - const { sut, authenticationStub } = makeSut() - const authSpy = jest.spyOn(authenticationStub, 'auth') - await sut.handle(mockRequest()) - expect(authSpy).toHaveBeenLastCalledWith({ email: 'any_email@example.com', password: 'any_password' }) - }) - - test('Should return 401 if invalid credentials are provided', async () => { - const { sut, authenticationStub } = makeSut() - jest.spyOn(authenticationStub, 'auth').mockReturnValueOnce(Promise.resolve(null)) - const httpResponse = await sut.handle(mockRequest()) - expect(httpResponse).toEqual(unauthorized()) - }) - - test('Should return 500 if Authentication throws', async () => { - const { sut, authenticationStub } = makeSut() - jest.spyOn(authenticationStub, 'auth').mockImplementationOnce(throwError) - const httpResponse = await sut.handle(mockRequest()) - expect(httpResponse).toEqual(serverError(new Error())) - }) - - test('Should return 200 if valid credentials are provided', async () => { - const { sut } = makeSut() - const httpResponse = await sut.handle(mockRequest()) - expect(httpResponse).toEqual(ok({ accessToken: 'any_token' })) - }) - - test('Should call Validation with correct values', async () => { - const { sut, validationStub } = makeSut() - const validateSpy = jest.spyOn(validationStub, 'validate') - const httpRequest = mockRequest() - await sut.handle(httpRequest) - expect(validateSpy).toHaveBeenCalledWith(httpRequest.body) - }) - - test('Should return 400 if Validation returns an error', async () => { - const { sut, validationStub } = makeSut() - jest.spyOn(validationStub, 'validate').mockReturnValueOnce(new MissingParamError('any_field')) - const httpResponse = await sut.handle(mockRequest()) - expect(httpResponse).toEqual(badRequest(new MissingParamError('any_field'))) - }) -}) diff --git a/src/presentation/controllers/login/login/login-controller.ts b/src/presentation/controllers/login/login/login-controller.ts deleted file mode 100644 index 9f98839..0000000 --- a/src/presentation/controllers/login/login/login-controller.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Controller, HttpRequest, HttpResponse, Authentication, Validation } from './login-controller-protocols' -import { badRequest, ok, serverError, unauthorized } from '@/presentation/helpers/http/http-helper' - -export class LoginController implements Controller { - constructor ( - private readonly authentication: Authentication, - private readonly validation: Validation - ) {} - - async handle (httpRequest: HttpRequest): Promise { - try { - const error = this.validation.validate(httpRequest.body) - if (error) { - return badRequest(error) - } - const { email, password } = httpRequest.body - const accessToken = await this.authentication.auth({ email, password }) - if (!accessToken) { - return unauthorized() - } - return ok({ accessToken }) - } catch (error) { - return serverError(error) - } - } -} diff --git a/src/presentation/controllers/login/signup/signup-controller-protocols.ts b/src/presentation/controllers/login/signup/signup-controller-protocols.ts deleted file mode 100644 index d4fc2a5..0000000 --- a/src/presentation/controllers/login/signup/signup-controller-protocols.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from '@/presentation/protocols' -export * from '@/domain/usecases/add-account' -export * from '@/domain/usecases/authentication' -export * from '@/domain/models/account' diff --git a/src/presentation/controllers/login/signup/signup-controller.spec.ts b/src/presentation/controllers/login/signup/signup-controller.spec.ts deleted file mode 100644 index aca79ec..0000000 --- a/src/presentation/controllers/login/signup/signup-controller.spec.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { SignUpController } from './signup-controller' -import { Validation, AddAccount, Authentication } from './signup-controller-protocols' -import { EmailInUseError, MissingParamError, ServerError } from '@/presentation/errors' -import { HttpRequest } from '@/presentation/protocols' -import { badRequest, ok, serverError, forbidden } from '@/presentation/helpers/http/http-helper' -import { mockAddAccount, mockAuthentication, mockValidation } from '@/presentation/test' -import { throwError } from '@/domain/test' - -const makeFakeRequest = (): HttpRequest => ({ - body: { - name: 'any_name', - email: 'any_email@example.com', - password: 'any_password', - passwordConfirmation: 'any_password' - } -}) - -type SutTypes = { - sut: SignUpController - addAccountStub: AddAccount - validationStub: Validation - authenticationStub: Authentication -} - -const makeSut = (): SutTypes => { - const authenticationStub = mockAuthentication() - const addAccountStub = mockAddAccount() - const validationStub = mockValidation() - const sut = new SignUpController(addAccountStub, validationStub, authenticationStub) - return { - sut, - addAccountStub, - validationStub, - authenticationStub - } -} - -describe('SignUp Controller', () => { - test('Should return 500 if AddAccount throws', async () => { - const { sut, addAccountStub } = makeSut() - jest.spyOn(addAccountStub, 'add').mockImplementationOnce(async () => { - return await Promise.reject(new Error()) - }) - const httpResponse = await sut.handle(makeFakeRequest()) - expect(httpResponse).toEqual(serverError(new ServerError(null))) - }) - - test('Should call AddAccount with correct values', async () => { - const { sut, addAccountStub } = makeSut() - const addSpy = jest.spyOn(addAccountStub, 'add') - await sut.handle(makeFakeRequest()) - expect(addSpy).toHaveBeenCalledWith({ - name: 'any_name', - email: 'any_email@example.com', - password: 'any_password' - }) - }) - - test('Should return 403 if AddAccount returns null', async () => { - const { sut, addAccountStub } = makeSut() - jest.spyOn(addAccountStub, 'add').mockReturnValueOnce(Promise.resolve(null)) - const httpResponse = await sut.handle(makeFakeRequest()) - expect(httpResponse).toEqual(forbidden(new EmailInUseError())) - }) - - test('Should return 200 if valid data is provided', async () => { - const { sut } = makeSut() - const httpResponse = await sut.handle(makeFakeRequest()) - expect(httpResponse).toEqual(ok({ accessToken: 'any_token' })) - }) - - test('Should call Validation with correct values', async () => { - const { sut, validationStub } = makeSut() - const validateSpy = jest.spyOn(validationStub, 'validate') - const httpRequest = makeFakeRequest() - await sut.handle(httpRequest) - expect(validateSpy).toHaveBeenCalledWith(httpRequest.body) - }) - - test('Should return 400 if Validation returns an error', async () => { - const { sut, validationStub } = makeSut() - jest.spyOn(validationStub, 'validate').mockReturnValueOnce(new MissingParamError('any_field')) - const httpResponse = await sut.handle(makeFakeRequest()) - expect(httpResponse).toEqual(badRequest(new MissingParamError('any_field'))) - }) - - test('Should call Authentication with correct values', async () => { - const { sut, authenticationStub } = makeSut() - const authSpy = jest.spyOn(authenticationStub, 'auth') - await sut.handle(makeFakeRequest()) - expect(authSpy).toHaveBeenLastCalledWith({ email: 'any_email@example.com', password: 'any_password' }) - }) - - test('Should return 500 if Authentication throws', async () => { - const { sut, authenticationStub } = makeSut() - jest.spyOn(authenticationStub, 'auth').mockImplementationOnce(throwError) - const httpResponse = await sut.handle(makeFakeRequest()) - expect(httpResponse).toEqual(serverError(new Error())) - }) -}) diff --git a/src/presentation/controllers/login/signup/signup-controller.ts b/src/presentation/controllers/login/signup/signup-controller.ts deleted file mode 100644 index 95e0812..0000000 --- a/src/presentation/controllers/login/signup/signup-controller.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { AddAccount, Controller, HttpRequest, HttpResponse, Authentication } from './signup-controller-protocols' -import { badRequest, forbidden, ok, serverError } from '@/presentation/helpers/http/http-helper' -import { Validation } from '@/presentation/protocols/validation' -import { EmailInUseError } from '@/presentation/errors' - -export class SignUpController implements Controller { - constructor ( - private readonly addAccount: AddAccount, - private readonly validation: Validation, - private readonly authentication: Authentication - ) {} - - async handle (httpRequest: HttpRequest): Promise { - try { - const error = this.validation.validate(httpRequest.body) - if (error) { - return badRequest(error) - } - const { name, email, password } = httpRequest.body - const account = await this.addAccount.add({ - name, - email, - password - }) - if (!account) { - return forbidden(new EmailInUseError()) - } - const accessToken = await this.authentication.auth({ - email, - password - }) - return ok({ accessToken }) - } catch (error) { - return serverError(error) - } - } -} diff --git a/src/presentation/controllers/save-survey-result-controller.ts b/src/presentation/controllers/save-survey-result-controller.ts new file mode 100644 index 0000000..c01ea0f --- /dev/null +++ b/src/presentation/controllers/save-survey-result-controller.ts @@ -0,0 +1,38 @@ +import { Controller, HttpResponse } from '@/presentation/protocols' +import { forbidden, serverError, ok } from '@/presentation/helpers' +import { InvalidParamError } from '@/presentation/errors' +import { LoadAnswersBySurvey, SaveSurveyResult } from '@/domain/usecases' + +export class SaveSurveyResultController implements Controller { + constructor ( + private readonly loadAnswersBySurvey: LoadAnswersBySurvey, + private readonly saveSurveyResult: SaveSurveyResult + ) {} + + async handle (request: SaveSurveyResultController.Request): Promise { + try { + const { surveyId, answer } = request + const answers = await this.loadAnswersBySurvey.loadAnswers(surveyId) + if (!answers.length) { + return forbidden(new InvalidParamError('surveyId')) + } else if (!answers.includes(answer)) { + return forbidden(new InvalidParamError('answer')) + } + const surveyResult = await this.saveSurveyResult.save({ + ...request, + date: new Date() + }) + return ok(surveyResult) + } catch (error) { + return serverError(error) + } + } +} + +export namespace SaveSurveyResultController { + export type Request = { + surveyId: string + answer: string + accountId: string + } +} diff --git a/src/presentation/controllers/signup-controller.ts b/src/presentation/controllers/signup-controller.ts new file mode 100644 index 0000000..e47da2c --- /dev/null +++ b/src/presentation/controllers/signup-controller.ts @@ -0,0 +1,46 @@ +import { Controller, HttpResponse, Validation } from '@/presentation/protocols' +import { badRequest, serverError, ok, forbidden } from '@/presentation/helpers' +import { EmailInUseError } from '@/presentation/errors' +import { AddAccount, Authentication } from '@/domain/usecases' + +export class SignUpController implements Controller { + constructor ( + private readonly addAccount: AddAccount, + private readonly validation: Validation, + private readonly authentication: Authentication + ) {} + + async handle (request: SignUpController.Request): Promise { + try { + const error = this.validation.validate(request) + if (error) { + return badRequest(error) + } + const { name, email, password } = request + const isValid = await this.addAccount.add({ + name, + email, + password + }) + if (!isValid) { + return forbidden(new EmailInUseError()) + } + const authenticationModel = await this.authentication.auth({ + email, + password + }) + return ok(authenticationModel) + } catch (error) { + return serverError(error) + } + } +} + +export namespace SignUpController { + export type Request = { + name: string + email: string + password: string + passwordConfirmation: string + } +} diff --git a/src/presentation/controllers/survey-result/save-survey-result-controller-protocols.ts b/src/presentation/controllers/survey-result/save-survey-result-controller-protocols.ts deleted file mode 100644 index a09e3be..0000000 --- a/src/presentation/controllers/survey-result/save-survey-result-controller-protocols.ts +++ /dev/null @@ -1,5 +0,0 @@ -export * from '@/presentation/protocols' -export * from '@/domain/usecases/load-survey-by-id' -export * from '@/domain/usecases/save-survey-result' -export * from '@/domain/models/survey' -export * from '@/domain/models/survey-result' diff --git a/src/presentation/controllers/survey-result/save-survey-result-controller.spec.ts b/src/presentation/controllers/survey-result/save-survey-result-controller.spec.ts deleted file mode 100644 index 815394e..0000000 --- a/src/presentation/controllers/survey-result/save-survey-result-controller.spec.ts +++ /dev/null @@ -1,103 +0,0 @@ -import { SaveSurveyResultController } from './save-survey-result-controller' -import { HttpRequest, LoadSurveyById, SaveSurveyResult } from './save-survey-result-controller-protocols' -import { InvalidParamError } from '@/presentation/errors' -import { forbidden, ok, serverError } from '@/presentation/helpers/http/http-helper' -import { mockLoadSurveyById, mockSaveSurveyResult } from '@/presentation/test' -import { mockSurveyResultModel, throwError } from '@/domain/test' -import MockDate from 'mockdate' - -const makeFakeRequest = (): HttpRequest => ({ - params: { - surveyId: 'any_survey_id' - }, - body: { - answer: 'any_answer' - }, - accountId: 'any_account_id' -}) - -type SutTypes = { - sut: SaveSurveyResultController - loadSurveyByIdStub: LoadSurveyById - saveSurveyResultStub: SaveSurveyResult -} - -const makeSut = (): SutTypes => { - const loadSurveyByIdStub = mockLoadSurveyById() - const saveSurveyResultStub = mockSaveSurveyResult() - const sut = new SaveSurveyResultController(loadSurveyByIdStub, saveSurveyResultStub) - return { - sut, - loadSurveyByIdStub, - saveSurveyResultStub - } -} - -describe('SaveSurveyResultController', () => { - beforeAll(() => { - MockDate.set(new Date()) - }) - - afterAll(() => { - MockDate.reset() - }) - - test('Should call LoadSurveyById with correct values', async () => { - const { sut, loadSurveyByIdStub } = makeSut() - const loadByIdSpy = jest.spyOn(loadSurveyByIdStub, 'loadById') - await sut.handle(makeFakeRequest()) - expect(loadByIdSpy).toHaveBeenCalledWith('any_survey_id') - }) - - test('Should return 403 if LoadSurveyById returns null', async () => { - const { sut, loadSurveyByIdStub } = makeSut() - jest.spyOn(loadSurveyByIdStub, 'loadById').mockReturnValueOnce(Promise.resolve(null)) - const httpResponse = await sut.handle(makeFakeRequest()) - expect(httpResponse).toEqual(forbidden(new InvalidParamError('surveyId'))) - }) - - test('Should return 500 if LoadSurveyById throws', async () => { - const { sut, loadSurveyByIdStub } = makeSut() - jest.spyOn(loadSurveyByIdStub, 'loadById').mockImplementationOnce(throwError) - const httpResponse = await sut.handle(makeFakeRequest()) - expect(httpResponse).toEqual(serverError(new Error())) - }) - - test('Should return 403 if an invalid answer is provided', async () => { - const { sut } = makeSut() - const httpResponse = await sut.handle({ - params: { - surveyId: 'any_survey_id' - }, - body: { - answer: 'wrong_answer' - } - }) - expect(httpResponse).toEqual(forbidden(new InvalidParamError('answer'))) - }) - - test('Should call SaveSurveyResult with correct values', async () => { - const { sut, saveSurveyResultStub } = makeSut() - const saveSpy = jest.spyOn(saveSurveyResultStub, 'save') - await sut.handle(makeFakeRequest()) - expect(saveSpy).toHaveBeenCalledWith({ - surveyId: 'any_survey_id', - accountId: 'any_account_id', - date: new Date(), - answer: 'any_answer' - }) - }) - - test('Should return 500 if SaveSurveyResult throws', async () => { - const { sut, saveSurveyResultStub } = makeSut() - jest.spyOn(saveSurveyResultStub, 'save').mockImplementationOnce(throwError) - const httpResponse = await sut.handle(makeFakeRequest()) - expect(httpResponse).toEqual(serverError(new Error())) - }) - - test('Should return 200 on success', async () => { - const { sut } = makeSut() - const httpResponse = await sut.handle(makeFakeRequest()) - expect(httpResponse).toEqual(ok(mockSurveyResultModel())) - }) -}) diff --git a/src/presentation/controllers/survey-result/save-survey-result-controller.ts b/src/presentation/controllers/survey-result/save-survey-result-controller.ts deleted file mode 100644 index a6ae0ed..0000000 --- a/src/presentation/controllers/survey-result/save-survey-result-controller.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Controller, HttpRequest, HttpResponse, LoadSurveyById, SaveSurveyResult } from './save-survey-result-controller-protocols' -import { InvalidParamError } from '@/presentation/errors' -import { forbidden, ok, serverError } from '@/presentation/helpers/http/http-helper' - -export class SaveSurveyResultController implements Controller { - constructor ( - private readonly loadSurveyById: LoadSurveyById, - private readonly saveSurveyResult: SaveSurveyResult - ) {} - - async handle (httpRequest: HttpRequest): Promise { - try { - const { surveyId } = httpRequest.params - const { answer } = httpRequest.body - const { accountId } = httpRequest - const survey = await this.loadSurveyById.loadById(surveyId) - if (survey) { - const answers = survey.answers.map(a => a.answer) - if (!answers.includes(answer)) { - return forbidden(new InvalidParamError('answer')) - } - } else { - return forbidden(new InvalidParamError('surveyId')) - } - const surveyResult = await this.saveSurveyResult.save({ - accountId, - surveyId, - answer, - date: new Date() - }) - return ok(surveyResult) - } catch (error) { - return serverError(error) - } - } -} diff --git a/src/presentation/controllers/survey/add-survey/add-survey-controller-protocols.ts b/src/presentation/controllers/survey/add-survey/add-survey-controller-protocols.ts deleted file mode 100644 index e187bea..0000000 --- a/src/presentation/controllers/survey/add-survey/add-survey-controller-protocols.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from '@/presentation/protocols' -export * from '@/domain/usecases/add-survey' diff --git a/src/presentation/controllers/survey/add-survey/add-survey-controller.spec.ts b/src/presentation/controllers/survey/add-survey/add-survey-controller.spec.ts deleted file mode 100644 index 7699858..0000000 --- a/src/presentation/controllers/survey/add-survey/add-survey-controller.spec.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { AddSurvey, HttpRequest, Validation } from './add-survey-controller-protocols' -import { AddSurveyController } from './add-survey-controller' -import { mockAddSurvey, mockValidation } from '@/presentation/test' -import { badRequest, noContent, serverError } from '@/presentation/helpers/http/http-helper' -import { throwError } from '@/domain/test' -import MockDate from 'mockdate' - -const makeFakeRequest = (): HttpRequest => ({ - body: { - question: 'any_question', - answers: [{ - image: 'any_image', - answer: 'any_answer' - }], - date: new Date() - } -}) - -type SutTypes = { - sut: AddSurveyController - validationStub: Validation - addSurveyStub: AddSurvey -} - -const makeSut = (): SutTypes => { - const validationStub = mockValidation() - const addSurveyStub = mockAddSurvey() - const sut = new AddSurveyController(validationStub, addSurveyStub) - return { - sut, - validationStub, - addSurveyStub - } -} - -describe('AddSurvey Controller', () => { - beforeAll(() => { - MockDate.set(new Date()) - }) - - afterAll(() => { - MockDate.reset() - }) - - test('Should call Validation with correct values', async () => { - const { sut, validationStub } = makeSut() - const validateSpy = jest.spyOn(validationStub, 'validate') - const httpRequest = makeFakeRequest() - await sut.handle(httpRequest) - expect(validateSpy).toHaveBeenCalledWith(httpRequest.body) - }) - - test('Should return 400 if Validation fails', async () => { - const { sut, validationStub } = makeSut() - jest.spyOn(validationStub, 'validate').mockReturnValueOnce(new Error()) - const httpResponse = await sut.handle(makeFakeRequest()) - expect(httpResponse).toEqual(badRequest(new Error())) - }) - - test('Should call AddSurvey with correct values', async () => { - const { sut, addSurveyStub } = makeSut() - const addSpy = jest.spyOn(addSurveyStub, 'add') - const httpRequest = makeFakeRequest() - await sut.handle(httpRequest) - expect(addSpy).toHaveBeenCalledWith(httpRequest.body) - }) - - test('Should return 500 if AddSurvey throws', async () => { - const { sut, addSurveyStub } = makeSut() - jest.spyOn(addSurveyStub, 'add').mockImplementationOnce(throwError) - const httpResponse = await sut.handle(makeFakeRequest()) - expect(httpResponse).toEqual(serverError(new Error())) - }) - - test('Should return 204 on success', async () => { - const { sut } = makeSut() - const httpResponse = await sut.handle(makeFakeRequest()) - expect(httpResponse).toEqual(noContent()) - }) -}) diff --git a/src/presentation/controllers/survey/add-survey/add-survey-controller.ts b/src/presentation/controllers/survey/add-survey/add-survey-controller.ts deleted file mode 100644 index 50f7548..0000000 --- a/src/presentation/controllers/survey/add-survey/add-survey-controller.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { AddSurvey, Controller, HttpRequest, HttpResponse, Validation } from './add-survey-controller-protocols' -import { badRequest, noContent, serverError } from '@/presentation/helpers/http/http-helper' - -export class AddSurveyController implements Controller { - constructor ( - private readonly validation: Validation, - private readonly addSurvey: AddSurvey - ) {} - - async handle (httpRequest: HttpRequest): Promise { - try { - const error = this.validation.validate(httpRequest.body) - if (error) { - return badRequest(error) - } - const { question, answers } = httpRequest.body - await this.addSurvey.add({ - question, - answers, - date: new Date() - }) - return noContent() - } catch (error) { - return serverError(error) - } - } -} diff --git a/src/presentation/controllers/survey/load-surveys/load-surveys-controller-protocols.ts b/src/presentation/controllers/survey/load-surveys/load-surveys-controller-protocols.ts deleted file mode 100644 index ccd9785..0000000 --- a/src/presentation/controllers/survey/load-surveys/load-surveys-controller-protocols.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from '@/presentation/protocols' -export * from '@/domain/usecases/load-surveys' -export * from '@/domain/models/survey' diff --git a/src/presentation/controllers/survey/load-surveys/load-surveys-controller.spec.ts b/src/presentation/controllers/survey/load-surveys/load-surveys-controller.spec.ts deleted file mode 100644 index 1bbedd2..0000000 --- a/src/presentation/controllers/survey/load-surveys/load-surveys-controller.spec.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { LoadSurveysController } from './load-surveys-controller' -import { LoadSurveys } from './load-surveys-controller-protocols' -import { noContent, ok, serverError } from '@/presentation/helpers/http/http-helper' -import { mockLoadSurveys } from '@/presentation/test' -import { mockSurveyModels } from '@/domain/test' -import MockDate from 'mockdate' - -type SutTypes = { - sut: LoadSurveysController - loadSurveysStub: LoadSurveys -} - -const makeSut = (): SutTypes => { - const loadSurveysStub = mockLoadSurveys() - const sut = new LoadSurveysController(loadSurveysStub) - return { - sut, - loadSurveysStub - } -} - -describe('LoadSurveys Controller', () => { - beforeAll(() => { - MockDate.set(new Date()) - }) - - afterAll(() => { - MockDate.reset() - }) - - test('Should call LoadSurveys', async () => { - const { sut, loadSurveysStub } = makeSut() - const loadSpy = jest.spyOn(loadSurveysStub, 'load') - await sut.handle({}) - expect(loadSpy).toHaveBeenCalled() - }) - - test('Should 200 on success', async () => { - const { sut } = makeSut() - const httpResponse = await sut.handle({}) - expect(httpResponse).toEqual(ok(mockSurveyModels())) - }) - - test('Should return 204 if LoadSurveys returns empty', async () => { - const { sut, loadSurveysStub } = makeSut() - jest.spyOn(loadSurveysStub, 'load').mockReturnValueOnce(Promise.resolve(([]))) - const httpResponse = await sut.handle({}) - expect(httpResponse).toEqual(noContent()) - }) - - test('Should return 500 if LoadSurveys throws', async () => { - const { sut, loadSurveysStub } = makeSut() - jest.spyOn(loadSurveysStub, 'load').mockReturnValueOnce(Promise.reject(new Error())) - const httpResponse = await sut.handle({}) - expect(httpResponse).toEqual(serverError(new Error())) - }) -}) diff --git a/src/presentation/controllers/survey/load-surveys/load-surveys-controller.ts b/src/presentation/controllers/survey/load-surveys/load-surveys-controller.ts deleted file mode 100644 index 8f55d2b..0000000 --- a/src/presentation/controllers/survey/load-surveys/load-surveys-controller.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { noContent, ok, serverError } from '@/presentation/helpers/http/http-helper' -import { Controller, HttpRequest, HttpResponse, LoadSurveys } from './load-surveys-controller-protocols' - -export class LoadSurveysController implements Controller { - constructor (private readonly loadSurveys: LoadSurveys) {} - - async handle (httpRequest: HttpRequest): Promise { - try { - const surveys = await this.loadSurveys.load() - return surveys.length ? ok(surveys) : noContent() - } catch (error) { - return serverError(error) - } - } -} diff --git a/src/presentation/helpers/http/http-helper.ts b/src/presentation/helpers/http-helper.ts similarity index 100% rename from src/presentation/helpers/http/http-helper.ts rename to src/presentation/helpers/http-helper.ts index 917b862..c40432f 100644 --- a/src/presentation/helpers/http/http-helper.ts +++ b/src/presentation/helpers/http-helper.ts @@ -1,32 +1,32 @@ import { HttpResponse } from '@/presentation/protocols' import { ServerError, UnauthorizedError } from '@/presentation/errors' -export const ok = (data: any): HttpResponse => ({ - statusCode: 200, - body: data -}) - -export const noContent = (): HttpResponse => ({ - statusCode: 204, - body: null -}) - export const badRequest = (error: Error): HttpResponse => ({ statusCode: 400, body: error }) -export const unauthorized = (): HttpResponse => ({ - statusCode: 401, - body: new UnauthorizedError() -}) - export const forbidden = (error: Error): HttpResponse => ({ statusCode: 403, body: error }) +export const unauthorized = (): HttpResponse => ({ + statusCode: 401, + body: new UnauthorizedError() +}) + export const serverError = (error: Error): HttpResponse => ({ statusCode: 500, body: new ServerError(error.stack) }) + +export const ok = (data: any): HttpResponse => ({ + statusCode: 200, + body: data +}) + +export const noContent = (): HttpResponse => ({ + statusCode: 204, + body: null +}) diff --git a/src/presentation/helpers/index.ts b/src/presentation/helpers/index.ts new file mode 100644 index 0000000..a170a2e --- /dev/null +++ b/src/presentation/helpers/index.ts @@ -0,0 +1 @@ +export * from './http-helper' diff --git a/src/presentation/middlewares/auth-middleware-protocols.ts b/src/presentation/middlewares/auth-middleware-protocols.ts deleted file mode 100644 index 9b6cd3b..0000000 --- a/src/presentation/middlewares/auth-middleware-protocols.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from '../protocols' -export * from '../../domain/usecases/load-account-by-token' -export * from '../../domain/models/account' diff --git a/src/presentation/middlewares/auth-middleware.spec.ts b/src/presentation/middlewares/auth-middleware.spec.ts deleted file mode 100644 index 62eaddc..0000000 --- a/src/presentation/middlewares/auth-middleware.spec.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { AuthMiddleware } from './auth-middleware' -import { LoadAccountByToken, HttpRequest } from './auth-middleware-protocols' -import { forbidden, ok, serverError } from '@/presentation/helpers/http/http-helper' -import { AccessDeniedError } from '@/presentation/errors' -import { mockLoadAccountByToken } from '../test' - -const makeFakeRequest = (): HttpRequest => ({ - headers: { - 'x-access-token': 'any_token' - } -}) - -type SutTypes = { - sut: AuthMiddleware - loadAccountByTokenStub: LoadAccountByToken -} - -const makeSut = (role?: string): SutTypes => { - const loadAccountByTokenStub = mockLoadAccountByToken() - const sut = new AuthMiddleware(loadAccountByTokenStub, role) - return { - sut, - loadAccountByTokenStub - } -} - -describe('Auth Middleware', () => { - test('Should return 403 if no x-access-token exists in headers', async () => { - const { sut } = makeSut() - const httpResponse = await sut.handle({}) - expect(httpResponse).toEqual(forbidden(new AccessDeniedError())) - }) - - test('Should call LoadAccountByToken with correct accessToken', async () => { - const role = 'any_role' - const { sut, loadAccountByTokenStub } = makeSut(role) - const loadSpy = jest.spyOn(loadAccountByTokenStub, 'load') - await sut.handle(makeFakeRequest()) - expect(loadSpy).toHaveBeenCalledWith('any_token', role) - }) - - test('Should return 403 if LoadAccountByToken returns null', async () => { - const { sut, loadAccountByTokenStub } = makeSut() - jest.spyOn(loadAccountByTokenStub, 'load').mockReturnValueOnce(Promise.resolve(null)) - const httpResponse = await sut.handle(makeFakeRequest()) - expect(httpResponse).toEqual(forbidden(new AccessDeniedError())) - }) - - test('Should return 200 if LoadAccountByToken returns an account', async () => { - const { sut } = makeSut() - const httpResponse = await sut.handle(makeFakeRequest()) - expect(httpResponse).toEqual(ok({ accountId: 'any_id' })) - }) - - test('Should return 500 if LoadAccountByToken throws', async () => { - const { sut, loadAccountByTokenStub } = makeSut() - jest.spyOn(loadAccountByTokenStub, 'load').mockReturnValueOnce(Promise.reject(new Error())) - const httpResponse = await sut.handle(makeFakeRequest()) - expect(httpResponse).toEqual(serverError(new Error())) - }) -}) diff --git a/src/presentation/middlewares/auth-middleware.ts b/src/presentation/middlewares/auth-middleware.ts index a81a768..c097512 100644 --- a/src/presentation/middlewares/auth-middleware.ts +++ b/src/presentation/middlewares/auth-middleware.ts @@ -1,6 +1,7 @@ -import { HttpRequest, HttpResponse, Middleware, LoadAccountByToken } from './auth-middleware-protocols' -import { forbidden, ok, serverError } from '../helpers/http/http-helper' -import { AccessDeniedError } from '../errors' +import { Middleware, HttpResponse } from '@/presentation/protocols' +import { forbidden, ok, serverError } from '@/presentation/helpers' +import { AccessDeniedError } from '@/presentation/errors' +import { LoadAccountByToken } from '@/domain/usecases' export class AuthMiddleware implements Middleware { constructor ( @@ -8,9 +9,9 @@ export class AuthMiddleware implements Middleware { private readonly role?: string ) {} - async handle (httpRequest: HttpRequest): Promise { + async handle (request: AuthMiddleware.Request): Promise { try { - const accessToken = httpRequest.headers?.['x-access-token'] + const { accessToken } = request if (accessToken) { const account = await this.loadAccountByToken.load(accessToken, this.role) if (account) { @@ -23,3 +24,9 @@ export class AuthMiddleware implements Middleware { } } } + +export namespace AuthMiddleware { + export type Request = { + accessToken?: string + } +} diff --git a/src/presentation/middlewares/index.ts b/src/presentation/middlewares/index.ts new file mode 100644 index 0000000..6a1dd44 --- /dev/null +++ b/src/presentation/middlewares/index.ts @@ -0,0 +1 @@ +export * from './auth-middleware' diff --git a/src/presentation/protocols/controller.ts b/src/presentation/protocols/controller.ts index adcb89b..3f3a992 100644 --- a/src/presentation/protocols/controller.ts +++ b/src/presentation/protocols/controller.ts @@ -1,5 +1,5 @@ -import { HttpRequest, HttpResponse } from './http' +import { HttpResponse } from '@/presentation/protocols' -export interface Controller { - handle: (httpRequest: HttpRequest) => Promise +export interface Controller { + handle: (request: T) => Promise } diff --git a/src/presentation/protocols/http.ts b/src/presentation/protocols/http.ts index bcb2572..e4d5618 100644 --- a/src/presentation/protocols/http.ts +++ b/src/presentation/protocols/http.ts @@ -2,10 +2,3 @@ export type HttpResponse = { statusCode: number body: any } - -export type HttpRequest = { - body?: any - headers?: any - params?: any - accountId?: string -} diff --git a/src/presentation/protocols/index.ts b/src/presentation/protocols/index.ts index 9596ff3..18968e1 100644 --- a/src/presentation/protocols/index.ts +++ b/src/presentation/protocols/index.ts @@ -1,4 +1,4 @@ export * from './controller' export * from './http' export * from './validation' -export * from './middlewares' +export * from './middleware' diff --git a/src/presentation/protocols/middleware.ts b/src/presentation/protocols/middleware.ts new file mode 100644 index 0000000..cbf8a08 --- /dev/null +++ b/src/presentation/protocols/middleware.ts @@ -0,0 +1,5 @@ +import { HttpResponse } from '@/presentation/protocols' + +export interface Middleware { + handle: (httpRequest: T) => Promise +} diff --git a/src/presentation/protocols/middlewares.ts b/src/presentation/protocols/middlewares.ts deleted file mode 100644 index cbc0962..0000000 --- a/src/presentation/protocols/middlewares.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { type HttpRequest, type HttpResponse } from './http' - -export interface Middleware { - handle: (httpRequest: HttpRequest) => Promise -} diff --git a/src/presentation/test/mock-account.ts b/src/presentation/test/mock-account.ts deleted file mode 100644 index a260544..0000000 --- a/src/presentation/test/mock-account.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Authentication, AuthenticationParams } from '../controllers/login/login/login-controller-protocols' -import { AddAccount, AddAccountParams } from '@/domain/usecases/add-account' -import { LoadAccountByToken } from '@/domain/usecases/load-account-by-token' -import { AccountModel } from '@/domain/models/account' -import { mockAccountModel } from '@/domain/test' - -export const mockAddAccount = (): AddAccount => { - class AddAccountStub implements AddAccount { - async add (account: AddAccountParams): Promise { - return await Promise.resolve(mockAccountModel()) - } - } - return new AddAccountStub() -} - -export const mockAuthentication = (): Authentication => { - class AuthenticationStub implements Authentication { - async auth (authentication: AuthenticationParams): Promise { - return 'any_token' - } - } - return new AuthenticationStub() -} - -export const mockLoadAccountByToken = (): LoadAccountByToken => { - class LoadAccountByTokenStub implements LoadAccountByToken { - async load (accessToken: string, role?: string): Promise { - return await Promise.resolve(mockAccountModel()) - } - } - return new LoadAccountByTokenStub() -} diff --git a/src/presentation/test/mock-survey-result.ts b/src/presentation/test/mock-survey-result.ts deleted file mode 100644 index 6254ad3..0000000 --- a/src/presentation/test/mock-survey-result.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { SaveSurveyResult, SaveSurveyResultParams } from '@/domain/usecases/save-survey-result' -import { SurveyResultModel } from '@/domain/models/survey-result' -import { mockSurveyResultModel } from '@/domain/test' - -export const mockSaveSurveyResult = (): SaveSurveyResult => { - class LoadSurveyByIdStub implements SaveSurveyResult { - async save (data: SaveSurveyResultParams): Promise { - return Promise.resolve(mockSurveyResultModel()) - } - } - return new LoadSurveyByIdStub() -} diff --git a/src/presentation/test/mock-survey.ts b/src/presentation/test/mock-survey.ts deleted file mode 100644 index b5af635..0000000 --- a/src/presentation/test/mock-survey.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { AddSurvey, AddSurveyParams } from '@/domain/usecases/add-survey' -import { LoadSurveyById } from '@/domain/usecases/load-survey-by-id' -import { LoadSurveys } from '@/domain/usecases/load-surveys' -import { SurveyModel } from '@/domain/models/survey' -import { mockSurveyModels, mockSurveyModel } from '@/domain/test' - -export const mockAddSurvey = (): AddSurvey => { - class AddSurveyStub implements AddSurvey { - async add (data: AddSurveyParams): Promise { - await Promise.resolve() - } - } - return new AddSurveyStub() -} - -export const mockLoadSurveys = (): LoadSurveys => { - class LoadSurveysStub implements LoadSurveys { - async load (): Promise { - return Promise.resolve(mockSurveyModels()) - } - } - return new LoadSurveysStub() -} - -export const mockLoadSurveyById = (): LoadSurveyById => { - class LoadSurveyByIdStub implements LoadSurveyById { - async loadById (id: string): Promise { - return Promise.resolve(mockSurveyModel()) - } - } - return new LoadSurveyByIdStub() -} diff --git a/src/presentation/test/mock-validation.ts b/src/presentation/test/mock-validation.ts deleted file mode 100644 index 742e810..0000000 --- a/src/presentation/test/mock-validation.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Validation } from '@/presentation/protocols' - -export const mockValidation = (): Validation => { - class ValidationStub implements Validation { - validate (input: any): Error { - return null - } - } - return new ValidationStub() -} diff --git a/src/validation/protocols/index.ts b/src/validation/protocols/index.ts new file mode 100644 index 0000000..544577c --- /dev/null +++ b/src/validation/protocols/index.ts @@ -0,0 +1 @@ +export * from './email-validator' diff --git a/src/validation/test/mock-email-validator.ts b/src/validation/test/mock-email-validator.ts deleted file mode 100644 index 63cf54a..0000000 --- a/src/validation/test/mock-email-validator.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { EmailValidator } from '@/validation/protocols/email-validator' - -export const mockEmailValidator = (): EmailValidator => { - class EmailValidatorStub implements EmailValidator { - isValid (email: string): boolean { - return true - } - } - return new EmailValidatorStub() -} diff --git a/src/validation/test/mock-validation.ts b/src/validation/test/mock-validation.ts deleted file mode 100644 index 742e810..0000000 --- a/src/validation/test/mock-validation.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Validation } from '@/presentation/protocols' - -export const mockValidation = (): Validation => { - class ValidationStub implements Validation { - validate (input: any): Error { - return null - } - } - return new ValidationStub() -} diff --git a/src/validation/validators/compare-fields-validation.spec.ts b/src/validation/validators/compare-fields-validation.spec.ts deleted file mode 100644 index a7afa8e..0000000 --- a/src/validation/validators/compare-fields-validation.spec.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { CompareFieldsValidation } from './compare-fields-validation' -import { InvalidParamError } from '@/presentation/errors' - -const makeSut = (): CompareFieldsValidation => { - return new CompareFieldsValidation('field', 'fieldToCompare') -} - -describe('CompareFields Validation', () => { - test('Should return a InvalidParamError if validation fails', () => { - const sut = makeSut() - const error = sut.validate({ field: 'any_value', fieldToCompare: 'wrong_value' }) - expect(error).toEqual(new InvalidParamError('fieldToCompare')) - }) - - test('Should not return if validation succeeds', () => { - const sut = makeSut() - const error = sut.validate({ field: 'any_value', fieldToCompare: 'any_value' }) - expect(error).toBeFalsy() - }) -}) diff --git a/src/validation/validators/compare-fields-validation.ts b/src/validation/validators/compare-fields-validation.ts index 030bbf3..a3fd5d5 100644 --- a/src/validation/validators/compare-fields-validation.ts +++ b/src/validation/validators/compare-fields-validation.ts @@ -1,5 +1,5 @@ +import { Validation } from '@/presentation/protocols' import { InvalidParamError } from '@/presentation/errors' -import { Validation } from '@/presentation/protocols/validation' export class CompareFieldsValidation implements Validation { constructor ( diff --git a/src/validation/validators/email-validation.spec.ts b/src/validation/validators/email-validation.spec.ts deleted file mode 100644 index c404420..0000000 --- a/src/validation/validators/email-validation.spec.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { EmailValidation } from './email-validation' -import { EmailValidator } from '@/validation/protocols/email-validator' -import { mockEmailValidator } from '@/validation/test' -import { InvalidParamError } from '@/presentation/errors' - -type SutTypes = { - sut: EmailValidation - emailValidatorStub: EmailValidator -} - -const makeSut = (): SutTypes => { - const emailValidatorStub = mockEmailValidator() - const sut = new EmailValidation('email', emailValidatorStub) - return { - sut, - emailValidatorStub - } -} - -describe('Email Validation', () => { - test('Should return an error if EmailValidator returns false', () => { - const { sut, emailValidatorStub } = makeSut() - jest.spyOn(emailValidatorStub, 'isValid').mockReturnValueOnce(false) - const error = sut.validate({ email: 'any_email@example.com' }) - expect(error).toEqual(new InvalidParamError('email')) - }) - - test('Should call EmailValidator with correct email', () => { - const { sut, emailValidatorStub } = makeSut() - const isValidSpy = jest.spyOn(emailValidatorStub, 'isValid') - sut.validate({ email: 'any_email@example.com' }) - expect(isValidSpy).toHaveBeenCalledWith('any_email@example.com') - }) - - test('Should throw if EmailValidator throws', () => { - const { sut, emailValidatorStub } = makeSut() - jest.spyOn(emailValidatorStub, 'isValid').mockImplementationOnce(() => { - throw new Error() - }) - expect(sut.validate).toThrow() - }) -}) diff --git a/src/validation/validators/email-validation.ts b/src/validation/validators/email-validation.ts index 181263d..57a86e3 100644 --- a/src/validation/validators/email-validation.ts +++ b/src/validation/validators/email-validation.ts @@ -1,6 +1,6 @@ +import { EmailValidator } from '@/validation/protocols' +import { Validation } from '@/presentation/protocols' import { InvalidParamError } from '@/presentation/errors' -import { EmailValidator } from '@/validation/protocols/email-validator' -import { Validation } from '@/presentation/protocols/validation' export class EmailValidation implements Validation { constructor ( diff --git a/src/validation/validators/required-field-validation.ts b/src/validation/validators/required-field-validation.ts index 5b9df85..53e0808 100644 --- a/src/validation/validators/required-field-validation.ts +++ b/src/validation/validators/required-field-validation.ts @@ -1,5 +1,5 @@ +import { Validation } from '@/presentation/protocols' import { MissingParamError } from '@/presentation/errors' -import { Validation } from '@/presentation/protocols/validation' export class RequiredFieldValidation implements Validation { constructor (private readonly fieldName: string) {} diff --git a/src/validation/validators/validation-composite.spec.ts b/src/validation/validators/validation-composite.spec.ts deleted file mode 100644 index 1cc8683..0000000 --- a/src/validation/validators/validation-composite.spec.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { ValidationComposite } from './validation-composite' -import { mockValidation } from '@/validation/test' -import { MissingParamError } from '@/presentation/errors' -import { Validation } from '@/presentation/protocols/validation' - -type SutTypes = { - sut: ValidationComposite - validationStubs: Validation[] -} - -const makeSut = (): SutTypes => { - const validationStubs = [mockValidation(), mockValidation()] - const sut = new ValidationComposite(validationStubs) - return { - sut, - validationStubs - } -} - -describe('Validation Composite', () => { - test('Should return an error if any validation fails', () => { - const { sut, validationStubs } = makeSut() - jest.spyOn(validationStubs[0], 'validate').mockReturnValueOnce(new MissingParamError('field')) - const error = sut.validate({ field: 'any_value' }) - expect(error).toEqual(new MissingParamError('field')) - }) - - test('Should return the first error if more then one validation fails', () => { - const { sut, validationStubs } = makeSut() - jest.spyOn(validationStubs[0], 'validate').mockReturnValueOnce(new Error()) - jest.spyOn(validationStubs[1], 'validate').mockReturnValueOnce(new MissingParamError('field')) - const error = sut.validate({ field: 'any_value' }) - expect(error).toEqual(new Error()) - }) - - test('Should not return if validation succeeds', () => { - const { sut } = makeSut() - const error = sut.validate({ field: 'any_value' }) - expect(error).toBeFalsy() - }) -}) diff --git a/src/validation/validators/validation-composite.ts b/src/validation/validators/validation-composite.ts index 471c8a4..e3c21ba 100644 --- a/src/validation/validators/validation-composite.ts +++ b/src/validation/validators/validation-composite.ts @@ -1,4 +1,4 @@ -import { Validation } from '@/presentation/protocols/validation' +import { Validation } from '@/presentation/protocols' export class ValidationComposite implements Validation { constructor (private readonly validations: Validation[]) {} diff --git a/src/data/test/index.ts b/tests/data/mocks/index.ts similarity index 79% rename from src/data/test/index.ts rename to tests/data/mocks/index.ts index 725413a..26817b1 100644 --- a/src/data/test/index.ts +++ b/tests/data/mocks/index.ts @@ -1,4 +1,4 @@ -export * from './mock-criptography' +export * from './mock-cryptography' export * from './mock-db-account' export * from './mock-db-log' export * from './mock-db-survey' diff --git a/tests/data/mocks/mock-cryptography.ts b/tests/data/mocks/mock-cryptography.ts new file mode 100644 index 0000000..2a1b291 --- /dev/null +++ b/tests/data/mocks/mock-cryptography.ts @@ -0,0 +1,45 @@ +import { Hasher, HashComparer, Encrypter, Decrypter } from '@/data/protocols' + +import { faker } from '@faker-js/faker' + +export class HasherSpy implements Hasher { + digest = faker.datatype.uuid() + plaintext: string + + async hash (plaintext: string): Promise { + this.plaintext = plaintext + return this.digest + } +} + +export class HashComparerSpy implements HashComparer { + plaintext: string + digest: string + isValid = true + + async compare (plaintext: string, digest: string): Promise { + this.plaintext = plaintext + this.digest = digest + return this.isValid + } +} + +export class EncrypterSpy implements Encrypter { + ciphertext = faker.datatype.uuid() + plaintext: string + + async encrypt (plaintext: string): Promise { + this.plaintext = plaintext + return this.ciphertext + } +} + +export class DecrypterSpy implements Decrypter { + plaintext = faker.internet.password() + ciphertext: string + + async decrypt (ciphertext: string): Promise { + this.ciphertext = ciphertext + return this.plaintext + } +} diff --git a/tests/data/mocks/mock-db-account.ts b/tests/data/mocks/mock-db-account.ts new file mode 100644 index 0000000..8b4d562 --- /dev/null +++ b/tests/data/mocks/mock-db-account.ts @@ -0,0 +1,61 @@ +import type { AddAccountRepository, LoadAccountByEmailRepository, LoadAccountByTokenRepository, UpdateAccessTokenRepository, CheckAccountByEmailRepository } from '@/data/protocols' + +import { faker } from '@faker-js/faker' + +export class AddAccountRepositorySpy implements AddAccountRepository { + params: AddAccountRepository.Params + result = true + + async add (params: AddAccountRepository.Params): Promise { + this.params = params + return this.result + } +} + +export class LoadAccountByEmailRepositorySpy implements LoadAccountByEmailRepository { + email: string + result = { + id: faker.datatype.uuid(), + name: faker.name.fullName(), + password: faker.internet.password() + } + + async loadByEmail (email: string): Promise { + this.email = email + return this.result + } +} + +export class CheckAccountByEmailRepositorySpy implements CheckAccountByEmailRepository { + email: string + result = false + + async checkByEmail (email: string): Promise { + this.email = email + return this.result + } +} + +export class LoadAccountByTokenRepositorySpy implements LoadAccountByTokenRepository { + token: string + role: string + result = { + id: faker.datatype.uuid() + } + + async loadByToken (token: string, role?: string): Promise { + this.token = token + this.role = role + return this.result + } +} + +export class UpdateAccessTokenRepositorySpy implements UpdateAccessTokenRepository { + id: string + token: string + + async updateAccessToken (id: string, token: string): Promise { + this.id = id + this.token = token + } +} diff --git a/tests/data/mocks/mock-db-log.ts b/tests/data/mocks/mock-db-log.ts new file mode 100644 index 0000000..a6eaa63 --- /dev/null +++ b/tests/data/mocks/mock-db-log.ts @@ -0,0 +1,9 @@ +import { LogErrorRepository } from '@/data/protocols' + +export class LogErrorRepositorySpy implements LogErrorRepository { + stack: string + + async logError (stack: string): Promise { + this.stack = stack + } +} diff --git a/tests/data/mocks/mock-db-survey-result.ts b/tests/data/mocks/mock-db-survey-result.ts new file mode 100644 index 0000000..611e542 --- /dev/null +++ b/tests/data/mocks/mock-db-survey-result.ts @@ -0,0 +1,22 @@ +import { SaveSurveyResultRepository, LoadSurveyResultRepository } from '@/data/protocols' +import { mockSurveyResultModel } from '@/tests/domain/mocks' + +export class SaveSurveyResultRepositorySpy implements SaveSurveyResultRepository { + params: SaveSurveyResultRepository.Params + + async save (params: SaveSurveyResultRepository.Params): Promise { + this.params = params + } +} + +export class LoadSurveyResultRepositorySpy implements LoadSurveyResultRepository { + surveyId: string + accountId: string + result = mockSurveyResultModel() + + async loadBySurveyId (surveyId: string, accountId: string): Promise { + this.surveyId = surveyId + this.accountId = accountId + return this.result + } +} diff --git a/tests/data/mocks/mock-db-survey.ts b/tests/data/mocks/mock-db-survey.ts new file mode 100644 index 0000000..4e5040f --- /dev/null +++ b/tests/data/mocks/mock-db-survey.ts @@ -0,0 +1,55 @@ +import { AddSurveyRepository, LoadSurveyByIdRepository, LoadSurveysRepository, CheckSurveyByIdRepository, LoadAnswersBySurveyRepository } from '@/data/protocols' +import { mockSurveyModel, mockSurveyModels } from '@/tests/domain/mocks' + +import { faker } from '@faker-js/faker' + +export class AddSurveyRepositorySpy implements AddSurveyRepository { + params: AddSurveyRepository.Params + + async add (params: AddSurveyRepository.Params): Promise { + this.params = params + } +} + +export class LoadSurveyByIdRepositorySpy implements LoadSurveyByIdRepository { + id: string + result = mockSurveyModel() + + async loadById (id: string): Promise { + this.id = id + return this.result + } +} + +export class LoadAnswersBySurveyRepositorySpy implements LoadAnswersBySurveyRepository { + id: string + result = [ + faker.random.word(), + faker.random.word() + ] + + async loadAnswers (id: string): Promise { + this.id = id + return this.result + } +} + +export class CheckSurveyByIdRepositorySpy implements CheckSurveyByIdRepository { + id: string + result = true + + async checkById (id: string): Promise { + this.id = id + return this.result + } +} + +export class LoadSurveysRepositorySpy implements LoadSurveysRepository { + accountId: string + result = mockSurveyModels() + + async loadAll (accountId: string): Promise { + this.accountId = accountId + return this.result + } +} diff --git a/tests/data/usecases/db-add-account.spec.ts b/tests/data/usecases/db-add-account.spec.ts new file mode 100644 index 0000000..5e7563f --- /dev/null +++ b/tests/data/usecases/db-add-account.spec.ts @@ -0,0 +1,84 @@ +import { DbAddAccount } from '@/data/usecases' +import { mockAddAccountParams, throwError } from '@/tests/domain/mocks' +import { HasherSpy, AddAccountRepositorySpy, CheckAccountByEmailRepositorySpy } from '@/tests/data/mocks' + +type SutTypes = { + sut: DbAddAccount + hasherSpy: HasherSpy + addAccountRepositorySpy: AddAccountRepositorySpy + checkAccountByEmailRepositorySpy: CheckAccountByEmailRepositorySpy +} + +const makeSut = (): SutTypes => { + const checkAccountByEmailRepositorySpy = new CheckAccountByEmailRepositorySpy() + const hasherSpy = new HasherSpy() + const addAccountRepositorySpy = new AddAccountRepositorySpy() + const sut = new DbAddAccount(hasherSpy, addAccountRepositorySpy, checkAccountByEmailRepositorySpy) + return { + sut, + hasherSpy, + addAccountRepositorySpy, + checkAccountByEmailRepositorySpy + } +} + +describe('DbAddAccount Usecase', () => { + test('Should call Hasher with correct plaintext', async () => { + const { sut, hasherSpy } = makeSut() + const addAccountParams = mockAddAccountParams() + await sut.add(addAccountParams) + expect(hasherSpy.plaintext).toBe(addAccountParams.password) + }) + + test('Should throw if Hasher throws', async () => { + const { sut, hasherSpy } = makeSut() + jest.spyOn(hasherSpy, 'hash').mockImplementationOnce(throwError) + const promise = sut.add(mockAddAccountParams()) + await expect(promise).rejects.toThrow() + }) + + test('Should call AddAccountRepository with correct values', async () => { + const { sut, addAccountRepositorySpy, hasherSpy } = makeSut() + const addAccountParams = mockAddAccountParams() + await sut.add(addAccountParams) + expect(addAccountRepositorySpy.params).toEqual({ + name: addAccountParams.name, + email: addAccountParams.email, + password: hasherSpy.digest + }) + }) + + test('Should throw if AddAccountRepository throws', async () => { + const { sut, addAccountRepositorySpy } = makeSut() + jest.spyOn(addAccountRepositorySpy, 'add').mockImplementationOnce(throwError) + const promise = sut.add(mockAddAccountParams()) + await expect(promise).rejects.toThrow() + }) + + test('Should return true on success', async () => { + const { sut } = makeSut() + const isValid = await sut.add(mockAddAccountParams()) + expect(isValid).toBe(true) + }) + + test('Should return false if AddAccountRepository returns false', async () => { + const { sut, addAccountRepositorySpy } = makeSut() + addAccountRepositorySpy.result = false + const isValid = await sut.add(mockAddAccountParams()) + expect(isValid).toBe(false) + }) + + test('Should return false if CheckAccountByEmailRepository returns true', async () => { + const { sut, checkAccountByEmailRepositorySpy } = makeSut() + checkAccountByEmailRepositorySpy.result = true + const isValid = await sut.add(mockAddAccountParams()) + expect(isValid).toBe(false) + }) + + test('Should call LoadAccountByEmailRepository with correct email', async () => { + const { sut, checkAccountByEmailRepositorySpy } = makeSut() + const addAccountParams = mockAddAccountParams() + await sut.add(addAccountParams) + expect(checkAccountByEmailRepositorySpy.email).toBe(addAccountParams.email) + }) +}) diff --git a/tests/data/usecases/db-add-survey.spec.ts b/tests/data/usecases/db-add-survey.spec.ts new file mode 100644 index 0000000..79da53e --- /dev/null +++ b/tests/data/usecases/db-add-survey.spec.ts @@ -0,0 +1,43 @@ +import { DbAddSurvey } from '@/data/usecases' +import { AddSurveyRepositorySpy } from '@/tests/data/mocks' +import { throwError, mockAddSurveyParams } from '@/tests/domain/mocks' + +import MockDate from 'mockdate' + +type SutTypes = { + sut: DbAddSurvey + addSurveyRepositorySpy: AddSurveyRepositorySpy +} + +const makeSut = (): SutTypes => { + const addSurveyRepositorySpy = new AddSurveyRepositorySpy() + const sut = new DbAddSurvey(addSurveyRepositorySpy) + return { + sut, + addSurveyRepositorySpy + } +} + +describe('DbAddSurvey Usecase', () => { + beforeAll(() => { + MockDate.set(new Date()) + }) + + afterAll(() => { + MockDate.reset() + }) + + test('Should call AddSurveyRepository with correct values', async () => { + const { sut, addSurveyRepositorySpy } = makeSut() + const surveyData = mockAddSurveyParams() + await sut.add(surveyData) + expect(addSurveyRepositorySpy.params).toEqual(surveyData) + }) + + test('Should throw if AddSurveyRepository throws', async () => { + const { sut, addSurveyRepositorySpy } = makeSut() + jest.spyOn(addSurveyRepositorySpy, 'add').mockImplementationOnce(throwError) + const promise = sut.add(mockAddSurveyParams()) + await expect(promise).rejects.toThrow() + }) +}) diff --git a/tests/data/usecases/db-authentication.spec.ts b/tests/data/usecases/db-authentication.spec.ts new file mode 100644 index 0000000..e9eae0b --- /dev/null +++ b/tests/data/usecases/db-authentication.spec.ts @@ -0,0 +1,110 @@ +import { DbAuthentication } from '@/data/usecases' +import { HashComparerSpy, EncrypterSpy, UpdateAccessTokenRepositorySpy, LoadAccountByEmailRepositorySpy } from '@/tests/data/mocks' +import { throwError, mockAuthenticationParams } from '@/tests/domain/mocks' + +type SutTypes = { + sut: DbAuthentication + loadAccountByEmailRepositorySpy: LoadAccountByEmailRepositorySpy + hashComparerSpy: HashComparerSpy + encrypterSpy: EncrypterSpy + updateAccessTokenRepositorySpy: UpdateAccessTokenRepositorySpy +} + +const makeSut = (): SutTypes => { + const loadAccountByEmailRepositorySpy = new LoadAccountByEmailRepositorySpy() + const hashComparerSpy = new HashComparerSpy() + const encrypterSpy = new EncrypterSpy() + const updateAccessTokenRepositorySpy = new UpdateAccessTokenRepositorySpy() + const sut = new DbAuthentication( + loadAccountByEmailRepositorySpy, + hashComparerSpy, + encrypterSpy, + updateAccessTokenRepositorySpy + ) + return { + sut, + loadAccountByEmailRepositorySpy, + hashComparerSpy, + encrypterSpy, + updateAccessTokenRepositorySpy + } +} + +describe('DbAuthentication UseCase', () => { + test('Should call LoadAccountByEmailRepository with correct email', async () => { + const { sut, loadAccountByEmailRepositorySpy } = makeSut() + const authenticationParams = mockAuthenticationParams() + await sut.auth(authenticationParams) + expect(loadAccountByEmailRepositorySpy.email).toBe(authenticationParams.email) + }) + + test('Should throw if LoadAccountByEmailRepository throws', async () => { + const { sut, loadAccountByEmailRepositorySpy } = makeSut() + jest.spyOn(loadAccountByEmailRepositorySpy, 'loadByEmail').mockImplementationOnce(throwError) + const promise = sut.auth(mockAuthenticationParams()) + await expect(promise).rejects.toThrow() + }) + + test('Should return null if LoadAccountByEmailRepository returns null', async () => { + const { sut, loadAccountByEmailRepositorySpy } = makeSut() + loadAccountByEmailRepositorySpy.result = null + const model = await sut.auth(mockAuthenticationParams()) + expect(model).toBeNull() + }) + + test('Should call HashComparer with correct values', async () => { + const { sut, hashComparerSpy, loadAccountByEmailRepositorySpy } = makeSut() + const authenticationParams = mockAuthenticationParams() + await sut.auth(authenticationParams) + expect(hashComparerSpy.plaintext).toBe(authenticationParams.password) + expect(hashComparerSpy.digest).toBe(loadAccountByEmailRepositorySpy.result.password) + }) + + test('Should throw if HashComparer throws', async () => { + const { sut, hashComparerSpy } = makeSut() + jest.spyOn(hashComparerSpy, 'compare').mockImplementationOnce(throwError) + const promise = sut.auth(mockAuthenticationParams()) + await expect(promise).rejects.toThrow() + }) + + test('Should return null if HashComparer returns false', async () => { + const { sut, hashComparerSpy } = makeSut() + hashComparerSpy.isValid = false + const model = await sut.auth(mockAuthenticationParams()) + expect(model).toBeNull() + }) + + test('Should call Encrypter with correct plaintext', async () => { + const { sut, encrypterSpy, loadAccountByEmailRepositorySpy } = makeSut() + await sut.auth(mockAuthenticationParams()) + expect(encrypterSpy.plaintext).toBe(loadAccountByEmailRepositorySpy.result.id) + }) + + test('Should throw if Encrypter throws', async () => { + const { sut, encrypterSpy } = makeSut() + jest.spyOn(encrypterSpy, 'encrypt').mockImplementationOnce(throwError) + const promise = sut.auth(mockAuthenticationParams()) + await expect(promise).rejects.toThrow() + }) + + test('Should return an data on success', async () => { + const { sut, encrypterSpy, loadAccountByEmailRepositorySpy } = makeSut() + const { accessToken, name } = await sut.auth(mockAuthenticationParams()) + expect(accessToken).toBe(encrypterSpy.ciphertext) + expect(name).toBe(loadAccountByEmailRepositorySpy.result.name) + }) + + test('Should call UpdateAccessTokenRepository with correct values', async () => { + const { sut, updateAccessTokenRepositorySpy, loadAccountByEmailRepositorySpy, encrypterSpy } = makeSut() + await sut.auth(mockAuthenticationParams()) + expect(updateAccessTokenRepositorySpy.id).toBe(loadAccountByEmailRepositorySpy.result.id) + expect(updateAccessTokenRepositorySpy.token).toBe(encrypterSpy.ciphertext) + }) + + test('Should throw if UpdateAccessTokenRepository throws', async () => { + const { sut, updateAccessTokenRepositorySpy } = makeSut() + jest.spyOn(updateAccessTokenRepositorySpy, 'updateAccessToken').mockImplementationOnce(throwError) + const promise = sut.auth(mockAuthenticationParams()) + await expect(promise).rejects.toThrow() + }) +}) diff --git a/tests/data/usecases/db-check-survey-by-id.spec.ts b/tests/data/usecases/db-check-survey-by-id.spec.ts new file mode 100644 index 0000000..a56684a --- /dev/null +++ b/tests/data/usecases/db-check-survey-by-id.spec.ts @@ -0,0 +1,53 @@ +import { DbCheckSurveyById } from '@/data/usecases' +import { CheckSurveyByIdRepositorySpy } from '@/tests/data/mocks' +import { throwError } from '@/tests/domain/mocks' + +import { faker } from '@faker-js/faker' + +type SutTypes = { + sut: DbCheckSurveyById + checkSurveyByIdRepositorySpy: CheckSurveyByIdRepositorySpy +} + +const makeSut = (): SutTypes => { + const checkSurveyByIdRepositorySpy = new CheckSurveyByIdRepositorySpy() + const sut = new DbCheckSurveyById(checkSurveyByIdRepositorySpy) + return { + sut, + checkSurveyByIdRepositorySpy + } +} + +let surveyId: string + +describe('DbLoadSurveyById', () => { + beforeEach(() => { + surveyId = faker.datatype.uuid() + }) + + test('Should call CheckSurveyByIdRepository', async () => { + const { sut, checkSurveyByIdRepositorySpy } = makeSut() + await sut.checkById(surveyId) + expect(checkSurveyByIdRepositorySpy.id).toBe(surveyId) + }) + + test('Should return true if CheckSurveyByIdRepository returns true', async () => { + const { sut } = makeSut() + const exists = await sut.checkById(surveyId) + expect(exists).toBe(true) + }) + + test('Should return false if CheckSurveyByIdRepository returns false', async () => { + const { sut, checkSurveyByIdRepositorySpy } = makeSut() + checkSurveyByIdRepositorySpy.result = false + const exists = await sut.checkById(surveyId) + expect(exists).toBe(false) + }) + + test('Should throw if CheckSurveyByIdRepository throws', async () => { + const { sut, checkSurveyByIdRepositorySpy } = makeSut() + jest.spyOn(checkSurveyByIdRepositorySpy, 'checkById').mockImplementationOnce(throwError) + const promise = sut.checkById(surveyId) + await expect(promise).rejects.toThrow() + }) +}) diff --git a/tests/data/usecases/db-load-account-by-token.spec.ts b/tests/data/usecases/db-load-account-by-token.spec.ts new file mode 100644 index 0000000..a432a64 --- /dev/null +++ b/tests/data/usecases/db-load-account-by-token.spec.ts @@ -0,0 +1,79 @@ +import { DbLoadAccountByToken } from '@/data/usecases' +import { DecrypterSpy, LoadAccountByTokenRepositorySpy } from '@/tests/data/mocks' +import { throwError } from '@/tests/domain/mocks' + +import { faker } from '@faker-js/faker' + +type SutTypes = { + sut: DbLoadAccountByToken + decrypterSpy: DecrypterSpy + loadAccountByTokenRepositorySpy: LoadAccountByTokenRepositorySpy +} + +const makeSut = (): SutTypes => { + const decrypterSpy = new DecrypterSpy() + const loadAccountByTokenRepositorySpy = new LoadAccountByTokenRepositorySpy() + const sut = new DbLoadAccountByToken(decrypterSpy, loadAccountByTokenRepositorySpy) + return { + sut, + decrypterSpy, + loadAccountByTokenRepositorySpy + } +} + +let token: string +let role: string + +describe('DbLoadAccountByToken Usecase', () => { + beforeEach(() => { + token = faker.datatype.uuid() + role = faker.random.word() + }) + + test('Should call Decrypter with correct ciphertext', async () => { + const { sut, decrypterSpy } = makeSut() + await sut.load(token, role) + expect(decrypterSpy.ciphertext).toBe(token) + }) + + test('Should return null if Decrypter returns null', async () => { + const { sut, decrypterSpy } = makeSut() + decrypterSpy.plaintext = null + const account = await sut.load(token, role) + expect(account).toBeNull() + }) + + test('Should call LoadAccountByTokenRepository with correct values', async () => { + const { sut, loadAccountByTokenRepositorySpy } = makeSut() + await sut.load(token, role) + expect(loadAccountByTokenRepositorySpy.token).toBe(token) + expect(loadAccountByTokenRepositorySpy.role).toBe(role) + }) + + test('Should return null if LoadAccountByTokenRepository returns null', async () => { + const { sut, loadAccountByTokenRepositorySpy } = makeSut() + loadAccountByTokenRepositorySpy.result = null + const account = await sut.load(token, role) + expect(account).toBeNull() + }) + + test('Should return an account on success', async () => { + const { sut, loadAccountByTokenRepositorySpy } = makeSut() + const account = await sut.load(token, role) + expect(account).toEqual(loadAccountByTokenRepositorySpy.result) + }) + + test('Should throw if Decrypter throws', async () => { + const { sut, decrypterSpy } = makeSut() + jest.spyOn(decrypterSpy, 'decrypt').mockImplementationOnce(throwError) + const account = await sut.load(token, role) + expect(account).toBeNull() + }) + + test('Should throw if LoadAccountByTokenRepository throws', async () => { + const { sut, loadAccountByTokenRepositorySpy } = makeSut() + jest.spyOn(loadAccountByTokenRepositorySpy, 'loadByToken').mockImplementationOnce(throwError) + const promise = sut.load(token, role) + await expect(promise).rejects.toThrow() + }) +}) diff --git a/tests/data/usecases/db-load-answers-by-survey.spec.ts b/tests/data/usecases/db-load-answers-by-survey.spec.ts new file mode 100644 index 0000000..110534f --- /dev/null +++ b/tests/data/usecases/db-load-answers-by-survey.spec.ts @@ -0,0 +1,56 @@ +import { DbLoadAnswersBySurvey } from '@/data/usecases' +import { LoadAnswersBySurveyRepositorySpy } from '@/tests/data/mocks' +import { throwError } from '@/tests/domain/mocks' + +import { faker } from '@faker-js/faker' + +type SutTypes = { + sut: DbLoadAnswersBySurvey + loadAnswersBySurveyRepositorySpy: LoadAnswersBySurveyRepositorySpy +} + +const makeSut = (): SutTypes => { + const loadAnswersBySurveyRepositorySpy = new LoadAnswersBySurveyRepositorySpy() + const sut = new DbLoadAnswersBySurvey(loadAnswersBySurveyRepositorySpy) + return { + sut, + loadAnswersBySurveyRepositorySpy + } +} + +let surveyId: string + +describe('DbLoadAnswersBySurvey', () => { + beforeEach(() => { + surveyId = faker.datatype.uuid() + }) + + test('Should call LoadAnswersBySurveyRepository', async () => { + const { sut, loadAnswersBySurveyRepositorySpy } = makeSut() + await sut.loadAnswers(surveyId) + expect(loadAnswersBySurveyRepositorySpy.id).toBe(surveyId) + }) + + test('Should return answers on success', async () => { + const { sut, loadAnswersBySurveyRepositorySpy } = makeSut() + const answers = await sut.loadAnswers(surveyId) + expect(answers).toEqual([ + loadAnswersBySurveyRepositorySpy.result[0], + loadAnswersBySurveyRepositorySpy.result[1] + ]) + }) + + test('Should return empty array if LoadAnswersBySurveyRepository returns []', async () => { + const { sut, loadAnswersBySurveyRepositorySpy } = makeSut() + loadAnswersBySurveyRepositorySpy.result = [] + const answers = await sut.loadAnswers(surveyId) + expect(answers).toEqual([]) + }) + + test('Should throw if LoadAnswersBySurveyRepository throws', async () => { + const { sut, loadAnswersBySurveyRepositorySpy } = makeSut() + jest.spyOn(loadAnswersBySurveyRepositorySpy, 'loadAnswers').mockImplementationOnce(throwError) + const promise = sut.loadAnswers(surveyId) + await expect(promise).rejects.toThrow() + }) +}) diff --git a/tests/data/usecases/db-load-survey-result.spec.ts b/tests/data/usecases/db-load-survey-result.spec.ts new file mode 100644 index 0000000..8025775 --- /dev/null +++ b/tests/data/usecases/db-load-survey-result.spec.ts @@ -0,0 +1,86 @@ +import { DbLoadSurveyResult } from '@/data/usecases' +import { LoadSurveyResultRepositorySpy, LoadSurveyByIdRepositorySpy } from '@/tests/data/mocks' +import { throwError } from '@/tests/domain/mocks' + +import MockDate from 'mockdate' +import { faker } from '@faker-js/faker' + +type SutTypes = { + sut: DbLoadSurveyResult + loadSurveyResultRepositorySpy: LoadSurveyResultRepositorySpy + loadSurveyByIdRepositorySpy: LoadSurveyByIdRepositorySpy +} + +const makeSut = (): SutTypes => { + const loadSurveyResultRepositorySpy = new LoadSurveyResultRepositorySpy() + const loadSurveyByIdRepositorySpy = new LoadSurveyByIdRepositorySpy() + const sut = new DbLoadSurveyResult(loadSurveyResultRepositorySpy, loadSurveyByIdRepositorySpy) + return { + sut, + loadSurveyResultRepositorySpy, + loadSurveyByIdRepositorySpy + } +} + +let surveyId: string +let accountId: string + +describe('DbLoadSurveyResult UseCase', () => { + beforeAll(() => { + MockDate.set(new Date()) + }) + + afterAll(() => { + MockDate.reset() + }) + + beforeEach(() => { + surveyId = faker.datatype.uuid() + accountId = faker.datatype.uuid() + }) + + test('Should call LoadSurveyResultRepository with correct values', async () => { + const { sut, loadSurveyResultRepositorySpy } = makeSut() + await sut.load(surveyId, accountId) + expect(loadSurveyResultRepositorySpy.surveyId).toBe(surveyId) + expect(loadSurveyResultRepositorySpy.accountId).toBe(accountId) + }) + + test('Should throw if LoadSurveyResultRepository throws', async () => { + const { sut, loadSurveyResultRepositorySpy } = makeSut() + jest.spyOn(loadSurveyResultRepositorySpy, 'loadBySurveyId').mockImplementationOnce(throwError) + const promise = sut.load(surveyId, accountId) + await expect(promise).rejects.toThrow() + }) + + test('Should call LoadSurveyByIdRepository if LoadSurveyResultRepository returns null', async () => { + const { sut, loadSurveyResultRepositorySpy, loadSurveyByIdRepositorySpy } = makeSut() + loadSurveyResultRepositorySpy.result = null + await sut.load(surveyId, accountId) + expect(loadSurveyByIdRepositorySpy.id).toBe(surveyId) + }) + + test('Should return surveyResultModel with all answers with count 0 if LoadSurveyResultRepository returns null', async () => { + const { sut, loadSurveyResultRepositorySpy, loadSurveyByIdRepositorySpy } = makeSut() + loadSurveyResultRepositorySpy.result = null + const surveyResult = await sut.load(surveyId, accountId) + const { result } = loadSurveyByIdRepositorySpy + expect(surveyResult).toEqual({ + surveyId: result.id, + question: result.question, + date: result.date, + answers: result.answers.map(answer => ({ + ...answer, + count: 0, + percent: 0, + isCurrentAccountAnswer: false + })) + }) + }) + + test('Should return surveyResultModel on success', async () => { + const { sut, loadSurveyResultRepositorySpy } = makeSut() + const surveyResult = await sut.load(surveyId, accountId) + expect(surveyResult).toEqual(loadSurveyResultRepositorySpy.result) + }) +}) diff --git a/tests/data/usecases/db-load-surveys.spec.ts b/tests/data/usecases/db-load-surveys.spec.ts new file mode 100644 index 0000000..992f73f --- /dev/null +++ b/tests/data/usecases/db-load-surveys.spec.ts @@ -0,0 +1,50 @@ +import { DbLoadSurveys } from '@/data/usecases' +import { LoadSurveysRepositorySpy } from '@/tests/data/mocks' +import { throwError } from '@/tests/domain/mocks' + +import MockDate from 'mockdate' +import { faker } from '@faker-js/faker' + +type SutTypes = { + sut: DbLoadSurveys + loadSurveysRepositorySpy: LoadSurveysRepositorySpy +} + +const makeSut = (): SutTypes => { + const loadSurveysRepositorySpy = new LoadSurveysRepositorySpy() + const sut = new DbLoadSurveys(loadSurveysRepositorySpy) + return { + sut, + loadSurveysRepositorySpy + } +} + +describe('DbLoadSurveys', () => { + beforeAll(() => { + MockDate.set(new Date()) + }) + + afterAll(() => { + MockDate.reset() + }) + + test('Should call LoadSurveysRepository', async () => { + const { sut, loadSurveysRepositorySpy } = makeSut() + const accountId = faker.datatype.uuid() + await sut.load(accountId) + expect(loadSurveysRepositorySpy.accountId).toBe(accountId) + }) + + test('Should return a list of Surveys on success', async () => { + const { sut, loadSurveysRepositorySpy } = makeSut() + const surveys = await sut.load(faker.datatype.uuid()) + expect(surveys).toEqual(loadSurveysRepositorySpy.result) + }) + + test('Should throw if LoadSurveysRepository throws', async () => { + const { sut, loadSurveysRepositorySpy } = makeSut() + jest.spyOn(loadSurveysRepositorySpy, 'loadAll').mockImplementationOnce(throwError) + const promise = sut.load(faker.datatype.uuid()) + await expect(promise).rejects.toThrow() + }) +}) diff --git a/tests/data/usecases/db-save-survey-result.spec.ts b/tests/data/usecases/db-save-survey-result.spec.ts new file mode 100644 index 0000000..e0a8c1d --- /dev/null +++ b/tests/data/usecases/db-save-survey-result.spec.ts @@ -0,0 +1,66 @@ +import { DbSaveSurveyResult } from '@/data/usecases' +import { SaveSurveyResultRepositorySpy, LoadSurveyResultRepositorySpy } from '@/tests/data/mocks' +import { throwError, mockSaveSurveyResultParams } from '@/tests/domain/mocks' + +import MockDate from 'mockdate' + +type SutTypes = { + sut: DbSaveSurveyResult + saveSurveyResultRepositorySpy: SaveSurveyResultRepositorySpy + loadSurveyResultRepositorySpy: LoadSurveyResultRepositorySpy +} + +const makeSut = (): SutTypes => { + const saveSurveyResultRepositorySpy = new SaveSurveyResultRepositorySpy() + const loadSurveyResultRepositorySpy = new LoadSurveyResultRepositorySpy() + const sut = new DbSaveSurveyResult(saveSurveyResultRepositorySpy, loadSurveyResultRepositorySpy) + return { + sut, + saveSurveyResultRepositorySpy, + loadSurveyResultRepositorySpy + } +} + +describe('DbSaveSurveyResult Usecase', () => { + beforeAll(() => { + MockDate.set(new Date()) + }) + + afterAll(() => { + MockDate.reset() + }) + + test('Should call SaveSurveyResultRepository with correct values', async () => { + const { sut, saveSurveyResultRepositorySpy } = makeSut() + const surveyResultData = mockSaveSurveyResultParams() + await sut.save(surveyResultData) + expect(saveSurveyResultRepositorySpy.params).toEqual(surveyResultData) + }) + + test('Should throw if SaveSurveyResultRepository throws', async () => { + const { sut, saveSurveyResultRepositorySpy } = makeSut() + jest.spyOn(saveSurveyResultRepositorySpy, 'save').mockImplementationOnce(throwError) + const promise = sut.save(mockSaveSurveyResultParams()) + await expect(promise).rejects.toThrow() + }) + + test('Should call LoadSurveyResultRepository with correct values', async () => { + const { sut, loadSurveyResultRepositorySpy } = makeSut() + const surveyResultData = mockSaveSurveyResultParams() + await sut.save(surveyResultData) + expect(loadSurveyResultRepositorySpy.surveyId).toBe(surveyResultData.surveyId) + }) + + test('Should throw if LoadSurveyResultRepository throws', async () => { + const { sut, loadSurveyResultRepositorySpy } = makeSut() + jest.spyOn(loadSurveyResultRepositorySpy, 'loadBySurveyId').mockImplementationOnce(throwError) + const promise = sut.save(mockSaveSurveyResultParams()) + await expect(promise).rejects.toThrow() + }) + + test('Should return SurveyResult on success', async () => { + const { sut, loadSurveyResultRepositorySpy } = makeSut() + const surveyResult = await sut.save(mockSaveSurveyResultParams()) + expect(surveyResult).toEqual(loadSurveyResultRepositorySpy.result) + }) +}) diff --git a/src/domain/test/index.ts b/tests/domain/mocks/index.ts similarity index 100% rename from src/domain/test/index.ts rename to tests/domain/mocks/index.ts index acbd5e6..055434c 100644 --- a/src/domain/test/index.ts +++ b/tests/domain/mocks/index.ts @@ -1,4 +1,4 @@ export * from './mock-account' -export * from './test-helpers' export * from './mock-survey' export * from './mock-survey-result' +export * from './test-helpers' diff --git a/tests/domain/mocks/mock-account.ts b/tests/domain/mocks/mock-account.ts new file mode 100644 index 0000000..27a74ef --- /dev/null +++ b/tests/domain/mocks/mock-account.ts @@ -0,0 +1,14 @@ +import { AddAccount, Authentication } from '@/domain/usecases' + +import { faker } from '@faker-js/faker' + +export const mockAddAccountParams = (): AddAccount.Params => ({ + name: faker.name.fullName(), + email: faker.internet.email(), + password: faker.internet.password() +}) + +export const mockAuthenticationParams = (): Authentication.Params => ({ + email: faker.internet.email(), + password: faker.internet.password() +}) diff --git a/tests/domain/mocks/mock-survey-result.ts b/tests/domain/mocks/mock-survey-result.ts new file mode 100644 index 0000000..cadf010 --- /dev/null +++ b/tests/domain/mocks/mock-survey-result.ts @@ -0,0 +1,47 @@ +import { SurveyResultModel } from '@/domain/models' +import { SaveSurveyResult } from '@/domain/usecases' + +import { faker } from '@faker-js/faker' + +export const mockSaveSurveyResultParams = (): SaveSurveyResult.Params => ({ + accountId: faker.datatype.uuid(), + surveyId: faker.datatype.uuid(), + answer: faker.random.word(), + date: faker.date.recent() +}) + +export const mockSurveyResultModel = (): SurveyResultModel => ({ + surveyId: faker.datatype.uuid(), + question: faker.random.words(), + answers: [{ + answer: faker.random.word(), + count: faker.datatype.number({ min: 0, max: 1000 }), + percent: faker.datatype.number({ min: 0, max: 100 }), + isCurrentAccountAnswer: faker.datatype.boolean() + }, { + answer: faker.random.word(), + image: faker.image.imageUrl(), + count: faker.datatype.number({ min: 0, max: 1000 }), + percent: faker.datatype.number({ min: 0, max: 100 }), + isCurrentAccountAnswer: faker.datatype.boolean() + }], + date: faker.date.recent() +}) + +export const mockEmptySurveyResultModel = (): SurveyResultModel => ({ + surveyId: faker.datatype.uuid(), + question: faker.random.words(), + answers: [{ + answer: faker.random.word(), + count: 0, + percent: 0, + isCurrentAccountAnswer: false + }, { + answer: faker.random.word(), + image: faker.image.imageUrl(), + count: 0, + percent: 0, + isCurrentAccountAnswer: false + }], + date: faker.date.recent() +}) diff --git a/tests/domain/mocks/mock-survey.ts b/tests/domain/mocks/mock-survey.ts new file mode 100644 index 0000000..f097067 --- /dev/null +++ b/tests/domain/mocks/mock-survey.ts @@ -0,0 +1,34 @@ +import { SurveyModel } from '@/domain/models' +import { AddSurvey } from '@/domain/usecases' + +import { faker } from '@faker-js/faker' + +export const mockSurveyModel = (): SurveyModel => { + return { + id: faker.datatype.uuid(), + question: faker.random.words(), + answers: [{ + answer: faker.random.word() + }, { + answer: faker.random.word(), + image: faker.image.imageUrl() + }], + date: faker.date.recent() + } +} + +export const mockSurveyModels = (): SurveyModel[] => [ + mockSurveyModel(), + mockSurveyModel() +] + +export const mockAddSurveyParams = (): AddSurvey.Params => ({ + question: faker.random.words(), + answers: [{ + image: faker.image.imageUrl(), + answer: faker.random.word() + }, { + answer: faker.random.word() + }], + date: faker.date.recent() +}) diff --git a/src/domain/test/test-helpers.ts b/tests/domain/mocks/test-helpers.ts similarity index 100% rename from src/domain/test/test-helpers.ts rename to tests/domain/mocks/test-helpers.ts diff --git a/src/infra/cryptography/bcrypt-adapter/bcrypt-adapter.spec.ts b/tests/infra/cryptography/bcrypt-adapter.spec.ts similarity index 78% rename from src/infra/cryptography/bcrypt-adapter/bcrypt-adapter.spec.ts rename to tests/infra/cryptography/bcrypt-adapter.spec.ts index 7ae5873..cdf4de1 100644 --- a/src/infra/cryptography/bcrypt-adapter/bcrypt-adapter.spec.ts +++ b/tests/infra/cryptography/bcrypt-adapter.spec.ts @@ -1,14 +1,15 @@ -import { BcryptAdapter } from './bcrypt-adapter' +import { BcryptAdapter } from '@/infra/cryptography' +import { throwError } from '@/tests/domain/mocks' + import bcrypt from 'bcrypt' -import { throwError } from '@/domain/test' jest.mock('bcrypt', () => ({ async hash (): Promise { - return await Promise.resolve('hash') + return 'hash' }, async compare (): Promise { - return await Promise.resolve(true) + return true } })) @@ -34,7 +35,7 @@ describe('Bcrypt Adapter', () => { test('Should throw if hash throws', async () => { const sut = makeSut() - jest.spyOn(bcrypt, 'hash').mockImplementationOnce(throwError) + jest.spyOn(bcrypt, 'hash').mockImplementationOnce(throwError) const promise = sut.hash('any_value') await expect(promise).rejects.toThrow() }) @@ -48,7 +49,7 @@ describe('Bcrypt Adapter', () => { expect(compareSpy).toHaveBeenCalledWith('any_value', 'any_hash') }) - test('Should return true when compare success', async () => { + test('Should return true when compare succeeds', async () => { const sut = makeSut() const isValid = await sut.compare('any_value', 'any_hash') expect(isValid).toBe(true) @@ -56,14 +57,14 @@ describe('Bcrypt Adapter', () => { test('Should return false when compare fails', async () => { const sut = makeSut() - jest.spyOn(bcrypt, 'compare').mockImplementationOnce(async () => false) + jest.spyOn(bcrypt, 'compare').mockImplementationOnce(() => false) const isValid = await sut.compare('any_value', 'any_hash') expect(isValid).toBe(false) }) test('Should throw if compare throws', async () => { const sut = makeSut() - jest.spyOn(bcrypt, 'compare').mockImplementationOnce(throwError) + jest.spyOn(bcrypt, 'compare').mockImplementationOnce(throwError) const promise = sut.compare('any_value', 'any_hash') await expect(promise).rejects.toThrow() }) diff --git a/src/infra/cryptography/jwt-adapter/jwt-adapter.spec.ts b/tests/infra/cryptography/jwt-adapter.spec.ts similarity index 62% rename from src/infra/cryptography/jwt-adapter/jwt-adapter.spec.ts rename to tests/infra/cryptography/jwt-adapter.spec.ts index e9d73e4..1ec4ea3 100644 --- a/src/infra/cryptography/jwt-adapter/jwt-adapter.spec.ts +++ b/tests/infra/cryptography/jwt-adapter.spec.ts @@ -1,13 +1,15 @@ -import { JwtAdapter } from './jwt-adapter' -import Jwt from 'jsonwebtoken' +import { JwtAdapter } from '@/infra/cryptography' +import { throwError } from '@/tests/domain/mocks' + +import jwt from 'jsonwebtoken' jest.mock('jsonwebtoken', () => ({ async sign (): Promise { - return await Promise.resolve('any_token') + return 'any_token' }, async verify (): Promise { - return await Promise.resolve('any_value') + return 'any_value' } })) @@ -19,9 +21,9 @@ describe('Jwt Adapter', () => { describe('sign()', () => { test('Should call sign with correct values', async () => { const sut = makeSut() - const signSpy = jest.spyOn(Jwt, 'sign') + const signSpy = jest.spyOn(jwt, 'sign') await sut.encrypt('any_id') - expect(signSpy).toHaveBeenLastCalledWith({ id: 'any_id' }, 'secret') + expect(signSpy).toHaveBeenCalledWith({ id: 'any_id' }, 'secret') }) test('Should return a token on sign success', async () => { @@ -30,11 +32,9 @@ describe('Jwt Adapter', () => { expect(accessToken).toBe('any_token') }) - test('Should throws if sign throws', async () => { + test('Should throw if sign throws', async () => { const sut = makeSut() - jest.spyOn(Jwt, 'sign').mockImplementationOnce(() => { - throw new Error() - }) + jest.spyOn(jwt, 'sign').mockImplementationOnce(throwError) const promise = sut.encrypt('any_id') await expect(promise).rejects.toThrow() }) @@ -43,9 +43,9 @@ describe('Jwt Adapter', () => { describe('verify()', () => { test('Should call verify with correct values', async () => { const sut = makeSut() - const verifySpy = jest.spyOn(Jwt, 'verify') + const verifySpy = jest.spyOn(jwt, 'verify') await sut.decrypt('any_token') - expect(verifySpy).toHaveBeenLastCalledWith('any_token', 'secret') + expect(verifySpy).toHaveBeenCalledWith('any_token', 'secret') }) test('Should return a value on verify success', async () => { @@ -54,11 +54,9 @@ describe('Jwt Adapter', () => { expect(value).toBe('any_value') }) - test('Should throws if verify throws', async () => { + test('Should throw if verify throws', async () => { const sut = makeSut() - jest.spyOn(Jwt, 'verify').mockImplementationOnce(() => { - throw new Error() - }) + jest.spyOn(jwt, 'verify').mockImplementationOnce(throwError) const promise = sut.decrypt('any_token') await expect(promise).rejects.toThrow() }) diff --git a/tests/infra/db/mongodb/account-mongo-repository.spec.ts b/tests/infra/db/mongodb/account-mongo-repository.spec.ts new file mode 100644 index 0000000..1776f41 --- /dev/null +++ b/tests/infra/db/mongodb/account-mongo-repository.spec.ts @@ -0,0 +1,143 @@ +import { AccountMongoRepository, MongoHelper } from '@/infra/db' +import { mockAddAccountParams } from '@/tests/domain/mocks' + +import { type Collection } from 'mongodb' +import { faker } from '@faker-js/faker' + +const makeSut = (): AccountMongoRepository => { + return new AccountMongoRepository() +} + +let accountCollection: Collection + +describe('AccountMongoRepository', () => { + beforeAll(async () => { + await MongoHelper.connect(process.env.MONGO_URL) + }) + + afterAll(async () => { + await MongoHelper.disconnect() + }) + + beforeEach(async () => { + accountCollection = MongoHelper.getCollection('accounts') + await accountCollection.deleteMany({}) + }) + + describe('add()', () => { + test('Should return an account on success', async () => { + const sut = makeSut() + const addAccountParams = mockAddAccountParams() + const isValid = await sut.add(addAccountParams) + expect(isValid).toBe(true) + }) + }) + + describe('loadByEmail()', () => { + test('Should return an account on success', async () => { + const sut = makeSut() + const addAccountParams = mockAddAccountParams() + await accountCollection.insertOne(addAccountParams) + const account = await sut.loadByEmail(addAccountParams.email) + expect(account).toBeTruthy() + expect(account.id).toBeTruthy() + expect(account.name).toBe(addAccountParams.name) + expect(account.password).toBe(addAccountParams.password) + }) + + test('Should return null if loadByEmail fails', async () => { + const sut = makeSut() + const account = await sut.loadByEmail(faker.internet.email()) + expect(account).toBeFalsy() + }) + }) + + describe('checkByEmail()', () => { + test('Should return true if email is valid', async () => { + const sut = makeSut() + const addAccountParams = mockAddAccountParams() + await accountCollection.insertOne(addAccountParams) + const exists = await sut.checkByEmail(addAccountParams.email) + expect(exists).toBe(true) + }) + + test('Should return false if email is not valid', async () => { + const sut = makeSut() + const exists = await sut.checkByEmail(faker.internet.email()) + expect(exists).toBe(false) + }) + }) + + describe('loadByToken()', () => { + let name = faker.name.fullName() + let email = faker.internet.email() + let password = faker.internet.password() + let accessToken = faker.datatype.uuid() + + beforeEach(() => { + name = faker.name.fullName() + email = faker.internet.email() + password = faker.internet.password() + accessToken = faker.datatype.uuid() + }) + + test('Should return an account on loadByToken without role', async () => { + const sut = makeSut() + await accountCollection.insertOne({ + name, + email, + password, + accessToken + }) + const account = await sut.loadByToken(accessToken) + expect(account).toBeTruthy() + expect(account.id).toBeTruthy() + }) + + test('Should return an account on loadByToken with admin role', async () => { + const sut = makeSut() + await accountCollection.insertOne({ + name, + email, + password, + accessToken, + role: 'admin' + }) + const account = await sut.loadByToken(accessToken, 'admin') + expect(account).toBeTruthy() + expect(account.id).toBeTruthy() + }) + + test('Should return null on loadByToken with invalid role', async () => { + const sut = makeSut() + await accountCollection.insertOne({ + name, + email, + password, + accessToken + }) + const account = await sut.loadByToken(accessToken, 'admin') + expect(account).toBeFalsy() + }) + + test('Should return an account on loadByToken with if user is admin', async () => { + const sut = makeSut() + await accountCollection.insertOne({ + name, + email, + password, + accessToken, + role: 'admin' + }) + const account = await sut.loadByToken(accessToken) + expect(account).toBeTruthy() + expect(account.id).toBeTruthy() + }) + + test('Should return null if loadByToken fails', async () => { + const sut = makeSut() + const account = await sut.loadByToken(accessToken) + expect(account).toBeFalsy() + }) + }) +}) diff --git a/src/infra/db/mongodb/log/log-mongo-repository.spec.ts b/tests/infra/db/mongodb/log-mongo-repository.spec.ts similarity index 72% rename from src/infra/db/mongodb/log/log-mongo-repository.spec.ts rename to tests/infra/db/mongodb/log-mongo-repository.spec.ts index ddee2ba..381be9c 100644 --- a/src/infra/db/mongodb/log/log-mongo-repository.spec.ts +++ b/tests/infra/db/mongodb/log-mongo-repository.spec.ts @@ -1,14 +1,15 @@ -import { LogMongoRepository } from './log-mongo-repository' -import { MongoHelper } from '../helpers/mongo-helper' +import { LogMongoRepository, MongoHelper } from '@/infra/db' + import { Collection } from 'mongodb' +import { faker } from '@faker-js/faker' const makeSut = (): LogMongoRepository => { return new LogMongoRepository() } -describe('log Mongo Repository', () => { - let errorCollection: Collection +let errorCollection: Collection +describe('LogMongoRepository', () => { beforeAll(async () => { await MongoHelper.connect(process.env.MONGO_URL) }) @@ -24,7 +25,7 @@ describe('log Mongo Repository', () => { test('Should create an error log on success', async () => { const sut = makeSut() - await sut.logError('any_error') + await sut.logError(faker.random.words()) const count = await errorCollection.countDocuments() expect(count).toBe(1) }) diff --git a/tests/infra/db/mongodb/survey-mongo-repository.spec.ts b/tests/infra/db/mongodb/survey-mongo-repository.spec.ts new file mode 100644 index 0000000..4490833 --- /dev/null +++ b/tests/infra/db/mongodb/survey-mongo-repository.spec.ts @@ -0,0 +1,123 @@ +import { SurveyMongoRepository, MongoHelper } from '@/infra/db' +import { mockAddSurveyParams, mockAddAccountParams } from '@/tests/domain/mocks' + +import { Collection, ObjectId } from 'mongodb' +import FakeObjectId from 'bson-objectid' + +let surveyCollection: Collection +let surveyResultCollection: Collection +let accountCollection: Collection + +const mockAccountId = async (): Promise => { + const res = await accountCollection.insertOne(mockAddAccountParams()) + return res.insertedId.toHexString() +} + +const makeSut = (): SurveyMongoRepository => { + return new SurveyMongoRepository() +} + +describe('SurveyMongoRepository', () => { + beforeAll(async () => { + await MongoHelper.connect(process.env.MONGO_URL) + }) + + afterAll(async () => { + await MongoHelper.disconnect() + }) + + beforeEach(async () => { + surveyCollection = MongoHelper.getCollection('surveys') + await surveyCollection.deleteMany({}) + surveyResultCollection = MongoHelper.getCollection('surveyResults') + await surveyResultCollection.deleteMany({}) + accountCollection = MongoHelper.getCollection('accounts') + await accountCollection.deleteMany({}) + }) + + describe('add()', () => { + test('Should add a survey on success', async () => { + const sut = makeSut() + await sut.add(mockAddSurveyParams()) + const count = await surveyCollection.countDocuments() + expect(count).toBe(1) + }) + }) + + describe('loadAll()', () => { + test('Should load all surveys on success', async () => { + const accountId = await mockAccountId() + const addSurveyModels = [mockAddSurveyParams(), mockAddSurveyParams()] + const result = await surveyCollection.insertMany(addSurveyModels) + const survey = await surveyCollection.findOne({ _id: result.insertedIds[0] }) + await surveyResultCollection.insertOne({ + surveyId: survey._id, + accountId: new ObjectId(accountId), + answer: survey.answers[0].answer, + date: new Date() + }) + const sut = makeSut() + const surveys = await sut.loadAll(accountId) + expect(surveys.length).toBe(2) + expect(surveys[0].id).toBeTruthy() + expect(surveys[0].question).toBe(addSurveyModels[0].question) + expect(surveys[0].didAnswer).toBe(true) + expect(surveys[1].question).toBe(addSurveyModels[1].question) + expect(surveys[1].didAnswer).toBe(false) + }) + + test('Should load empty list', async () => { + const accountId = await mockAccountId() + const sut = makeSut() + const surveys = await sut.loadAll(accountId) + expect(surveys.length).toBe(0) + }) + }) + + describe('loadById()', () => { + test('Should load survey by id on success', async () => { + const res = await surveyCollection.insertOne(mockAddSurveyParams()) + const sut = makeSut() + const survey = await sut.loadById(res.insertedId.toHexString()) + expect(survey).toBeTruthy() + expect(survey.id).toBeTruthy() + }) + + test('Should return null if survey does not exists', async () => { + const sut = makeSut() + const survey = await sut.loadById(new FakeObjectId().toHexString()) + expect(survey).toBeFalsy() + }) + }) + + describe('loadAnswers()', () => { + test('Should load answers on success', async () => { + const res = await surveyCollection.insertOne(mockAddSurveyParams()) + const survey = await surveyCollection.findOne({ _id: res.insertedId }) + const sut = makeSut() + const answers = await sut.loadAnswers(survey._id.toHexString()) + expect(answers).toEqual([survey.answers[0].answer, survey.answers[1].answer]) + }) + + test('Should return empty array if survey does not exists', async () => { + const sut = makeSut() + const answers = await sut.loadAnswers(new FakeObjectId().toHexString()) + expect(answers).toEqual([]) + }) + }) + + describe('checkById()', () => { + test('Should return true if survey exists', async () => { + const res = await surveyCollection.insertOne(mockAddSurveyParams()) + const sut = makeSut() + const exists = await sut.checkById(res.insertedId.toHexString()) + expect(exists).toBe(true) + }) + + test('Should return false if survey exists', async () => { + const sut = makeSut() + const exists = await sut.checkById(new FakeObjectId().toHexString()) + expect(exists).toBe(false) + }) + }) +}) diff --git a/tests/infra/db/mongodb/survey-result-mongo-repository.spec.ts b/tests/infra/db/mongodb/survey-result-mongo-repository.spec.ts new file mode 100644 index 0000000..a18037f --- /dev/null +++ b/tests/infra/db/mongodb/survey-result-mongo-repository.spec.ts @@ -0,0 +1,189 @@ +import { SurveyResultMongoRepository, MongoHelper } from '@/infra/db' +import { SurveyModel } from '@/domain/models' +import { mockAddSurveyParams, mockAddAccountParams } from '@/tests/domain/mocks' + +import { Collection, ObjectId } from 'mongodb' + +let surveyCollection: Collection +let surveyResultCollection: Collection +let accountCollection: Collection + +const makeSut = (): SurveyResultMongoRepository => { + return new SurveyResultMongoRepository() +} + +const mockSurvey = async (): Promise => { + const res = await surveyCollection.insertOne(mockAddSurveyParams()) + const survey = await surveyCollection.findOne({ _id: res.insertedId }) + return MongoHelper.map(survey) +} + +const mockAccountId = async (): Promise => { + const res = await accountCollection.insertOne(mockAddAccountParams()) + return res.insertedId.toHexString() +} + +describe('SurveyMongoRepository', () => { + beforeAll(async () => { + await MongoHelper.connect(process.env.MONGO_URL) + }) + + afterAll(async () => { + await MongoHelper.disconnect() + }) + + beforeEach(async () => { + surveyCollection = MongoHelper.getCollection('surveys') + await surveyCollection.deleteMany({}) + surveyResultCollection = MongoHelper.getCollection('surveyResults') + await surveyResultCollection.deleteMany({}) + accountCollection = MongoHelper.getCollection('accounts') + await accountCollection.deleteMany({}) + }) + + describe('save()', () => { + test('Should add a survey result if its new', async () => { + const survey = await mockSurvey() + const accountId = await mockAccountId() + const sut = makeSut() + await sut.save({ + surveyId: survey.id, + accountId, + answer: survey.answers[0].answer, + date: new Date() + }) + const surveyResult = await surveyResultCollection.findOne({ + surveyId: new ObjectId(survey.id), + accountId: new ObjectId(accountId) + }) + expect(surveyResult).toBeTruthy() + }) + + test('Should update survey result if its not new', async () => { + const survey = await mockSurvey() + const accountId = await mockAccountId() + await surveyResultCollection.insertOne({ + surveyId: new ObjectId(survey.id), + accountId: new ObjectId(accountId), + answer: survey.answers[0].answer, + date: new Date() + }) + const sut = makeSut() + await sut.save({ + surveyId: survey.id, + accountId, + answer: survey.answers[1].answer, + date: new Date() + }) + const surveyResult = await surveyResultCollection + .find({ + surveyId: new ObjectId(survey.id), + accountId: new ObjectId(accountId) + }) + .toArray() + expect(surveyResult).toBeTruthy() + expect(surveyResult.length).toBe(1) + }) + }) + + describe('loadBySurveyId()', () => { + test('Should load survey result', async () => { + const survey = await mockSurvey() + const accountId = await mockAccountId() + const accountId2 = await mockAccountId() + await surveyResultCollection.insertMany([{ + surveyId: new ObjectId(survey.id), + accountId: new ObjectId(accountId2), + answer: survey.answers[0].answer, + date: new Date() + }, { + surveyId: new ObjectId(survey.id), + accountId: new ObjectId(accountId), + answer: survey.answers[0].answer, + date: new Date() + }]) + const sut = makeSut() + const surveyResult = await sut.loadBySurveyId(survey.id, accountId) + expect(surveyResult).toBeTruthy() + expect(surveyResult.surveyId).toEqual(survey.id) + expect(surveyResult.answers[0].count).toBe(2) + expect(surveyResult.answers[0].percent).toBe(100) + expect(surveyResult.answers[0].isCurrentAccountAnswer).toBe(true) + expect(surveyResult.answers[1].count).toBe(0) + expect(surveyResult.answers[1].percent).toBe(0) + expect(surveyResult.answers[1].isCurrentAccountAnswer).toBe(false) + expect(surveyResult.answers.length).toBe(survey.answers.length) + }) + + test('Should load survey result 2', async () => { + const survey = await mockSurvey() + const accountId = await mockAccountId() + const accountId2 = await mockAccountId() + const accountId3 = await mockAccountId() + await surveyResultCollection.insertMany([{ + surveyId: new ObjectId(survey.id), + accountId: new ObjectId(accountId), + answer: survey.answers[0].answer, + date: new Date() + }, { + surveyId: new ObjectId(survey.id), + accountId: new ObjectId(accountId2), + answer: survey.answers[1].answer, + date: new Date() + }, { + surveyId: new ObjectId(survey.id), + accountId: new ObjectId(accountId3), + answer: survey.answers[1].answer, + date: new Date() + }]) + const sut = makeSut() + const surveyResult = await sut.loadBySurveyId(survey.id, accountId2) + expect(surveyResult).toBeTruthy() + expect(surveyResult.surveyId).toEqual(survey.id) + expect(surveyResult.answers[0].count).toBe(2) + expect(surveyResult.answers[0].percent).toBe(67) + expect(surveyResult.answers[0].isCurrentAccountAnswer).toBe(true) + expect(surveyResult.answers[1].count).toBe(1) + expect(surveyResult.answers[1].percent).toBe(33) + expect(surveyResult.answers[1].isCurrentAccountAnswer).toBe(false) + expect(surveyResult.answers.length).toBe(survey.answers.length) + }) + + test('Should load survey result 3', async () => { + const survey = await mockSurvey() + const accountId = await mockAccountId() + const accountId2 = await mockAccountId() + const accountId3 = await mockAccountId() + await surveyResultCollection.insertMany([{ + surveyId: new ObjectId(survey.id), + accountId: new ObjectId(accountId), + answer: survey.answers[0].answer, + date: new Date() + }, { + surveyId: new ObjectId(survey.id), + accountId: new ObjectId(accountId2), + answer: survey.answers[1].answer, + date: new Date() + }]) + const sut = makeSut() + const surveyResult = await sut.loadBySurveyId(survey.id, accountId3) + expect(surveyResult).toBeTruthy() + expect(surveyResult.surveyId).toEqual(survey.id) + expect(surveyResult.answers[0].count).toBe(1) + expect(surveyResult.answers[0].percent).toBe(50) + expect(surveyResult.answers[0].isCurrentAccountAnswer).toBe(false) + expect(surveyResult.answers[1].count).toBe(1) + expect(surveyResult.answers[1].percent).toBe(50) + expect(surveyResult.answers[1].isCurrentAccountAnswer).toBe(false) + expect(surveyResult.answers.length).toBe(survey.answers.length) + }) + + test('Should return null if there is no survey result', async () => { + const survey = await mockSurvey() + const accountId = await mockAccountId() + const sut = makeSut() + const surveyResult = await sut.loadBySurveyId(survey.id, accountId) + expect(surveyResult).toBeNull() + }) + }) +}) diff --git a/src/infra/validators/email-validator-adapter.spec.ts b/tests/infra/validators/email-validator-adapter.spec.ts similarity index 83% rename from src/infra/validators/email-validator-adapter.spec.ts rename to tests/infra/validators/email-validator-adapter.spec.ts index c633a3b..2c0b67e 100644 --- a/src/infra/validators/email-validator-adapter.spec.ts +++ b/tests/infra/validators/email-validator-adapter.spec.ts @@ -1,4 +1,5 @@ -import { EmailValidatorAdapter } from './email-validator-adapter' +import { EmailValidatorAdapter } from '@/infra/validators' + import validator from 'validator' jest.mock('validator', () => ({ @@ -11,7 +12,7 @@ const makeSut = (): EmailValidatorAdapter => { return new EmailValidatorAdapter() } -describe('EmailValidator Adapter', () => { +describe('EmailValidatorAdapter', () => { test('Should return false if validator returns false', () => { const sut = makeSut() jest.spyOn(validator, 'isEmail').mockReturnValueOnce(false) @@ -21,7 +22,7 @@ describe('EmailValidator Adapter', () => { test('Should return true if validator returns true', () => { const sut = makeSut() - const isValid = sut.isValid('any_email@mail.com') + const isValid = sut.isValid('valid_email@mail.com') expect(isValid).toBe(true) }) diff --git a/tests/main/decorators/log-controller-decorator.spec.ts b/tests/main/decorators/log-controller-decorator.spec.ts new file mode 100644 index 0000000..5dc0511 --- /dev/null +++ b/tests/main/decorators/log-controller-decorator.spec.ts @@ -0,0 +1,62 @@ +import { LogControllerDecorator } from '@/main/decorators' +import { Controller, HttpResponse } from '@/presentation/protocols' +import { serverError, ok } from '@/presentation/helpers' +import { LogErrorRepositorySpy } from '@/tests/data/mocks' + +import { faker } from '@faker-js/faker' + +class ControllerSpy implements Controller { + httpResponse = ok(faker.datatype.uuid()) + request: any + + async handle (request: any): Promise { + this.request = request + return this.httpResponse + } +} + +const mockServerError = (): HttpResponse => { + const fakeError = new Error() + fakeError.stack = 'any_stack' + return serverError(fakeError) +} + +type SutTypes = { + sut: LogControllerDecorator + controllerSpy: ControllerSpy + logErrorRepositorySpy: LogErrorRepositorySpy +} + +const makeSut = (): SutTypes => { + const controllerSpy = new ControllerSpy() + const logErrorRepositorySpy = new LogErrorRepositorySpy() + const sut = new LogControllerDecorator(controllerSpy, logErrorRepositorySpy) + return { + sut, + controllerSpy, + logErrorRepositorySpy + } +} + +describe('LogController Decorator', () => { + test('Should call controller handle', async () => { + const { sut, controllerSpy } = makeSut() + const request = faker.lorem.sentence() + await sut.handle(request) + expect(controllerSpy.request).toEqual(request) + }) + + test('Should return the same result of the controller', async () => { + const { sut, controllerSpy } = makeSut() + const httpResponse = await sut.handle(faker.lorem.sentence()) + expect(httpResponse).toEqual(controllerSpy.httpResponse) + }) + + test('Should call LogErrorRepository with correct error if controller returns a server error', async () => { + const { sut, controllerSpy, logErrorRepositorySpy } = makeSut() + const serverError = mockServerError() + controllerSpy.httpResponse = serverError + await sut.handle(faker.lorem.sentence()) + expect(logErrorRepositorySpy.stack).toBe(serverError.body.stack) + }) +}) diff --git a/src/main/factories/controllers/survey/add-survey/add-survey-validation-factory.spec.ts b/tests/main/factories/add-survey-validation-factory.spec.ts similarity index 68% rename from src/main/factories/controllers/survey/add-survey/add-survey-validation-factory.spec.ts rename to tests/main/factories/add-survey-validation-factory.spec.ts index 5823506..e221134 100644 --- a/src/main/factories/controllers/survey/add-survey/add-survey-validation-factory.spec.ts +++ b/tests/main/factories/add-survey-validation-factory.spec.ts @@ -1,8 +1,8 @@ -import { makeAddSurveyValidation } from './add-survey-validation-factory' +import { makeAddSurveyValidation } from '@/main/factories' +import { ValidationComposite, RequiredFieldValidation } from '@/validation/validators' import { Validation } from '@/presentation/protocols' -import { RequiredFieldValidation, ValidationComposite } from '@/validation/validators' -jest.mock('../../../../../validation/validators/validation-composite') +jest.mock('@/validation/validators/validation-composite') describe('AddSurveyValidation Factory', () => { test('Should call ValidationComposite with all validations', () => { diff --git a/tests/main/factories/login-validation-factory.spec.ts b/tests/main/factories/login-validation-factory.spec.ts new file mode 100644 index 0000000..24a488f --- /dev/null +++ b/tests/main/factories/login-validation-factory.spec.ts @@ -0,0 +1,18 @@ +import { makeLoginValidation } from '@/main/factories' +import { ValidationComposite, RequiredFieldValidation, EmailValidation } from '@/validation/validators' +import type { Validation } from '@/presentation/protocols' +import { EmailValidatorAdapter } from '@/infra/validators' + +jest.mock('@/validation/validators/validation-composite') + +describe('LoginValidation Factory', () => { + test('Should call ValidationComposite with all validations', () => { + makeLoginValidation() + const validations: Validation[] = [] + for (const field of ['email', 'password']) { + validations.push(new RequiredFieldValidation(field)) + } + validations.push(new EmailValidation('email', new EmailValidatorAdapter())) + expect(ValidationComposite).toHaveBeenCalledWith(validations) + }) +}) diff --git a/src/main/factories/controllers/login/signup/signup-validation-factory.spec.ts b/tests/main/factories/signup-validation-factory.spec.ts similarity index 50% rename from src/main/factories/controllers/login/signup/signup-validation-factory.spec.ts rename to tests/main/factories/signup-validation-factory.spec.ts index b341ef1..50c0ef9 100644 --- a/src/main/factories/controllers/login/signup/signup-validation-factory.spec.ts +++ b/tests/main/factories/signup-validation-factory.spec.ts @@ -1,28 +1,19 @@ -import { makeSignupValidation } from './signup-validation-factory' +import { makeSignUpValidation } from '@/main/factories' import { ValidationComposite, RequiredFieldValidation, CompareFieldsValidation, EmailValidation } from '@/validation/validators' -import { Validation } from '@/presentation/protocols/validation' -import { EmailValidator } from '@/validation/protocols/email-validator' +import { Validation } from '@/presentation/protocols' +import { EmailValidatorAdapter } from '@/infra/validators' -jest.mock('../../../../../validation/validators/validation-composite') - -const makeEmailValidator = (): EmailValidator => { - class EmailValidatorStub implements EmailValidator { - isValid (email: string): boolean { - return true - } - } - return new EmailValidatorStub() -} +jest.mock('@/validation/validators/validation-composite') describe('SignUpValidation Factory', () => { test('Should call ValidationComposite with all validations', () => { - makeSignupValidation() + makeSignUpValidation() const validations: Validation[] = [] for (const field of ['name', 'email', 'password', 'passwordConfirmation']) { validations.push(new RequiredFieldValidation(field)) } validations.push(new CompareFieldsValidation('password', 'passwordConfirmation')) - validations.push(new EmailValidation('email', makeEmailValidator())) + validations.push(new EmailValidation('email', new EmailValidatorAdapter())) expect(ValidationComposite).toHaveBeenCalledWith(validations) }) }) diff --git a/tests/main/graphql/login.test.ts b/tests/main/graphql/login.test.ts new file mode 100644 index 0000000..887b862 --- /dev/null +++ b/tests/main/graphql/login.test.ts @@ -0,0 +1,92 @@ +import { MongoHelper } from '@/infra/db' +import { setupApp } from '@/main/config/app' + +import { Collection } from 'mongodb' +import { hash } from 'bcrypt' +import { Express } from 'express' +import request from 'supertest' + +let accountCollection: Collection +let app: Express + +describe('Login GraphQL', () => { + beforeAll(async () => { + app = await setupApp() + await MongoHelper.connect(process.env.MONGO_URL) + }) + + afterAll(async () => { + await MongoHelper.disconnect() + }) + + beforeEach(async () => { + accountCollection = MongoHelper.getCollection('accounts') + await accountCollection.deleteMany({}) + }) + + describe('Login Query', () => { + const query = `query { + login (email: "rodrigo.manguinho@gmail.com", password: "123") { + accessToken + name + } + }` + + test('Should return an Account on valid credentials', async () => { + const password = await hash('123', 12) + await accountCollection.insertOne({ + name: 'Rodrigo', + email: 'rodrigo.manguinho@gmail.com', + password + }) + const res = await request(app) + .post('/graphql') + .send({ query }) + expect(res.status).toBe(200) + expect(res.body.data.login.accessToken).toBeTruthy() + expect(res.body.data.login.name).toBe('Rodrigo') + }) + + test('Should return UnauthorizedError on invalid credentials', async () => { + const res = await request(app) + .post('/graphql') + .send({ query }) + expect(res.status).toBe(401) + expect(res.body.data).toBeFalsy() + expect(res.body.errors[0].message).toBe('Unauthorized') + }) + }) + + describe('SignUp Mutation', () => { + const query = `mutation { + signUp (name: "Rodrigo", email: "rodrigo.manguinho@gmail.com", password: "123", passwordConfirmation: "123") { + accessToken + name + } + }` + + test('Should return an Account on valid data', async () => { + const res = await request(app) + .post('/graphql') + .send({ query }) + expect(res.status).toBe(200) + expect(res.body.data.signUp.accessToken).toBeTruthy() + expect(res.body.data.signUp.name).toBe('Rodrigo') + }) + + test('Should return EmailInUseError on invalid data', async () => { + const password = await hash('123', 12) + await accountCollection.insertOne({ + name: 'Rodrigo', + email: 'rodrigo.manguinho@gmail.com', + password + }) + const res = await request(app) + .post('/graphql') + .send({ query }) + expect(res.status).toBe(403) + expect(res.body.data).toBeFalsy() + expect(res.body.errors[0].message).toBe('The received email is already in use') + }) + }) +}) diff --git a/tests/main/graphql/survey-result.test.ts b/tests/main/graphql/survey-result.test.ts new file mode 100644 index 0000000..2a14864 --- /dev/null +++ b/tests/main/graphql/survey-result.test.ts @@ -0,0 +1,205 @@ +import { MongoHelper } from '@/infra/db' +import env from '@/main/config/env' +import { setupApp } from '@/main/config/app' + +import { Collection } from 'mongodb' +import { sign } from 'jsonwebtoken' +import { Express } from 'express' +import request from 'supertest' + +let surveyCollection: Collection +let accountCollection: Collection +let app: Express + +const mockAccessToken = async (): Promise => { + const res = await accountCollection.insertOne({ + name: 'Rodrigo', + email: 'rodrigo.manguinho@gmail.com', + password: '123', + role: 'admin' + }) + const id = res.insertedId.toHexString() + const accessToken = sign({ id }, env.jwtSecret) + await accountCollection.updateOne({ + _id: res.insertedId + }, { + $set: { + accessToken + } + }) + return accessToken +} + +describe('SurveyResult GraphQL', () => { + beforeAll(async () => { + app = await setupApp() + await MongoHelper.connect(process.env.MONGO_URL) + }) + + afterAll(async () => { + await MongoHelper.disconnect() + }) + + beforeEach(async () => { + surveyCollection = MongoHelper.getCollection('surveys') + await surveyCollection.deleteMany({}) + accountCollection = MongoHelper.getCollection('accounts') + await accountCollection.deleteMany({}) + }) + + describe('SurveyResult Query', () => { + test('Should return SurveyResult', async () => { + const accessToken = await mockAccessToken() + const now = new Date() + const surveyRes = await surveyCollection.insertOne({ + question: 'Question', + answers: [{ + answer: 'Answer 1', + image: 'http://image-name.com' + }, { + answer: 'Answer 2' + }], + date: now + }) + const query = `query { + surveyResult (surveyId: "${surveyRes.insertedId.toHexString()}") { + question + answers { + answer + count + percent + isCurrentAccountAnswer + } + date + } + }` + const res = await request(app) + .post('/graphql') + .set('x-access-token', accessToken) + .send({ query }) + expect(res.status).toBe(200) + expect(res.body.data.surveyResult.question).toBe('Question') + expect(res.body.data.surveyResult.date).toBe(now.toISOString()) + expect(res.body.data.surveyResult.answers).toEqual([{ + answer: 'Answer 1', + count: 0, + percent: 0, + isCurrentAccountAnswer: false + }, { + answer: 'Answer 2', + count: 0, + percent: 0, + isCurrentAccountAnswer: false + }]) + }) + + test('Should return AccessDeniedError if no token is provided', async () => { + const surveyRes = await surveyCollection.insertOne({ + question: 'Question', + answers: [{ + answer: 'Answer 1', + image: 'http://image-name.com' + }, { + answer: 'Answer 2' + }], + date: new Date() + }) + const query = `query { + surveyResult (surveyId: "${surveyRes.insertedId.toHexString()}") { + question + answers { + answer + count + percent + isCurrentAccountAnswer + } + date + } + }` + const res = await request(app) + .post('/graphql') + .send({ query }) + expect(res.status).toBe(403) + expect(res.body.data).toBeFalsy() + expect(res.body.errors[0].message).toBe('Access denied') + }) + }) + + describe('SaveSurveyResult Mutation', () => { + test('Should return SurveyResult', async () => { + const accessToken = await mockAccessToken() + const now = new Date() + const surveyRes = await surveyCollection.insertOne({ + question: 'Question', + answers: [{ + answer: 'Answer 1', + image: 'http://image-name.com' + }, { + answer: 'Answer 2' + }], + date: now + }) + const query = `mutation { + saveSurveyResult (surveyId: "${surveyRes.insertedId.toHexString()}", answer: "Answer 1") { + question + answers { + answer + count + percent + isCurrentAccountAnswer + } + date + } + }` + const res = await request(app) + .post('/graphql') + .set('x-access-token', accessToken) + .send({ query }) + expect(res.status).toBe(200) + expect(res.body.data.saveSurveyResult.question).toBe('Question') + expect(res.body.data.saveSurveyResult.date).toBe(now.toISOString()) + expect(res.body.data.saveSurveyResult.answers).toEqual([{ + answer: 'Answer 1', + count: 1, + percent: 100, + isCurrentAccountAnswer: true + }, { + answer: 'Answer 2', + count: 0, + percent: 0, + isCurrentAccountAnswer: false + }]) + }) + + test('Should return AccessDeniedError if no token is provided', async () => { + const surveyRes = await surveyCollection.insertOne({ + question: 'Question', + answers: [{ + answer: 'Answer 1', + image: 'http://image-name.com' + }, { + answer: 'Answer 2' + }], + date: new Date() + }) + const query = `mutation { + saveSurveyResult (surveyId: "${surveyRes.insertedId.toHexString()}", answer: "Answer 1") { + question + answers { + answer + count + percent + isCurrentAccountAnswer + } + date + } + }` + const res = await request(app) + .post('/graphql') + .send({ query }) + expect(res.status).toBe(403) + expect(res.body.data).toBeFalsy() + expect(res.body.errors[0].message).toBe('Access denied') + }) + }) +}) diff --git a/tests/main/graphql/survey.test.ts b/tests/main/graphql/survey.test.ts new file mode 100644 index 0000000..ac42620 --- /dev/null +++ b/tests/main/graphql/survey.test.ts @@ -0,0 +1,115 @@ +import { MongoHelper } from '@/infra/db' +import env from '@/main/config/env' +import { setupApp } from '@/main/config/app' + +import { Collection } from 'mongodb' +import { sign } from 'jsonwebtoken' +import { Express } from 'express' +import request from 'supertest' + +let surveyCollection: Collection +let accountCollection: Collection +let app: Express + +const mockAccessToken = async (): Promise => { + const res = await accountCollection.insertOne({ + name: 'Rodrigo', + email: 'rodrigo.manguinho@gmail.com', + password: '123', + role: 'admin' + }) + const id = res.insertedId.toHexString() + const accessToken = sign({ id }, env.jwtSecret) + await accountCollection.updateOne({ + _id: res.insertedId + }, { + $set: { + accessToken + } + }) + return accessToken +} + +describe('Survey GraphQL', () => { + beforeAll(async () => { + app = await setupApp() + await MongoHelper.connect(process.env.MONGO_URL) + }) + + afterAll(async () => { + await MongoHelper.disconnect() + }) + + beforeEach(async () => { + surveyCollection = MongoHelper.getCollection('surveys') + await surveyCollection.deleteMany({}) + accountCollection = MongoHelper.getCollection('accounts') + await accountCollection.deleteMany({}) + }) + + describe('Surveys Query', () => { + const query = `query { + surveys { + id + question + answers { + image + answer + } + date + didAnswer + } + }` + + test('Should return Surveys', async () => { + const accessToken = await mockAccessToken() + const now = new Date() + await surveyCollection.insertOne({ + question: 'Question', + answers: [{ + answer: 'Answer 1', + image: 'http://image-name.com' + }, { + answer: 'Answer 2' + }], + date: now + }) + const res = await request(app) + .post('/graphql') + .set('x-access-token', accessToken) + .send({ query }) + expect(res.status).toBe(200) + expect(res.body.data.surveys.length).toBe(1) + expect(res.body.data.surveys[0].id).toBeTruthy() + expect(res.body.data.surveys[0].question).toBe('Question') + expect(res.body.data.surveys[0].date).toBe(now.toISOString()) + expect(res.body.data.surveys[0].didAnswer).toBe(false) + expect(res.body.data.surveys[0].answers).toEqual([{ + answer: 'Answer 1', + image: 'http://image-name.com' + }, { + answer: 'Answer 2', + image: null + }]) + }) + + test('Should return AccessDeniedError if no token is provided', async () => { + await surveyCollection.insertOne({ + question: 'Question', + answers: [{ + answer: 'Answer 1', + image: 'http://image-name.com' + }, { + answer: 'Answer 2' + }], + date: new Date() + }) + const res = await request(app) + .post('/graphql') + .send({ query }) + expect(res.status).toBe(403) + expect(res.body.data).toBeFalsy() + expect(res.body.errors[0].message).toBe('Access denied') + }) + }) +}) diff --git a/src/main/middlewares/body-parser.test.ts b/tests/main/middlewares/body-parser.test.ts similarity index 54% rename from src/main/middlewares/body-parser.test.ts rename to tests/main/middlewares/body-parser.test.ts index 21ebe3c..102e1c8 100644 --- a/src/main/middlewares/body-parser.test.ts +++ b/tests/main/middlewares/body-parser.test.ts @@ -1,14 +1,22 @@ +import { setupApp } from '@/main/config/app' + +import { Express } from 'express' import request from 'supertest' -import app from '../config/app' + +let app: Express describe('Body Parser Middleware', () => { + beforeAll(async () => { + app = await setupApp() + }) + test('Should parse body as json', async () => { app.post('/test_body_parser', (req, res) => { res.send(req.body) }) await request(app) .post('/test_body_parser') - .send({ name: 'Beto' }) - .expect({ name: 'Beto' }) + .send({ name: 'Rodrigo' }) + .expect({ name: 'Rodrigo' }) }) }) diff --git a/src/main/middlewares/content-type.test.ts b/tests/main/middlewares/content-type.test.ts similarity index 73% rename from src/main/middlewares/content-type.test.ts rename to tests/main/middlewares/content-type.test.ts index b44cfcf..aad878b 100644 --- a/src/main/middlewares/content-type.test.ts +++ b/tests/main/middlewares/content-type.test.ts @@ -1,7 +1,15 @@ +import { setupApp } from '@/main/config/app' + +import { Express } from 'express' import request from 'supertest' -import app from '../config/app' -describe('Content type Middleware', () => { +let app: Express + +describe('Content Type Middleware', () => { + beforeAll(async () => { + app = await setupApp() + }) + test('Should return default content type as json', async () => { app.get('/test_content_type', (req, res) => { res.send('') diff --git a/src/main/middlewares/cors.test.ts b/tests/main/middlewares/cors.test.ts similarity index 71% rename from src/main/middlewares/cors.test.ts rename to tests/main/middlewares/cors.test.ts index 0ce8569..89e1eda 100644 --- a/src/main/middlewares/cors.test.ts +++ b/tests/main/middlewares/cors.test.ts @@ -1,7 +1,15 @@ +import { setupApp } from '@/main/config/app' + +import { Express } from 'express' import request from 'supertest' -import app from '../config/app' + +let app: Express describe('CORS Middleware', () => { + beforeAll(async () => { + app = await setupApp() + }) + test('Should enable CORS', async () => { app.get('/test_cors', (req, res) => { res.send() diff --git a/src/main/middlewares/no-cache.test.ts b/tests/main/middlewares/no-cache.test.ts similarity index 69% rename from src/main/middlewares/no-cache.test.ts rename to tests/main/middlewares/no-cache.test.ts index c422f81..58ec8a8 100644 --- a/src/main/middlewares/no-cache.test.ts +++ b/tests/main/middlewares/no-cache.test.ts @@ -1,8 +1,16 @@ +import { setupApp } from '@/main/config/app' +import { noCache } from '@/main/middlewares' + +import { Express } from 'express' import request from 'supertest' -import { noCache } from './no-cache' -import app from '../config/app' + +let app: Express describe('NoCache Middleware', () => { + beforeAll(async () => { + app = await setupApp() + }) + test('Should disable cache', async () => { app.get('/test_no_cache', noCache, (req, res) => { res.send() diff --git a/src/main/routes/login-routes.test.ts b/tests/main/routes/login-routes.test.ts similarity index 65% rename from src/main/routes/login-routes.test.ts rename to tests/main/routes/login-routes.test.ts index dec92c5..507007e 100644 --- a/src/main/routes/login-routes.test.ts +++ b/tests/main/routes/login-routes.test.ts @@ -1,14 +1,17 @@ -import app from '../config/app' -import { MongoHelper } from '@/infra/db/mongodb/helpers/mongo-helper' +import { MongoHelper } from '@/infra/db' +import { setupApp } from '@/main/config/app' -import request from 'supertest' -import { hash } from 'bcrypt' import { Collection } from 'mongodb' +import { hash } from 'bcrypt' +import { Express } from 'express' +import request from 'supertest' let accountCollection: Collection +let app: Express describe('Login Routes', () => { beforeAll(async () => { + app = await setupApp() await MongoHelper.connect(process.env.MONGO_URL) }) @@ -26,12 +29,21 @@ describe('Login Routes', () => { await request(app) .post('/api/signup') .send({ - name: 'Gilberto', - email: 'example@gmail.com', + name: 'Rodrigo', + email: 'rodrigo.manguinho@gmail.com', password: '123', passwordConfirmation: '123' }) .expect(200) + await request(app) + .post('/api/signup') + .send({ + name: 'Rodrigo', + email: 'rodrigo.manguinho@gmail.com', + password: '123', + passwordConfirmation: '123' + }) + .expect(403) }) }) @@ -39,14 +51,14 @@ describe('Login Routes', () => { test('Should return 200 on login', async () => { const password = await hash('123', 12) await accountCollection.insertOne({ - name: 'Gilberto', - email: 'example@gmail.com', + name: 'Rodrigo', + email: 'rodrigo.manguinho@gmail.com', password }) await request(app) .post('/api/login') .send({ - email: 'example@gmail.com', + email: 'rodrigo.manguinho@gmail.com', password: '123' }) .expect(200) @@ -56,7 +68,7 @@ describe('Login Routes', () => { await request(app) .post('/api/login') .send({ - email: 'example@gmail.com', + email: 'rodrigo.manguinho@gmail.com', password: '123' }) .expect(401) diff --git a/src/main/routes/survey-result-routes.test.ts b/tests/main/routes/survey-result-routes.test.ts similarity index 89% rename from src/main/routes/survey-result-routes.test.ts rename to tests/main/routes/survey-result-routes.test.ts index f39c590..1f7ff22 100644 --- a/src/main/routes/survey-result-routes.test.ts +++ b/tests/main/routes/survey-result-routes.test.ts @@ -1,18 +1,20 @@ -import app from '../config/app' -import env from '../config/env' -import { MongoHelper } from '@/infra/db/mongodb/helpers/mongo-helper' +import env from '@/main/config/env' +import { MongoHelper } from '@/infra/db' +import { setupApp } from '@/main/config/app' import { sign } from 'jsonwebtoken' import { Collection } from 'mongodb' +import { Express } from 'express' import request from 'supertest' let surveyCollection: Collection let accountCollection: Collection +let app: Express const mockAccessToken = async (): Promise => { const res = await accountCollection.insertOne({ - name: 'Beto', - email: 'example@gmail.com', + name: 'Rodrigo', + email: 'rodrigo.manguinho@gmail.com', password: '123' }) const id = res.insertedId.toHexString() @@ -27,8 +29,9 @@ const mockAccessToken = async (): Promise => { return accessToken } -describe('Survey Result Routes', () => { +describe('Survey Routes', () => { beforeAll(async () => { + app = await setupApp() await MongoHelper.connect(process.env.MONGO_URL) }) diff --git a/src/main/routes/survey-routes.test.ts b/tests/main/routes/survey-routes.test.ts similarity index 88% rename from src/main/routes/survey-routes.test.ts rename to tests/main/routes/survey-routes.test.ts index dbea2e3..cc3a338 100644 --- a/src/main/routes/survey-routes.test.ts +++ b/tests/main/routes/survey-routes.test.ts @@ -1,22 +1,24 @@ -import app from '../config/app' -import env from '../config/env' -import { MongoHelper } from '@/infra/db/mongodb/helpers/mongo-helper' +import env from '@/main/config/env' +import { MongoHelper } from '@/infra/db' +import { setupApp } from '@/main/config/app' import { sign } from 'jsonwebtoken' import { Collection } from 'mongodb' +import { Express } from 'express' import request from 'supertest' let surveyCollection: Collection let accountCollection: Collection +let app: Express const mockAccessToken = async (): Promise => { const res = await accountCollection.insertOne({ - name: 'Beto', - email: 'example@gmail.com', + name: 'Rodrigo', + email: 'rodrigo.manguinho@gmail.com', password: '123', role: 'admin' }) - const id = res.insertedId.toString() + const id = res.insertedId.toHexString() const accessToken = sign({ id }, env.jwtSecret) await accountCollection.updateOne({ _id: res.insertedId @@ -30,6 +32,7 @@ const mockAccessToken = async (): Promise => { describe('Survey Routes', () => { beforeAll(async () => { + app = await setupApp() await MongoHelper.connect(process.env.MONGO_URL) }) diff --git a/tests/presentation/controllers/add-survey-controller.spec.ts b/tests/presentation/controllers/add-survey-controller.spec.ts new file mode 100644 index 0000000..6ab3788 --- /dev/null +++ b/tests/presentation/controllers/add-survey-controller.spec.ts @@ -0,0 +1,76 @@ +import { AddSurveyController } from '@/presentation/controllers' +import { badRequest, serverError, noContent } from '@/presentation/helpers' +import { ValidationSpy, AddSurveySpy } from '@/tests/presentation/mocks' +import { throwError } from '@/tests/domain/mocks' + +import MockDate from 'mockdate' +import { faker } from '@faker-js/faker' + +const mockRequest = (): AddSurveyController.Request => ({ + question: faker.random.words(), + answers: [{ + image: faker.image.imageUrl(), + answer: faker.random.word() + }] +}) + +type SutTypes = { + sut: AddSurveyController + validationSpy: ValidationSpy + addSurveySpy: AddSurveySpy +} + +const makeSut = (): SutTypes => { + const validationSpy = new ValidationSpy() + const addSurveySpy = new AddSurveySpy() + const sut = new AddSurveyController(validationSpy, addSurveySpy) + return { + sut, + validationSpy, + addSurveySpy + } +} + +describe('AddSurvey Controller', () => { + beforeAll(() => { + MockDate.set(new Date()) + }) + + afterAll(() => { + MockDate.reset() + }) + + test('Should call Validation with correct values', async () => { + const { sut, validationSpy } = makeSut() + const request = mockRequest() + await sut.handle(request) + expect(validationSpy.input).toEqual(request) + }) + + test('Should return 400 if Validation fails', async () => { + const { sut, validationSpy } = makeSut() + validationSpy.error = new Error() + const httpResponse = await sut.handle(mockRequest()) + expect(httpResponse).toEqual(badRequest(validationSpy.error)) + }) + + test('Should call AddSurvey with correct values', async () => { + const { sut, addSurveySpy } = makeSut() + const request = mockRequest() + await sut.handle(request) + expect(addSurveySpy.params).toEqual({ ...request, date: new Date() }) + }) + + test('Should return 500 if AddSurvey throws', async () => { + const { sut, addSurveySpy } = makeSut() + jest.spyOn(addSurveySpy, 'add').mockImplementationOnce(throwError) + const httpResponse = await sut.handle(mockRequest()) + expect(httpResponse).toEqual(serverError(new Error())) + }) + + test('Should return 204 on success', async () => { + const { sut } = makeSut() + const httpResponse = await sut.handle(mockRequest()) + expect(httpResponse).toEqual(noContent()) + }) +}) diff --git a/tests/presentation/controllers/load-survey-result-controller.spec.ts b/tests/presentation/controllers/load-survey-result-controller.spec.ts new file mode 100644 index 0000000..d2fedc7 --- /dev/null +++ b/tests/presentation/controllers/load-survey-result-controller.spec.ts @@ -0,0 +1,82 @@ +import { LoadSurveyResultController } from '@/presentation/controllers' +import { forbidden, serverError, ok } from '@/presentation/helpers' +import { InvalidParamError } from '@/presentation/errors' +import { CheckSurveyByIdSpy, LoadSurveyResultSpy } from '@/tests/presentation/mocks' +import { throwError } from '@/tests/domain/mocks' + +import MockDate from 'mockdate' +import { faker } from '@faker-js/faker' + +const mockRequest = (): LoadSurveyResultController.Request => ({ + accountId: faker.datatype.uuid(), + surveyId: faker.datatype.uuid() +}) + +type SutTypes = { + sut: LoadSurveyResultController + checkSurveyByIdSpy: CheckSurveyByIdSpy + loadSurveyResultSpy: LoadSurveyResultSpy +} + +const makeSut = (): SutTypes => { + const checkSurveyByIdSpy = new CheckSurveyByIdSpy() + const loadSurveyResultSpy = new LoadSurveyResultSpy() + const sut = new LoadSurveyResultController(checkSurveyByIdSpy, loadSurveyResultSpy) + return { + sut, + checkSurveyByIdSpy, + loadSurveyResultSpy + } +} + +describe('LoadSurveyResult Controller', () => { + beforeAll(() => { + MockDate.set(new Date()) + }) + + afterAll(() => { + MockDate.reset() + }) + + test('Should call CheckSurveyById with correct value', async () => { + const { sut, checkSurveyByIdSpy } = makeSut() + const request = mockRequest() + await sut.handle(request) + expect(checkSurveyByIdSpy.id).toBe(request.surveyId) + }) + + test('Should return 403 if CheckSurveyById returns false', async () => { + const { sut, checkSurveyByIdSpy } = makeSut() + checkSurveyByIdSpy.result = false + const httpResponse = await sut.handle(mockRequest()) + expect(httpResponse).toEqual(forbidden(new InvalidParamError('surveyId'))) + }) + + test('Should return 500 if CheckSurveyById throws', async () => { + const { sut, checkSurveyByIdSpy } = makeSut() + jest.spyOn(checkSurveyByIdSpy, 'checkById').mockImplementationOnce(throwError) + const httpResponse = await sut.handle(mockRequest()) + expect(httpResponse).toEqual(serverError(new Error())) + }) + + test('Should call LoadSurveyResult with correct values', async () => { + const { sut, loadSurveyResultSpy } = makeSut() + const request = mockRequest() + await sut.handle(request) + expect(loadSurveyResultSpy.surveyId).toBe(request.surveyId) + expect(loadSurveyResultSpy.accountId).toBe(request.accountId) + }) + + test('Should return 500 if LoadSurveyResult throws', async () => { + const { sut, loadSurveyResultSpy } = makeSut() + jest.spyOn(loadSurveyResultSpy, 'load').mockImplementationOnce(throwError) + const httpResponse = await sut.handle(mockRequest()) + expect(httpResponse).toEqual(serverError(new Error())) + }) + + test('Should return 200 on success', async () => { + const { sut, loadSurveyResultSpy } = makeSut() + const httpResponse = await sut.handle(mockRequest()) + expect(httpResponse).toEqual(ok(loadSurveyResultSpy.result)) + }) +}) diff --git a/tests/presentation/controllers/load-surveys-controller.spec.ts b/tests/presentation/controllers/load-surveys-controller.spec.ts new file mode 100644 index 0000000..9dd9cbb --- /dev/null +++ b/tests/presentation/controllers/load-surveys-controller.spec.ts @@ -0,0 +1,60 @@ +import { LoadSurveysController } from '@/presentation/controllers' +import { ok, serverError, noContent } from '@/presentation/helpers' +import { LoadSurveysSpy } from '@/tests/presentation/mocks' +import { throwError } from '@/tests/domain/mocks' + +import MockDate from 'mockdate' +import { faker } from '@faker-js/faker' + +const mockRequest = (): LoadSurveysController.Request => ({ accountId: faker.datatype.uuid() }) + +type SutTypes = { + sut: LoadSurveysController + loadSurveysSpy: LoadSurveysSpy +} + +const makeSut = (): SutTypes => { + const loadSurveysSpy = new LoadSurveysSpy() + const sut = new LoadSurveysController(loadSurveysSpy) + return { + sut, + loadSurveysSpy + } +} + +describe('LoadSurveys Controller', () => { + beforeAll(() => { + MockDate.set(new Date()) + }) + + afterAll(() => { + MockDate.reset() + }) + + test('Should call LoadSurveys with correct value', async () => { + const { sut, loadSurveysSpy } = makeSut() + const request = mockRequest() + await sut.handle(request) + expect(loadSurveysSpy.accountId).toBe(request.accountId) + }) + + test('Should return 200 on success', async () => { + const { sut, loadSurveysSpy } = makeSut() + const httpResponse = await sut.handle(mockRequest()) + expect(httpResponse).toEqual(ok(loadSurveysSpy.result)) + }) + + test('Should return 204 if LoadSurveys returns empty', async () => { + const { sut, loadSurveysSpy } = makeSut() + loadSurveysSpy.result = [] + const httpResponse = await sut.handle(mockRequest()) + expect(httpResponse).toEqual(noContent()) + }) + + test('Should return 500 if LoadSurveys throws', async () => { + const { sut, loadSurveysSpy } = makeSut() + jest.spyOn(loadSurveysSpy, 'load').mockImplementationOnce(throwError) + const httpResponse = await sut.handle(mockRequest()) + expect(httpResponse).toEqual(serverError(new Error())) + }) +}) diff --git a/tests/presentation/controllers/login-controller.spec.ts b/tests/presentation/controllers/login-controller.spec.ts new file mode 100644 index 0000000..f1c66ed --- /dev/null +++ b/tests/presentation/controllers/login-controller.spec.ts @@ -0,0 +1,75 @@ +import { LoginController } from '@/presentation/controllers' +import { badRequest, serverError, unauthorized, ok } from '@/presentation/helpers' +import { MissingParamError } from '@/presentation/errors' +import { AuthenticationSpy, ValidationSpy } from '@/tests/presentation/mocks' +import { throwError } from '@/tests/domain/mocks' + +import { faker } from '@faker-js/faker' + +const mockRequest = (): LoginController.Request => ({ + email: faker.internet.email(), + password: faker.internet.password() +}) + +type SutTypes = { + sut: LoginController + authenticationSpy: AuthenticationSpy + validationSpy: ValidationSpy +} + +const makeSut = (): SutTypes => { + const authenticationSpy = new AuthenticationSpy() + const validationSpy = new ValidationSpy() + const sut = new LoginController(authenticationSpy, validationSpy) + return { + sut, + authenticationSpy, + validationSpy + } +} + +describe('Login Controller', () => { + test('Should call Authentication with correct values', async () => { + const { sut, authenticationSpy } = makeSut() + const request = mockRequest() + await sut.handle(request) + expect(authenticationSpy.params).toEqual({ + email: request.email, + password: request.password + }) + }) + + test('Should return 401 if invalid credentials are provided', async () => { + const { sut, authenticationSpy } = makeSut() + authenticationSpy.result = null + const httpResponse = await sut.handle(mockRequest()) + expect(httpResponse).toEqual(unauthorized()) + }) + + test('Should return 500 if Authentication throws', async () => { + const { sut, authenticationSpy } = makeSut() + jest.spyOn(authenticationSpy, 'auth').mockImplementationOnce(throwError) + const httpResponse = await sut.handle(mockRequest()) + expect(httpResponse).toEqual(serverError(new Error())) + }) + + test('Should return 200 if valid credentials are provided', async () => { + const { sut, authenticationSpy } = makeSut() + const httpResponse = await sut.handle(mockRequest()) + expect(httpResponse).toEqual(ok(authenticationSpy.result)) + }) + + test('Should call Validation with correct value', async () => { + const { sut, validationSpy } = makeSut() + const request = mockRequest() + await sut.handle(request) + expect(validationSpy.input).toEqual(request) + }) + + test('Should return 400 if Validation returns an error', async () => { + const { sut, validationSpy } = makeSut() + validationSpy.error = new MissingParamError(faker.random.word()) + const httpResponse = await sut.handle(mockRequest()) + expect(httpResponse).toEqual(badRequest(validationSpy.error)) + }) +}) diff --git a/tests/presentation/controllers/save-survey-result-controller.spec.ts b/tests/presentation/controllers/save-survey-result-controller.spec.ts new file mode 100644 index 0000000..a4f9035 --- /dev/null +++ b/tests/presentation/controllers/save-survey-result-controller.spec.ts @@ -0,0 +1,95 @@ +import { SaveSurveyResultController } from '@/presentation/controllers' +import { InvalidParamError } from '@/presentation/errors' +import { forbidden, serverError, ok } from '@/presentation/helpers' +import { SaveSurveyResultSpy, LoadAnswersBySurveySpy } from '@/tests/presentation/mocks' +import { throwError } from '@/tests/domain/mocks' + +import MockDate from 'mockdate' +import { faker } from '@faker-js/faker' + +const mockRequest = (answer: string = null): SaveSurveyResultController.Request => ({ + surveyId: faker.datatype.uuid(), + answer, + accountId: faker.datatype.uuid() +}) + +type SutTypes = { + sut: SaveSurveyResultController + loadAnswersBySurveySpy: LoadAnswersBySurveySpy + saveSurveyResultSpy: SaveSurveyResultSpy +} + +const makeSut = (): SutTypes => { + const loadAnswersBySurveySpy = new LoadAnswersBySurveySpy() + const saveSurveyResultSpy = new SaveSurveyResultSpy() + const sut = new SaveSurveyResultController(loadAnswersBySurveySpy, saveSurveyResultSpy) + return { + sut, + loadAnswersBySurveySpy, + saveSurveyResultSpy + } +} + +describe('SaveSurveyResult Controller', () => { + beforeAll(() => { + MockDate.set(new Date()) + }) + + afterAll(() => { + MockDate.reset() + }) + + test('Should call LoadAnswersBySurvey with correct values', async () => { + const { sut, loadAnswersBySurveySpy } = makeSut() + const request = mockRequest() + await sut.handle(request) + expect(loadAnswersBySurveySpy.id).toBe(request.surveyId) + }) + + test('Should return 403 if LoadAnswersBySurvey returns null', async () => { + const { sut, loadAnswersBySurveySpy } = makeSut() + loadAnswersBySurveySpy.result = [] + const httpResponse = await sut.handle(mockRequest()) + expect(httpResponse).toEqual(forbidden(new InvalidParamError('surveyId'))) + }) + + test('Should return 500 if LoadAnswersBySurvey throws', async () => { + const { sut, loadAnswersBySurveySpy } = makeSut() + jest.spyOn(loadAnswersBySurveySpy, 'loadAnswers').mockImplementationOnce(throwError) + const httpResponse = await sut.handle(mockRequest()) + expect(httpResponse).toEqual(serverError(new Error())) + }) + + test('Should return 403 if an invalid answer is provided', async () => { + const { sut } = makeSut() + const httpResponse = await sut.handle(mockRequest()) + expect(httpResponse).toEqual(forbidden(new InvalidParamError('answer'))) + }) + + test('Should call SaveSurveyResult with correct values', async () => { + const { sut, saveSurveyResultSpy, loadAnswersBySurveySpy } = makeSut() + const request = mockRequest(loadAnswersBySurveySpy.result[0]) + await sut.handle(request) + expect(saveSurveyResultSpy.params).toEqual({ + surveyId: request.surveyId, + accountId: request.accountId, + date: new Date(), + answer: request.answer + }) + }) + + test('Should return 500 if SaveSurveyResult throws', async () => { + const { sut, saveSurveyResultSpy, loadAnswersBySurveySpy } = makeSut() + jest.spyOn(saveSurveyResultSpy, 'save').mockImplementationOnce(throwError) + const request = mockRequest(loadAnswersBySurveySpy.result[0]) + const httpResponse = await sut.handle(request) + expect(httpResponse).toEqual(serverError(new Error())) + }) + + test('Should return 200 on success', async () => { + const { sut, saveSurveyResultSpy, loadAnswersBySurveySpy } = makeSut() + const request = mockRequest(loadAnswersBySurveySpy.result[0]) + const httpResponse = await sut.handle(request) + expect(httpResponse).toEqual(ok(saveSurveyResultSpy.result)) + }) +}) diff --git a/tests/presentation/controllers/signup-controller.spec.ts b/tests/presentation/controllers/signup-controller.spec.ts new file mode 100644 index 0000000..00a4714 --- /dev/null +++ b/tests/presentation/controllers/signup-controller.spec.ts @@ -0,0 +1,101 @@ +import { SignUpController } from '@/presentation/controllers' +import { MissingParamError, ServerError, EmailInUseError } from '@/presentation/errors' +import { ok, serverError, badRequest, forbidden } from '@/presentation/helpers' +import { AuthenticationSpy, ValidationSpy, AddAccountSpy } from '@/tests/presentation/mocks' +import { throwError } from '@/tests/domain/mocks' + +import { faker } from '@faker-js/faker' + +const mockRequest = (): SignUpController.Request => { + const password = faker.internet.password() + return { + name: faker.name.fullName(), + email: faker.internet.email(), + password, + passwordConfirmation: password + } +} + +type SutTypes = { + sut: SignUpController + addAccountSpy: AddAccountSpy + validationSpy: ValidationSpy + authenticationSpy: AuthenticationSpy +} + +const makeSut = (): SutTypes => { + const authenticationSpy = new AuthenticationSpy() + const addAccountSpy = new AddAccountSpy() + const validationSpy = new ValidationSpy() + const sut = new SignUpController(addAccountSpy, validationSpy, authenticationSpy) + return { + sut, + addAccountSpy, + validationSpy, + authenticationSpy + } +} + +describe('SignUp Controller', () => { + test('Should return 500 if AddAccount throws', async () => { + const { sut, addAccountSpy } = makeSut() + jest.spyOn(addAccountSpy, 'add').mockImplementationOnce(throwError) + const httpResponse = await sut.handle(mockRequest()) + expect(httpResponse).toEqual(serverError(new ServerError(null))) + }) + + test('Should call AddAccount with correct values', async () => { + const { sut, addAccountSpy } = makeSut() + const request = mockRequest() + await sut.handle(request) + expect(addAccountSpy.params).toEqual({ + name: request.name, + email: request.email, + password: request.password + }) + }) + + test('Should return 403 if AddAccount returns false', async () => { + const { sut, addAccountSpy } = makeSut() + addAccountSpy.result = false + const httpResponse = await sut.handle(mockRequest()) + expect(httpResponse).toEqual(forbidden(new EmailInUseError())) + }) + + test('Should return 200 if valid data is provided', async () => { + const { sut, authenticationSpy } = makeSut() + const httpResponse = await sut.handle(mockRequest()) + expect(httpResponse).toEqual(ok(authenticationSpy.result)) + }) + + test('Should call Validation with correct value', async () => { + const { sut, validationSpy } = makeSut() + const request = mockRequest() + await sut.handle(request) + expect(validationSpy.input).toEqual(request) + }) + + test('Should return 400 if Validation returns an error', async () => { + const { sut, validationSpy } = makeSut() + validationSpy.error = new MissingParamError(faker.random.word()) + const httpResponse = await sut.handle(mockRequest()) + expect(httpResponse).toEqual(badRequest(validationSpy.error)) + }) + + test('Should call Authentication with correct values', async () => { + const { sut, authenticationSpy } = makeSut() + const request = mockRequest() + await sut.handle(request) + expect(authenticationSpy.params).toEqual({ + email: request.email, + password: request.password + }) + }) + + test('Should return 500 if Authentication throws', async () => { + const { sut, authenticationSpy } = makeSut() + jest.spyOn(authenticationSpy, 'auth').mockImplementationOnce(throwError) + const httpResponse = await sut.handle(mockRequest()) + expect(httpResponse).toEqual(serverError(new Error())) + }) +}) diff --git a/tests/presentation/middlewares/auth-middleware.spec.ts b/tests/presentation/middlewares/auth-middleware.spec.ts new file mode 100644 index 0000000..415f20e --- /dev/null +++ b/tests/presentation/middlewares/auth-middleware.spec.ts @@ -0,0 +1,62 @@ +import { AuthMiddleware } from '@/presentation/middlewares' +import { forbidden, ok, serverError } from '@/presentation/helpers' +import { AccessDeniedError } from '@/presentation/errors' +import { LoadAccountByTokenSpy } from '@/tests/presentation/mocks' +import { throwError } from '@/tests/domain/mocks' + +const mockRequest = (): AuthMiddleware.Request => ({ + accessToken: 'any_token' +}) + +type SutTypes = { + sut: AuthMiddleware + loadAccountByTokenSpy: LoadAccountByTokenSpy +} + +const makeSut = (role?: string): SutTypes => { + const loadAccountByTokenSpy = new LoadAccountByTokenSpy() + const sut = new AuthMiddleware(loadAccountByTokenSpy, role) + return { + sut, + loadAccountByTokenSpy + } +} + +describe('Auth Middleware', () => { + test('Should return 403 if no x-access-token exists in headers', async () => { + const { sut } = makeSut() + const httpResponse = await sut.handle({}) + expect(httpResponse).toEqual(forbidden(new AccessDeniedError())) + }) + + test('Should call LoadAccountByToken with correct accessToken', async () => { + const role = 'any_role' + const { sut, loadAccountByTokenSpy } = makeSut(role) + const httpRequest = mockRequest() + await sut.handle(httpRequest) + expect(loadAccountByTokenSpy.accessToken).toBe(httpRequest.accessToken) + expect(loadAccountByTokenSpy.role).toBe(role) + }) + + test('Should return 403 if LoadAccountByToken returns null', async () => { + const { sut, loadAccountByTokenSpy } = makeSut() + loadAccountByTokenSpy.result = null + const httpResponse = await sut.handle(mockRequest()) + expect(httpResponse).toEqual(forbidden(new AccessDeniedError())) + }) + + test('Should return 200 if LoadAccountByToken returns an account', async () => { + const { sut, loadAccountByTokenSpy } = makeSut() + const httpResponse = await sut.handle(mockRequest()) + expect(httpResponse).toEqual(ok({ + accountId: loadAccountByTokenSpy.result.id + })) + }) + + test('Should return 500 if LoadAccountByToken throws', async () => { + const { sut, loadAccountByTokenSpy } = makeSut() + jest.spyOn(loadAccountByTokenSpy, 'load').mockImplementationOnce(throwError) + const httpResponse = await sut.handle(mockRequest()) + expect(httpResponse).toEqual(serverError(new Error())) + }) +}) diff --git a/src/presentation/test/index.ts b/tests/presentation/mocks/index.ts similarity index 100% rename from src/presentation/test/index.ts rename to tests/presentation/mocks/index.ts index 9e0c3df..f329582 100644 --- a/src/presentation/test/index.ts +++ b/tests/presentation/mocks/index.ts @@ -1,4 +1,4 @@ +export * from './mock-validation' export * from './mock-account' -export * from './mock-survey-result' export * from './mock-survey' -export * from './mock-validation' +export * from './mock-survey-result' diff --git a/tests/presentation/mocks/mock-account.ts b/tests/presentation/mocks/mock-account.ts new file mode 100644 index 0000000..a91c13e --- /dev/null +++ b/tests/presentation/mocks/mock-account.ts @@ -0,0 +1,40 @@ +import { AddAccount, Authentication, LoadAccountByToken } from '@/domain/usecases' + +import { faker } from '@faker-js/faker' + +export class AddAccountSpy implements AddAccount { + params: AddAccount.Params + result = true + + async add (params: AddAccount.Params): Promise { + this.params = params + return this.result + } +} + +export class AuthenticationSpy implements Authentication { + params: Authentication.Params + result = { + accessToken: faker.datatype.uuid(), + name: faker.name.fullName() + } + + async auth (params: Authentication.Params): Promise { + this.params = params + return this.result + } +} + +export class LoadAccountByTokenSpy implements LoadAccountByToken { + accessToken: string + role: string + result = { + id: faker.datatype.uuid() + } + + async load (accessToken: string, role?: string): Promise { + this.accessToken = accessToken + this.role = role + return this.result + } +} diff --git a/tests/presentation/mocks/mock-survey-result.ts b/tests/presentation/mocks/mock-survey-result.ts new file mode 100644 index 0000000..2965faf --- /dev/null +++ b/tests/presentation/mocks/mock-survey-result.ts @@ -0,0 +1,24 @@ +import { SaveSurveyResult, LoadSurveyResult } from '@/domain/usecases' +import { mockSurveyResultModel } from '@/tests/domain/mocks' + +export class SaveSurveyResultSpy implements SaveSurveyResult { + params: SaveSurveyResult.Params + result = mockSurveyResultModel() + + async save (params: SaveSurveyResult.Params): Promise { + this.params = params + return this.result + } +} + +export class LoadSurveyResultSpy implements LoadSurveyResult { + surveyId: string + accountId: string + result = mockSurveyResultModel() + + async load (surveyId: string, accountId: string): Promise { + this.surveyId = surveyId + this.accountId = accountId + return this.result + } +} diff --git a/tests/presentation/mocks/mock-survey.ts b/tests/presentation/mocks/mock-survey.ts new file mode 100644 index 0000000..e528be8 --- /dev/null +++ b/tests/presentation/mocks/mock-survey.ts @@ -0,0 +1,45 @@ +import { AddSurvey, LoadAnswersBySurvey, LoadSurveys, CheckSurveyById } from '@/domain/usecases' +import { mockSurveyModels } from '@/tests/domain/mocks' + +import { faker } from '@faker-js/faker' + +export class AddSurveySpy implements AddSurvey { + params: AddSurvey.Params + + async add (params: AddSurvey.Params): Promise { + this.params = params + } +} + +export class LoadSurveysSpy implements LoadSurveys { + accountId: string + result = mockSurveyModels() + + async load (accountId: string): Promise { + this.accountId = accountId + return this.result + } +} + +export class LoadAnswersBySurveySpy implements LoadAnswersBySurvey { + id: string + result = [ + faker.random.word(), + faker.random.word() + ] + + async loadAnswers (id: string): Promise { + this.id = id + return this.result + } +} + +export class CheckSurveyByIdSpy implements CheckSurveyById { + id: string + result = true + + async checkById (id: string): Promise { + this.id = id + return this.result + } +} diff --git a/tests/presentation/mocks/mock-validation.ts b/tests/presentation/mocks/mock-validation.ts new file mode 100644 index 0000000..9c6e042 --- /dev/null +++ b/tests/presentation/mocks/mock-validation.ts @@ -0,0 +1,11 @@ +import { Validation } from '@/presentation/protocols' + +export class ValidationSpy implements Validation { + error: Error = null + input: any + + validate (input: any): Error { + this.input = input + return this.error + } +} diff --git a/src/validation/test/index.ts b/tests/validation/mocks/index.ts similarity index 53% rename from src/validation/test/index.ts rename to tests/validation/mocks/index.ts index 8f168aa..7470ae8 100644 --- a/src/validation/test/index.ts +++ b/tests/validation/mocks/index.ts @@ -1,2 +1 @@ export * from './mock-email-validator' -export * from './mock-validation' diff --git a/tests/validation/mocks/mock-email-validator.ts b/tests/validation/mocks/mock-email-validator.ts new file mode 100644 index 0000000..33d29fd --- /dev/null +++ b/tests/validation/mocks/mock-email-validator.ts @@ -0,0 +1,11 @@ +import { EmailValidator } from '@/validation/protocols' + +export class EmailValidatorSpy implements EmailValidator { + isEmailValid = true + email: string + + isValid (email: string): boolean { + this.email = email + return this.isEmailValid + } +} diff --git a/tests/validation/validators/compare-fields-validation.spec.ts b/tests/validation/validators/compare-fields-validation.spec.ts new file mode 100644 index 0000000..64e0a71 --- /dev/null +++ b/tests/validation/validators/compare-fields-validation.spec.ts @@ -0,0 +1,32 @@ +import { CompareFieldsValidation } from '@/validation/validators' +import { InvalidParamError } from '@/presentation/errors' + +import { faker } from '@faker-js/faker' + +const field = faker.random.word() +const fieldToCompare = faker.random.word() + +const makeSut = (): CompareFieldsValidation => { + return new CompareFieldsValidation(field, fieldToCompare) +} + +describe('CompareFieldsValidation', () => { + test('Should return an InvalidParamError if validation fails', () => { + const sut = makeSut() + const error = sut.validate({ + [field]: 'any_field', + [fieldToCompare]: 'other_field' + }) + expect(error).toEqual(new InvalidParamError(fieldToCompare)) + }) + + test('Should not return if validation succeeds', () => { + const sut = makeSut() + const value = faker.random.word() + const error = sut.validate({ + [field]: value, + [fieldToCompare]: value + }) + expect(error).toBeFalsy() + }) +}) diff --git a/tests/validation/validators/email-validation.spec.ts b/tests/validation/validators/email-validation.spec.ts new file mode 100644 index 0000000..72f3637 --- /dev/null +++ b/tests/validation/validators/email-validation.spec.ts @@ -0,0 +1,45 @@ +import { EmailValidation } from '@/validation/validators' +import { InvalidParamError } from '@/presentation/errors' +import { EmailValidatorSpy } from '@/tests/validation/mocks' +import { throwError } from '@/tests/domain/mocks' + +import { faker } from '@faker-js/faker' + +const field = faker.random.word() + +type SutTypes = { + sut: EmailValidation + emailValidatorSpy: EmailValidatorSpy +} + +const makeSut = (): SutTypes => { + const emailValidatorSpy = new EmailValidatorSpy() + const sut = new EmailValidation(field, emailValidatorSpy) + return { + sut, + emailValidatorSpy + } +} + +describe('Email Validation', () => { + test('Should return an error if EmailValidator returns false', () => { + const { sut, emailValidatorSpy } = makeSut() + emailValidatorSpy.isEmailValid = false + const email = faker.internet.email() + const error = sut.validate({ [field]: email }) + expect(error).toEqual(new InvalidParamError(field)) + }) + + test('Should call EmailValidator with correct email', () => { + const { sut, emailValidatorSpy } = makeSut() + const email = faker.internet.email() + sut.validate({ [field]: email }) + expect(emailValidatorSpy.email).toBe(email) + }) + + test('Should throw if EmailValidator throws', () => { + const { sut, emailValidatorSpy } = makeSut() + jest.spyOn(emailValidatorSpy, 'isValid').mockImplementationOnce(throwError) + expect(sut.validate).toThrow() + }) +}) diff --git a/src/validation/validators/required-field-validation.spec.ts b/tests/validation/validators/required-field-validation.spec.ts similarity index 50% rename from src/validation/validators/required-field-validation.spec.ts rename to tests/validation/validators/required-field-validation.spec.ts index 38950a3..b9b5876 100644 --- a/src/validation/validators/required-field-validation.spec.ts +++ b/tests/validation/validators/required-field-validation.spec.ts @@ -1,20 +1,24 @@ -import { RequiredFieldValidation } from './required-field-validation' +import { RequiredFieldValidation } from '@/validation/validators' import { MissingParamError } from '@/presentation/errors' +import { faker } from '@faker-js/faker' + +const field = faker.random.word() + const makeSut = (): RequiredFieldValidation => { - return new RequiredFieldValidation('field') + return new RequiredFieldValidation(field) } describe('RequiredField Validation', () => { test('Should return a MissingParamError if validation fails', () => { const sut = makeSut() - const error = sut.validate({ name: 'any_name' }) - expect(error).toEqual(new MissingParamError('field')) + const error = sut.validate({ invalidField: faker.random.word() }) + expect(error).toEqual(new MissingParamError(field)) }) test('Should not return if validation succeeds', () => { const sut = makeSut() - const error = sut.validate({ field: 'any_name' }) + const error = sut.validate({ [field]: faker.random.word() }) expect(error).toBeFalsy() }) }) diff --git a/tests/validation/validators/validation-composite.spec.ts b/tests/validation/validators/validation-composite.spec.ts new file mode 100644 index 0000000..6a6a193 --- /dev/null +++ b/tests/validation/validators/validation-composite.spec.ts @@ -0,0 +1,47 @@ +import { ValidationComposite } from '@/validation/validators' +import { MissingParamError } from '@/presentation/errors' +import { ValidationSpy } from '@/tests/presentation/mocks' + +import { faker } from '@faker-js/faker' + +const field = faker.random.word() + +type SutTypes = { + sut: ValidationComposite + validationSpies: ValidationSpy[] +} + +const makeSut = (): SutTypes => { + const validationSpies = [ + new ValidationSpy(), + new ValidationSpy() + ] + const sut = new ValidationComposite(validationSpies) + return { + sut, + validationSpies + } +} + +describe('Validation Composite', () => { + test('Should return an error if any validation fails', () => { + const { sut, validationSpies } = makeSut() + validationSpies[1].error = new MissingParamError(field) + const error = sut.validate({ [field]: faker.random.word() }) + expect(error).toEqual(validationSpies[1].error) + }) + + test('Should return the first error if more then one validation fails', () => { + const { sut, validationSpies } = makeSut() + validationSpies[0].error = new Error() + validationSpies[1].error = new MissingParamError(field) + const error = sut.validate({ [field]: faker.random.word() }) + expect(error).toEqual(validationSpies[0].error) + }) + + test('Should not return if validation succeeds', () => { + const { sut } = makeSut() + const error = sut.validate({ [field]: faker.random.word() }) + expect(error).toBeFalsy() + }) +}) diff --git a/tsconfig-build.json b/tsconfig-build.json index 9eefd23..ebd1b3c 100644 --- a/tsconfig-build.json +++ b/tsconfig-build.json @@ -1,8 +1,4 @@ { "extends": "./tsconfig.json", - "exclude": [ - "**/*.spec.ts", - "**/*.test.ts", - "**/test/**" - ] + "exclude": ["tests"] } \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 5bce9b1..074ab69 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,12 +4,14 @@ "module": "commonjs", "target": "es2019", "esModuleInterop": true, + "sourceMap": true, + "rootDirs": ["src", "tests"], "baseUrl": "src", "paths": { + "@/tests/*": ["../tests/*"], "@/*": ["*"] } }, - "include": [ - "src" - ] + "include": ["src", "tests"], + "exclude": [] } \ No newline at end of file