From 7e11c1e5cefd8f8d4d372876dd430c6ec51671ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Tue, 3 Jun 2025 20:31:53 -0500 Subject: [PATCH] feat: api --- LICENSE | 661 ------------------ bun.lockb | Bin 315788 -> 316528 bytes package.json | 1 + packages/core/package.json | 3 +- .../{metadata/abstract.ts => metadata.ts} | 77 +- packages/core/src/blitz/metadata/index.ts | 3 - packages/core/src/blitz/metadata/remote.ts | 30 - packages/core/src/blitz/metadata/socket.ts | 37 - packages/core/src/blitzkit/api/abstract.ts | 8 + packages/core/src/blitzkit/api/client.ts | 15 + packages/core/src/blitzkit/api/index.ts | 3 + packages/core/src/blitzkit/api/server.ts | 37 + packages/core/src/blitzkit/index.ts | 1 + .../src/core/blitz/metadata.remote.ts | 5 - .../src/core/blitz/metadata.socket.ts | 6 - .../website-ue/src/core/blitz/metadata.ts | 11 - packages/website-ue/src/core/blitzkit/api.ts | 11 - .../src/core/blitzkit/api/client.ts | 3 + .../website-ue/src/core/blitzkit/api/index.ts | 11 + .../src/core/blitzkit/api/server.ts | 6 + .../src/pages/[...locale]/avatars/_index.tsx | 17 +- .../src/pages/[...locale]/avatars/index.astro | 6 +- .../src/pages/api/avatars/[id].webp.ts | 35 +- .../src/pages/api/internal/avatars.pb.ts | 7 + .../pages/api/internal/catalog/[item].pb.ts | 19 - submodules/blitzkit-closed | 2 +- 26 files changed, 149 insertions(+), 866 deletions(-) delete mode 100644 LICENSE rename packages/core/src/blitz/{metadata/abstract.ts => metadata.ts} (60%) delete mode 100644 packages/core/src/blitz/metadata/index.ts delete mode 100644 packages/core/src/blitz/metadata/remote.ts delete mode 100644 packages/core/src/blitz/metadata/socket.ts create mode 100644 packages/core/src/blitzkit/api/abstract.ts create mode 100644 packages/core/src/blitzkit/api/client.ts create mode 100644 packages/core/src/blitzkit/api/index.ts create mode 100644 packages/core/src/blitzkit/api/server.ts delete mode 100644 packages/website-ue/src/core/blitz/metadata.remote.ts delete mode 100644 packages/website-ue/src/core/blitz/metadata.socket.ts delete mode 100644 packages/website-ue/src/core/blitz/metadata.ts delete mode 100644 packages/website-ue/src/core/blitzkit/api.ts create mode 100644 packages/website-ue/src/core/blitzkit/api/client.ts create mode 100644 packages/website-ue/src/core/blitzkit/api/index.ts create mode 100644 packages/website-ue/src/core/blitzkit/api/server.ts create mode 100644 packages/website-ue/src/pages/api/internal/avatars.pb.ts delete mode 100644 packages/website-ue/src/pages/api/internal/catalog/[item].pb.ts diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 0ad25db4b..000000000 --- a/LICENSE +++ /dev/null @@ -1,661 +0,0 @@ - GNU AFFERO GENERAL PUBLIC LICENSE - Version 3, 19 November 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU Affero General Public License is a free, copyleft license for -software and other kinds of works, specifically designed to ensure -cooperation with the community in the case of network server software. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -our General Public Licenses are intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - Developers that use our General Public Licenses protect your rights -with two steps: (1) assert copyright on the software, and (2) offer -you this License which gives you legal permission to copy, distribute -and/or modify the software. - - A secondary benefit of defending all users' freedom is that -improvements made in alternate versions of the program, if they -receive widespread use, become available for other developers to -incorporate. Many developers of free software are heartened and -encouraged by the resulting cooperation. However, in the case of -software used on network servers, this result may fail to come about. -The GNU General Public License permits making a modified version and -letting the public access it on a server without ever releasing its -source code to the public. - - The GNU Affero General Public License is designed specifically to -ensure that, in such cases, the modified source code becomes available -to the community. It requires the operator of a network server to -provide the source code of the modified version running there to the -users of that server. Therefore, public use of a modified version, on -a publicly accessible server, gives the public access to the source -code of the modified version. - - An older license, called the Affero General Public License and -published by Affero, was designed to accomplish similar goals. This is -a different license, not a version of the Affero GPL, but Affero has -released a new version of the Affero GPL which permits relicensing under -this license. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU Affero General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Remote Network Interaction; Use with the GNU General Public License. - - Notwithstanding any other provision of this License, if you modify the -Program, your modified version must prominently offer all users -interacting with it remotely through a computer network (if your version -supports such interaction) an opportunity to receive the Corresponding -Source of your version by providing access to the Corresponding Source -from a network server at no charge, through some standard or customary -means of facilitating copying of software. This Corresponding Source -shall include the Corresponding Source for any work covered by version 3 -of the GNU General Public License that is incorporated pursuant to the -following paragraph. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the work with which it is combined will remain governed by version -3 of the GNU General Public License. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU Affero General Public License from time to time. Such new versions -will be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU Affero General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU Affero General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU Affero General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published - by the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If your software can interact with users remotely through a computer -network, you should also make sure that it provides a way for users to -get its source. For example, if your program is a web application, its -interface could display a "Source" link that leads users to an archive -of the code. There are many ways you could offer source, and different -solutions will be better for different programs; see section 13 for the -specific requirements. - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU AGPL, see -. diff --git a/bun.lockb b/bun.lockb index 12cb0af5ea80dca27859df7fdc3643232fa6218d..a9bea9ac71664d3dc35d0f01e5a8531be84b32cb 100644 GIT binary patch delta 62871 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 diff --git a/package.json b/package.json index d68f54c17..ca1be902f 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ }, "license": "MIT", "dependencies": { + "@types/bun": "^1.2.15", "prettier": "^3.5.3" } } diff --git a/packages/core/package.json b/packages/core/package.json index 9dd270759..c1ca69a22 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -6,6 +6,7 @@ "dependencies": { "@types/js-yaml": "^4.0.9", "js-yaml": "^4.1.0", - "ts-proto": "^2.2.2" + "ts-proto": "^2.2.2", + "@blitzkit/closed": "workspace:*" } } diff --git a/packages/core/src/blitz/metadata/abstract.ts b/packages/core/src/blitz/metadata.ts similarity index 60% rename from packages/core/src/blitz/metadata/abstract.ts rename to packages/core/src/blitz/metadata.ts index 9f274b5c5..3826893d5 100644 --- a/packages/core/src/blitz/metadata/abstract.ts +++ b/packages/core/src/blitz/metadata.ts @@ -1,9 +1,7 @@ +import { CatalogItem } from '@protos/blitz_items'; +import { Metadata } from '@protos/blitz_metadata'; import { LocalizationResourcesComponent } from '@protos/blitz_static_localization_resources_component'; -import { ProfileAvatarComponent } from '@protos/blitz_static_profile_avatar_component'; import { RemoteStorageComponent } from '@protos/blitz_static_remote_storage_component'; -import { SellableComponent } from '@protos/blitz_static_sellable_component'; -import { StuffUIComponent } from '@protos/blitz_static_stuff_ui_component'; -import { BlitzkitAllAvatarsComponent } from '@protos/blitzkit_static_all_avatars_component'; import { load } from 'js-yaml'; import { minimatch } from 'minimatch'; import { CatalogItemAccessor } from 'packages/core/src/blitz/catalogItemAccessor'; @@ -12,12 +10,35 @@ interface LocalizationConfig { namespaces: string[]; } -export abstract class MetadataAccessor { - abstract get(item: string): Promise; +export class MetadataAccessor { + items: Record = {}; - abstract add(item: CatalogItemAccessor): void; + constructor(metadata: Metadata) { + for (const item of metadata.catalog_items) { + this.items[item.catalog_id] = item; + } + } - abstract filter(predicate: (item: string) => boolean): CatalogItemAccessor[]; + get(item: string) { + if (item in this.items) return new CatalogItemAccessor(this.items[item]); + throw new Error(`Item ${item} does not exist in socket metadata`); + } + + add(item: CatalogItemAccessor) { + this.items[item.id] = item.pack(); + } + + filter(predicate: (item: string) => boolean) { + const items: CatalogItemAccessor[] = []; + + for (const item in this.items) { + if (predicate(item)) { + items.push(new CatalogItemAccessor(this.items[item])); + } + } + + return items; + } async strings(locale: string) { const clientConfig = await this.get( @@ -97,44 +118,4 @@ export abstract class MetadataAccessor { return filtered; } - - injectBlitzkit() { - this.injectBlitzkitProfileAvatars(); - - return this; - } - - injectBlitzkitProfileAvatars() { - const allAvatars: BlitzkitAllAvatarsComponent = { avatars: [] }; - - for (const item of this.filter((item) => - item.startsWith('ProfileAvatarEntity.'), - )) { - const stuff = item.get(StuffUIComponent, 'UIComponent'); - const avatar = item.get(ProfileAvatarComponent, 'profileAvatarComponent'); - const sellable = item.getOptional(SellableComponent, 'sellableComponent'); - - allAvatars.avatars.push({ - id: item.undiscriminatedId(), - name: stuff.display_name, - obtaining: stuff.obtaining_methods, - description: stuff.description, - grade: stuff.grade, - category: avatar.category, - hidden_if_not_obtained: avatar.hidden_if_not_obtained, - sale: sellable?.reward, - }); - } - - this.add( - CatalogItemAccessor.fromComponent( - 'BlitzkitAllAvatarsEntity.blitzkit_all_avatars', - { - type_url: - './blitzkit_static_all_avatars_component.BlitzkitAllAvatarsComponent', - value: BlitzkitAllAvatarsComponent.encode(allAvatars).finish(), - }, - ), - ); - } } diff --git a/packages/core/src/blitz/metadata/index.ts b/packages/core/src/blitz/metadata/index.ts deleted file mode 100644 index 495f63f5f..000000000 --- a/packages/core/src/blitz/metadata/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './abstract'; -export * from './remote'; -export * from './socket'; diff --git a/packages/core/src/blitz/metadata/remote.ts b/packages/core/src/blitz/metadata/remote.ts deleted file mode 100644 index b92a18968..000000000 --- a/packages/core/src/blitz/metadata/remote.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { CatalogItem } from '@protos/blitz_items'; -import { CatalogItemAccessor } from '../catalogItemAccessor'; -import { MetadataAccessor } from './abstract'; - -export class RemoteMetadataAccessor extends MetadataAccessor { - constructor(private base: string) { - super(); - } - - async get(item: string) { - const response = await fetch(`${this.base}/${item}.pb`); - - if (!response.ok) { - throw new Error(`Item ${item} does not exist in remote metadata`); - } - - const buffer = new Uint8Array(await response.arrayBuffer()); - const catalogItem = CatalogItem.decode(buffer); - - return new CatalogItemAccessor(catalogItem); - } - - add() { - throw new Error('Cannot add items to remote metadata'); - } - - filter(): CatalogItemAccessor[] { - throw new Error('Cannot filter remote metadata'); - } -} diff --git a/packages/core/src/blitz/metadata/socket.ts b/packages/core/src/blitz/metadata/socket.ts deleted file mode 100644 index 7ecca8912..000000000 --- a/packages/core/src/blitz/metadata/socket.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { CatalogItem } from '@protos/blitz_items'; -import { Metadata } from '@protos/blitz_metadata'; -import { CatalogItemAccessor } from '../catalogItemAccessor'; -import { MetadataAccessor } from './abstract'; - -export class SocketMetadataAccessor extends MetadataAccessor { - items: Record = {}; - - constructor(metadata: Metadata) { - super(); - - for (const item of metadata.catalog_items) { - this.items[item.catalog_id] = item; - } - } - - async get(item: string) { - if (item in this.items) return new CatalogItemAccessor(this.items[item]); - throw new Error(`Item ${item} does not exist in socket metadata`); - } - - add(item: CatalogItemAccessor) { - this.items[item.id] = item.pack(); - } - - filter(predicate: (item: string) => boolean) { - const items: CatalogItemAccessor[] = []; - - for (const item in this.items) { - if (predicate(item)) { - items.push(new CatalogItemAccessor(this.items[item])); - } - } - - return items; - } -} diff --git a/packages/core/src/blitzkit/api/abstract.ts b/packages/core/src/blitzkit/api/abstract.ts new file mode 100644 index 000000000..b9361658c --- /dev/null +++ b/packages/core/src/blitzkit/api/abstract.ts @@ -0,0 +1,8 @@ +import { BlitzKitAvatars } from '@protos/blitzkit'; +import { MetadataAccessor } from '../../blitz/metadata'; + +export abstract class BlitzkitAPI { + abstract metadata: MetadataAccessor; + + abstract avatars(): Promise; +} diff --git a/packages/core/src/blitzkit/api/client.ts b/packages/core/src/blitzkit/api/client.ts new file mode 100644 index 000000000..194db3510 --- /dev/null +++ b/packages/core/src/blitzkit/api/client.ts @@ -0,0 +1,15 @@ +import { BlitzKitAvatars } from '@protos/blitzkit'; +import { MetadataAccessor } from '../../blitz/metadata'; +import { BlitzkitAPI } from './abstract'; + +export class BlitzkitClientAPI extends BlitzkitAPI { + get metadata(): MetadataAccessor { + throw new Error('Cannot access metadata from client'); + } + + async avatars() { + const response = await fetch('/api/internal/avatars.pb'); + const buffer = await response.arrayBuffer(); + return BlitzKitAvatars.decode(new Uint8Array(buffer)); + } +} diff --git a/packages/core/src/blitzkit/api/index.ts b/packages/core/src/blitzkit/api/index.ts new file mode 100644 index 000000000..6b9f1a6bc --- /dev/null +++ b/packages/core/src/blitzkit/api/index.ts @@ -0,0 +1,3 @@ +export * from './abstract'; +export * from './client'; +export * from './server'; diff --git a/packages/core/src/blitzkit/api/server.ts b/packages/core/src/blitzkit/api/server.ts new file mode 100644 index 000000000..b9a70bf1a --- /dev/null +++ b/packages/core/src/blitzkit/api/server.ts @@ -0,0 +1,37 @@ +import { ProfileAvatarComponent } from '@protos/blitz_static_profile_avatar_component'; +import { SellableComponent } from '@protos/blitz_static_sellable_component'; +import { StuffUIComponent } from '@protos/blitz_static_stuff_ui_component'; +import { BlitzKitAvatars } from '@protos/blitzkit'; +import { BlitzkitAPI } from '.'; +import { MetadataAccessor } from '../../blitz/metadata'; + +export class BlitzkitServerAPI extends BlitzkitAPI { + constructor(public metadata: MetadataAccessor) { + super(); + } + + async avatars() { + const avatars: BlitzKitAvatars = { avatars: [] }; + + for (const item of this.metadata.filter((item) => + item.startsWith('ProfileAvatarEntity.'), + )) { + const stuff = item.get(StuffUIComponent, 'UIComponent'); + const avatar = item.get(ProfileAvatarComponent, 'profileAvatarComponent'); + const sellable = item.getOptional(SellableComponent, 'sellableComponent'); + + avatars.avatars.push({ + id: item.undiscriminatedId(), + name: stuff.display_name, + obtaining: stuff.obtaining_methods, + description: stuff.description, + grade: stuff.grade, + category: avatar.category, + hidden_if_not_obtained: avatar.hidden_if_not_obtained, + sale: sellable?.reward, + }); + } + + return avatars; + } +} diff --git a/packages/core/src/blitzkit/index.ts b/packages/core/src/blitzkit/index.ts index c5c879837..1d3dc134e 100644 --- a/packages/core/src/blitzkit/index.ts +++ b/packages/core/src/blitzkit/index.ts @@ -41,6 +41,7 @@ export * from './uniqueGuns'; export * from './unwrapBlitzkitResponse'; export * from './votes'; // export * from './withCORSProxy'; +export * from './api'; export * from './createDefaultProvisions'; export * from './gallery'; export * from './metaSortTank'; diff --git a/packages/website-ue/src/core/blitz/metadata.remote.ts b/packages/website-ue/src/core/blitz/metadata.remote.ts deleted file mode 100644 index 6db643f64..000000000 --- a/packages/website-ue/src/core/blitz/metadata.remote.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { RemoteMetadataAccessor } from 'packages/core/src'; - -export const remoteMetadata = new RemoteMetadataAccessor( - '/api/internal/catalog', -); diff --git a/packages/website-ue/src/core/blitz/metadata.socket.ts b/packages/website-ue/src/core/blitz/metadata.socket.ts deleted file mode 100644 index 675425f86..000000000 --- a/packages/website-ue/src/core/blitz/metadata.socket.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { fetchMetadata } from '@blitzkit/closed'; -import { SocketMetadataAccessor } from 'packages/core/src'; - -export const socketMetadata = new SocketMetadataAccessor( - await fetchMetadata(), -).injectBlitzkit(); diff --git a/packages/website-ue/src/core/blitz/metadata.ts b/packages/website-ue/src/core/blitz/metadata.ts deleted file mode 100644 index 39d886c20..000000000 --- a/packages/website-ue/src/core/blitz/metadata.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type { MetadataAccessor } from 'packages/core/src'; - -let accessor: MetadataAccessor; - -if (import.meta.env.SSR) { - accessor = await import('./metadata.socket').then((m) => m.socketMetadata); -} else { - accessor = await import('./metadata.remote').then((m) => m.remoteMetadata); -} - -export const metadata = accessor; diff --git a/packages/website-ue/src/core/blitzkit/api.ts b/packages/website-ue/src/core/blitzkit/api.ts deleted file mode 100644 index 7d11c7294..000000000 --- a/packages/website-ue/src/core/blitzkit/api.ts +++ /dev/null @@ -1,11 +0,0 @@ -let base: string; - -if (import.meta.env.DEV) { - base = 'http://localhost:4321'; -} else { - base = import.meta.env.SITE; -} - -export function api(path: string) { - return `${base}/api/${path}`; -} diff --git a/packages/website-ue/src/core/blitzkit/api/client.ts b/packages/website-ue/src/core/blitzkit/api/client.ts new file mode 100644 index 000000000..afdb8451a --- /dev/null +++ b/packages/website-ue/src/core/blitzkit/api/client.ts @@ -0,0 +1,3 @@ +import { BlitzkitClientAPI } from '@blitzkit/core'; + +export const api = new BlitzkitClientAPI(); diff --git a/packages/website-ue/src/core/blitzkit/api/index.ts b/packages/website-ue/src/core/blitzkit/api/index.ts new file mode 100644 index 000000000..890098de8 --- /dev/null +++ b/packages/website-ue/src/core/blitzkit/api/index.ts @@ -0,0 +1,11 @@ +import type { BlitzkitAPI } from 'packages/core/src'; + +let api: BlitzkitAPI; + +if (import.meta.env.SSR) { + api = await import('./server').then((module) => module.api); +} else { + api = await import('./client').then((module) => module.api); +} + +export { api }; diff --git a/packages/website-ue/src/core/blitzkit/api/server.ts b/packages/website-ue/src/core/blitzkit/api/server.ts new file mode 100644 index 000000000..f6ac7e490 --- /dev/null +++ b/packages/website-ue/src/core/blitzkit/api/server.ts @@ -0,0 +1,6 @@ +import { fetchMetadata } from '@blitzkit/closed'; +import { BlitzkitServerAPI, MetadataAccessor } from '@blitzkit/core'; + +const metadata = await fetchMetadata(); +const accessor = new MetadataAccessor(metadata); +export const api = new BlitzkitServerAPI(accessor); diff --git a/packages/website-ue/src/pages/[...locale]/avatars/_index.tsx b/packages/website-ue/src/pages/[...locale]/avatars/_index.tsx index 0387fe967..4dea502cb 100644 --- a/packages/website-ue/src/pages/[...locale]/avatars/_index.tsx +++ b/packages/website-ue/src/pages/[...locale]/avatars/_index.tsx @@ -1,11 +1,10 @@ -import { BlitzkitAllAvatarsComponent } from '@protos/blitzkit_static_all_avatars_component'; import { MagnifyingGlassIcon } from '@radix-ui/react-icons'; import { Flex, Grid, Spinner, TextField } from '@radix-ui/themes'; import fuzzysort from 'fuzzysort'; import { debounce, times } from 'lodash-es'; import { AvatarGroup } from 'packages/website-ue/src/components/Avatars/Group'; import { PageWrapper } from 'packages/website-ue/src/components/PageWrapper'; -import { metadata } from 'packages/website-ue/src/core/blitz/metadata'; +import { api } from 'packages/website-ue/src/core/blitzkit/api'; import { LocaleProvider, useLocale, @@ -14,13 +13,7 @@ import { import type { MaybeSkeletonComponentProps } from 'packages/website-ue/src/types/maybeSkeletonComponentProps'; import { useCallback, useMemo, useRef, useState } from 'react'; -const allAvatars = await metadata - .get('BlitzkitAllAvatarsEntity.blitzkit_all_avatars') - .then((entity) => - entity - .get(BlitzkitAllAvatarsComponent, 'blitzkitAllAvatarsComponent') - .avatars.reverse(), - ); +const { avatars } = await api.avatars(); export function Page({ localeData }: LocaleAcceptorProps) { return ( @@ -39,7 +32,7 @@ function Content({ skeleton }: MaybeSkeletonComponentProps) { const [search, setSearch] = useState(null); const [searching, setSearching] = useState(false); const groups = useMemo(() => { - const avatars = allAvatars + const avatarsSorted = avatars .map((avatar) => ({ avatar, name: gameStrings[avatar.name] as string | undefined, @@ -52,9 +45,9 @@ function Content({ skeleton }: MaybeSkeletonComponentProps) { ? -1 : a.name.localeCompare(b.name), ); - const groups = new Map(); + const groups = new Map(); - for (const avatar of avatars) { + for (const avatar of avatarsSorted) { if (groups.has(avatar.name)) { groups.get(avatar.name)!.push(avatar); } else { diff --git a/packages/website-ue/src/pages/[...locale]/avatars/index.astro b/packages/website-ue/src/pages/[...locale]/avatars/index.astro index b1e50eff1..732bdcb6a 100644 --- a/packages/website-ue/src/pages/[...locale]/avatars/index.astro +++ b/packages/website-ue/src/pages/[...locale]/avatars/index.astro @@ -1,6 +1,6 @@ --- import { avatarsTool } from 'packages/website-ue/src/constants/tools'; -import { metadata } from 'packages/website-ue/src/core/blitz/metadata'; +import { api } from 'packages/website-ue/src/core/blitzkit/api'; import ToolLayout from 'packages/website-ue/src/layouts/ToolLayout.astro'; import { Page } from './_index'; @@ -8,11 +8,11 @@ export { getStaticPaths } from '../index.astro'; const { locale } = Astro.props; -const gameStrings = await metadata.stringsPartial(locale, [ +const gameStrings = await api.metadata.stringsPartial(locale, [ 'ProfileAvatarEntity__*', ]); --- - + diff --git a/packages/website-ue/src/pages/api/avatars/[id].webp.ts b/packages/website-ue/src/pages/api/avatars/[id].webp.ts index 2c46fa9ce..e6d780f11 100644 --- a/packages/website-ue/src/pages/api/avatars/[id].webp.ts +++ b/packages/website-ue/src/pages/api/avatars/[id].webp.ts @@ -1,29 +1,28 @@ import { ProfileAvatarComponent } from '@protos/blitz_static_profile_avatar_component'; -import type { APIRoute, GetStaticPaths, GetStaticPathsItem } from 'astro'; -import { socketMetadata } from 'packages/website-ue/src/core/blitz/metadata.socket'; +import type { BlitzKitAvatar } from '@protos/blitzkit'; +import type { APIRoute, GetStaticPaths } from 'astro'; +import { api } from 'packages/website-ue/src/core/blitzkit/api'; export const getStaticPaths: GetStaticPaths = async () => { - const paths: GetStaticPathsItem[] = []; - - for (const item in socketMetadata.items) { - if (!item.startsWith('ProfileAvatarEntity.')) continue; - - const id = await socketMetadata - .get(item) - .then((item) => item.undiscriminatedId()); - - paths.push({ params: { id } }); - } - - return paths; + const { avatars } = await api.avatars(); + return avatars.map((avatar) => ({ + params: { id: avatar.id }, + props: { avatar }, + })); }; -export const GET: APIRoute<{}, { id: string }> = async ({ params }) => { - const item = await socketMetadata.get(`ProfileAvatarEntity.${params.id}`); +export const GET: APIRoute< + { avatar: BlitzKitAvatar }, + { id: string } +> = async ({ params }) => { + const item = api.metadata.get(`ProfileAvatarEntity.${params.id}`); const avatar = item.get(ProfileAvatarComponent, 'profileAvatarComponent'); try { - return await fetch(avatar.avatar); + const response = await fetch(avatar.avatar); + const buffer = await response.arrayBuffer(); + + return new Response(buffer, { headers: response.headers }); } catch { return new Response(null, { status: 404 }); } diff --git a/packages/website-ue/src/pages/api/internal/avatars.pb.ts b/packages/website-ue/src/pages/api/internal/avatars.pb.ts new file mode 100644 index 000000000..2c64dc5bb --- /dev/null +++ b/packages/website-ue/src/pages/api/internal/avatars.pb.ts @@ -0,0 +1,7 @@ +import { BlitzKitAvatars } from '@protos/blitzkit'; +import type { APIRoute } from 'astro'; +import { api } from 'packages/website-ue/src/core/blitzkit/api'; + +export const GET: APIRoute = async () => { + return new Response(BlitzKitAvatars.encode(await api.avatars()).finish()); +}; diff --git a/packages/website-ue/src/pages/api/internal/catalog/[item].pb.ts b/packages/website-ue/src/pages/api/internal/catalog/[item].pb.ts deleted file mode 100644 index 5a9409c48..000000000 --- a/packages/website-ue/src/pages/api/internal/catalog/[item].pb.ts +++ /dev/null @@ -1,19 +0,0 @@ -import type { APIRoute, GetStaticPaths, GetStaticPathsItem } from 'astro'; -import { socketMetadata } from 'packages/website-ue/src/core/blitz/metadata.socket'; - -export const getStaticPaths: GetStaticPaths = () => { - const paths: GetStaticPathsItem[] = []; - - for (const item in socketMetadata.items) { - paths.push({ params: { item } }); - } - - return paths; -}; - -export const GET: APIRoute<{}, { item: string }> = async ({ params }) => { - return new Response( - await socketMetadata.get(params.item).then((item) => item.encode()), - { headers: { 'Content-Type': 'application/octet-stream' } }, - ); -}; diff --git a/submodules/blitzkit-closed b/submodules/blitzkit-closed index 7f4ec5f5b..cba6a7bfa 160000 --- a/submodules/blitzkit-closed +++ b/submodules/blitzkit-closed @@ -1 +1 @@ -Subproject commit 7f4ec5f5bc17d7dbd778398e888bcefc846e0080 +Subproject commit cba6a7bfabdb6d6c7419553774166aa459d52d52