diff --git a/package.json b/package.json index 5fb6026..6fc3ea1 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,9 @@ "@nestjs/common": "10.3.8", "@nestjs/core": "10.3.8", "@nestjs/microservices": "^10.3.8", - "@t3-oss/env-core": "^0.10.1", + "@t3-oss/env-core": "0.8.0", + "got-cjs": "^12.5.4", + "memoizee": "^0.4.15", "slonik": "^45.4.1", "slonik-interceptor-query-logging": "^45.4.1", "tslib": "^2.6.2", @@ -29,6 +31,7 @@ "@swc-node/register": "~1.9.1", "@swc/core": "~1.5.7", "@swc/helpers": "~0.5.11", + "@types/memoizee": "^0.4.11", "@types/node": "20.12.12", "@typescript-eslint/eslint-plugin": "^7.3.0", "@typescript-eslint/parser": "^7.3.0", @@ -39,6 +42,7 @@ "npm-check-updates": "^16.14.20", "nx": "19.0.6", "prettier": "^2.6.2", + "prettier-plugin-organize-imports": "^3.2.4", "tsx": "^4.11.0", "typescript": "~5.4.5", "vite": "~5.2.11", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9374b3c..5ac0604 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -24,8 +24,14 @@ importers: specifier: ^10.3.8 version: 10.3.8(@nestjs/common@10.3.8(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.3.8)(reflect-metadata@0.1.14)(rxjs@7.8.1) '@t3-oss/env-core': - specifier: ^0.10.1 - version: 0.10.1(typescript@5.4.5)(zod@3.23.8) + specifier: 0.8.0 + version: 0.8.0(typescript@5.4.5)(zod@3.23.8) + got-cjs: + specifier: ^12.5.4 + version: 12.5.4 + memoizee: + specifier: ^0.4.15 + version: 0.4.15 slonik: specifier: ^45.4.1 version: 45.4.1(zod@3.23.8) @@ -69,6 +75,9 @@ importers: '@swc/helpers': specifier: ~0.5.11 version: 0.5.11 + '@types/memoizee': + specifier: ^0.4.11 + version: 0.4.11 '@types/node': specifier: 20.12.12 version: 20.12.12 @@ -99,6 +108,9 @@ importers: prettier: specifier: ^2.6.2 version: 2.8.8 + prettier-plugin-organize-imports: + specifier: ^3.2.4 + version: 3.2.4(prettier@2.8.8)(typescript@5.4.5) tsx: specifier: ^4.11.0 version: 4.11.0 @@ -1375,6 +1387,10 @@ packages: '@sinclair/typebox@0.27.8': resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + '@sindresorhus/is@4.6.0': + resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} + engines: {node: '>=10'} + '@sindresorhus/is@5.6.0': resolution: {integrity: sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==} engines: {node: '>=14.16'} @@ -1512,12 +1528,16 @@ packages: '@swc/types@0.1.7': resolution: {integrity: sha512-scHWahbHF0eyj3JsxG9CFJgFdFNaVQCNAimBlT6PzS3n/HptxqREjsm4OH6AN3lYcffZYSPxXW8ua2BEHp0lJQ==} + '@szmarczak/http-timer@4.0.6': + resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==} + engines: {node: '>=10'} + '@szmarczak/http-timer@5.0.1': resolution: {integrity: sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==} engines: {node: '>=14.16'} - '@t3-oss/env-core@0.10.1': - resolution: {integrity: sha512-GcKZiCfWks5CTxhezn9k5zWX3sMDIYf6Kaxy2Gx9YEQftFcz8hDRN56hcbylyAO3t4jQnQ5ifLawINsNgCDpOg==} + '@t3-oss/env-core@0.8.0': + resolution: {integrity: sha512-Tc1pg0KH/tJeI0Z1s/Isp1VsGDj1N03ZAYFV8GjWgMxytF/ve0Dv+opjmTapHICRv8qiB1Y/fsTjkWNMpKPRCQ==} peerDependencies: typescript: '>=5.0.0' zod: ^3.0.0 @@ -1555,12 +1575,18 @@ packages: '@types/http-cache-semantics@4.0.4': resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==} + '@types/memoizee@0.4.11': + resolution: {integrity: sha512-2gyorIBZu8GoDr9pYjROkxWWcFtHCquF7TVbN2I+/OvgZhnIGQS0vX5KJz4lXNKb8XOSfxFOSG5OLru1ESqLUg==} + '@types/node@20.12.12': resolution: {integrity: sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==} '@types/parse-json@4.0.2': resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} + '@types/responselike@1.0.0': + resolution: {integrity: sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==} + '@types/semver-utils@1.1.3': resolution: {integrity: sha512-T+YwkslhsM+CeuhYUxyAjWm7mJ5am/K10UX40RuA6k6Lc7eGtq8iY2xOzy7Vq0GOqhl/xZl5l2FwURZMTPTUww==} @@ -1887,6 +1913,10 @@ packages: resolution: {integrity: sha512-/aJwG2l3ZMJ1xNAnqbMpA40of9dj/pIH3QfiuQSqjfPJF747VR0J/bHn+/KdNnHKc6XQcWt/AfRSBft82W1d2A==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + cacheable-lookup@6.1.0: + resolution: {integrity: sha512-KJ/Dmo1lDDhmW2XDPMo+9oiy/CeqosPguPCrgcVzKyZrL6pM1gU2GmPY/xo6OQPTUaA/c0kwHuywB4E6nmT9ww==} + engines: {node: '>=10.6.0'} + cacheable-lookup@7.0.0: resolution: {integrity: sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==} engines: {node: '>=14.16'} @@ -1895,6 +1925,10 @@ packages: resolution: {integrity: sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==} engines: {node: '>=14.16'} + cacheable-request@7.0.2: + resolution: {integrity: sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==} + engines: {node: '>=8'} + call-bind@1.0.7: resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} engines: {node: '>= 0.4'} @@ -1965,6 +1999,9 @@ packages: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} + clone-response@1.0.3: + resolution: {integrity: sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==} + clone@1.0.4: resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} engines: {node: '>=0.8'} @@ -2062,6 +2099,10 @@ packages: resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==} engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + d@1.0.2: + resolution: {integrity: sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==} + engines: {node: '>=0.12'} + de-indent@1.0.2: resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==} @@ -2211,6 +2252,20 @@ packages: resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} engines: {node: '>= 0.4'} + es5-ext@0.10.64: + resolution: {integrity: sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==} + engines: {node: '>=0.10'} + + es6-iterator@2.0.3: + resolution: {integrity: sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==} + + es6-symbol@3.1.4: + resolution: {integrity: sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==} + engines: {node: '>=0.12'} + + es6-weak-map@2.0.3: + resolution: {integrity: sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==} + esbuild@0.20.2: resolution: {integrity: sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==} engines: {node: '>=12'} @@ -2251,6 +2306,10 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true + esniff@2.0.1: + resolution: {integrity: sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==} + engines: {node: '>=0.10'} + espree@9.6.1: resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -2282,6 +2341,9 @@ packages: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} + event-emitter@0.3.5: + resolution: {integrity: sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==} + eventemitter3@4.0.7: resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} @@ -2292,6 +2354,9 @@ packages: exponential-backoff@3.1.1: resolution: {integrity: sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==} + ext@1.7.0: + resolution: {integrity: sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==} + fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -2368,6 +2433,9 @@ packages: resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} engines: {node: '>=14'} + form-data-encoder@1.7.2: + resolution: {integrity: sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==} + form-data-encoder@2.1.4: resolution: {integrity: sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==} engines: {node: '>= 14.17'} @@ -2434,6 +2502,10 @@ packages: resolution: {integrity: sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==} engines: {node: '>=10'} + get-stream@5.2.0: + resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} + engines: {node: '>=8'} + get-stream@6.0.1: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} @@ -2484,6 +2556,10 @@ packages: gopd@1.0.1: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + got-cjs@12.5.4: + resolution: {integrity: sha512-Uas6lAsP8bRCt5WXGMhjFf/qEHTrm4v4qxGR02rLG2kdG9qedctvlkdwXVcDJ7Cs84X+r4dPU7vdwGjCaspXug==} + engines: {node: '>=12'} + got@12.6.1: resolution: {integrity: sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==} engines: {node: '>=14.16'} @@ -2701,6 +2777,9 @@ packages: resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} engines: {node: '>=8'} + is-promise@2.2.2: + resolution: {integrity: sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==} + is-reference@3.0.2: resolution: {integrity: sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==} @@ -2888,6 +2967,10 @@ packages: lower-case@2.0.2: resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + lowercase-keys@2.0.0: + resolution: {integrity: sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==} + engines: {node: '>=8'} + lowercase-keys@3.0.0: resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -2903,6 +2986,9 @@ packages: resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} engines: {node: '>=12'} + lru-queue@0.1.0: + resolution: {integrity: sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==} + magic-string@0.30.10: resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==} @@ -2927,6 +3013,9 @@ packages: mdn-data@2.0.30: resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} + memoizee@0.4.15: + resolution: {integrity: sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==} + merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} @@ -2959,6 +3048,10 @@ packages: resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} engines: {node: '>=12'} + mimic-response@1.0.1: + resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==} + engines: {node: '>=4'} + mimic-response@3.1.0: resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} engines: {node: '>=10'} @@ -3062,6 +3155,9 @@ packages: resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} engines: {node: '>= 0.6'} + next-tick@1.1.0: + resolution: {integrity: sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==} + no-case@3.0.4: resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} @@ -3094,6 +3190,10 @@ packages: resolution: {integrity: sha512-h9iPVIfrVZ9wVYQnxFgtw1ugSvGEMOlyPWWtm8BMJhnwyEL/FLbYbTY3V3PpjI/BUK67n9PEWDu6eHzu1fB15Q==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + normalize-url@6.1.0: + resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} + engines: {node: '>=10'} + normalize-url@8.0.1: resolution: {integrity: sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==} engines: {node: '>=14.16'} @@ -3193,6 +3293,10 @@ packages: resolution: {integrity: sha512-zAKMgGXUim0Jyd6CXK9lraBnD3H5yPGBPPOkC23a2BG6hsm4Zu6OQSjQuEtV0BHDf4aKHcUFvJiGRrFuW3MG8g==} engines: {node: '>=10'} + p-cancelable@2.1.1: + resolution: {integrity: sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==} + engines: {node: '>=8'} + p-cancelable@3.0.0: resolution: {integrity: sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==} engines: {node: '>=12.20'} @@ -3401,6 +3505,19 @@ packages: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} + prettier-plugin-organize-imports@3.2.4: + resolution: {integrity: sha512-6m8WBhIp0dfwu0SkgfOxJqh+HpdyfqSSLfKKRZSFbDuEQXDDndb8fTpRWkUrX/uBenkex3MgnVk0J3b3Y5byog==} + peerDependencies: + '@volar/vue-language-plugin-pug': ^1.0.4 + '@volar/vue-typescript': ^1.0.4 + prettier: '>=2.0' + typescript: '>=2.9' + peerDependenciesMeta: + '@volar/vue-language-plugin-pug': + optional: true + '@volar/vue-typescript': + optional: true + prettier@2.8.8: resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} engines: {node: '>=10.13.0'} @@ -3444,6 +3561,9 @@ packages: proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + pump@3.0.0: + resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} + punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -3547,6 +3667,9 @@ packages: resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} hasBin: true + responselike@2.0.1: + resolution: {integrity: sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==} + responselike@3.0.0: resolution: {integrity: sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==} engines: {node: '>=14.16'} @@ -3847,6 +3970,9 @@ packages: through@2.3.8: resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + timers-ext@0.1.7: + resolution: {integrity: sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==} + tinybench@2.8.0: resolution: {integrity: sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==} @@ -3940,6 +4066,9 @@ packages: resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} engines: {node: '>=12.20'} + type@2.7.2: + resolution: {integrity: sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==} + typedarray-to-buffer@3.1.5: resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==} @@ -5676,6 +5805,8 @@ snapshots: '@sinclair/typebox@0.27.8': {} + '@sindresorhus/is@4.6.0': {} + '@sindresorhus/is@5.6.0': {} '@slonik/driver@45.4.1(zod@3.23.8)': @@ -5809,11 +5940,15 @@ snapshots: dependencies: '@swc/counter': 0.1.3 + '@szmarczak/http-timer@4.0.6': + dependencies: + defer-to-connect: 2.0.1 + '@szmarczak/http-timer@5.0.1': dependencies: defer-to-connect: 2.0.1 - '@t3-oss/env-core@0.10.1(typescript@5.4.5)(zod@3.23.8)': + '@t3-oss/env-core@0.8.0(typescript@5.4.5)(zod@3.23.8)': dependencies: zod: 3.23.8 optionalDependencies: @@ -5840,12 +5975,18 @@ snapshots: '@types/http-cache-semantics@4.0.4': {} + '@types/memoizee@0.4.11': {} + '@types/node@20.12.12': dependencies: undici-types: 5.26.5 '@types/parse-json@4.0.2': {} + '@types/responselike@1.0.0': + dependencies: + '@types/node': 20.12.12 + '@types/semver-utils@1.1.3': {} '@typescript-eslint/eslint-plugin@7.10.0(@typescript-eslint/parser@7.10.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5)': @@ -6283,6 +6424,8 @@ snapshots: tar: 6.2.1 unique-filename: 3.0.0 + cacheable-lookup@6.1.0: {} + cacheable-lookup@7.0.0: {} cacheable-request@10.2.14: @@ -6295,6 +6438,16 @@ snapshots: normalize-url: 8.0.1 responselike: 3.0.0 + cacheable-request@7.0.2: + dependencies: + clone-response: 1.0.3 + get-stream: 5.2.0 + http-cache-semantics: 4.1.1 + keyv: 4.5.4 + lowercase-keys: 2.0.0 + normalize-url: 6.1.0 + responselike: 2.0.1 + call-bind@1.0.7: dependencies: es-define-property: 1.0.0 @@ -6364,6 +6517,10 @@ snapshots: strip-ansi: 6.0.1 wrap-ansi: 7.0.0 + clone-response@1.0.3: + dependencies: + mimic-response: 1.0.1 + clone@1.0.4: {} code-red@1.0.4: @@ -6461,6 +6618,11 @@ snapshots: mdn-data: 2.0.30 source-map-js: 1.2.0 + d@1.0.2: + dependencies: + es5-ext: 0.10.64 + type: 2.7.2 + de-indent@1.0.2: {} debug@3.2.7: @@ -6575,6 +6737,31 @@ snapshots: es-errors@1.3.0: {} + es5-ext@0.10.64: + dependencies: + es6-iterator: 2.0.3 + es6-symbol: 3.1.4 + esniff: 2.0.1 + next-tick: 1.1.0 + + es6-iterator@2.0.3: + dependencies: + d: 1.0.2 + es5-ext: 0.10.64 + es6-symbol: 3.1.4 + + es6-symbol@3.1.4: + dependencies: + d: 1.0.2 + ext: 1.7.0 + + es6-weak-map@2.0.3: + dependencies: + d: 1.0.2 + es5-ext: 0.10.64 + es6-iterator: 2.0.3 + es6-symbol: 3.1.4 + esbuild@0.20.2: optionalDependencies: '@esbuild/aix-ppc64': 0.20.2 @@ -6663,6 +6850,13 @@ snapshots: transitivePeerDependencies: - supports-color + esniff@2.0.1: + dependencies: + d: 1.0.2 + es5-ext: 0.10.64 + event-emitter: 0.3.5 + type: 2.7.2 + espree@9.6.1: dependencies: acorn: 8.11.3 @@ -6689,6 +6883,11 @@ snapshots: esutils@2.0.3: {} + event-emitter@0.3.5: + dependencies: + d: 1.0.2 + es5-ext: 0.10.64 + eventemitter3@4.0.7: {} execa@8.0.1: @@ -6705,6 +6904,10 @@ snapshots: exponential-backoff@3.1.1: {} + ext@1.7.0: + dependencies: + type: 2.7.2 + fast-deep-equal@3.1.3: {} fast-glob@3.2.7: @@ -6779,6 +6982,8 @@ snapshots: cross-spawn: 7.0.3 signal-exit: 4.1.0 + form-data-encoder@1.7.2: {} + form-data-encoder@2.1.4: {} form-data@4.0.0: @@ -6843,6 +7048,10 @@ snapshots: get-stdin@8.0.0: {} + get-stream@5.2.0: + dependencies: + pump: 3.0.0 + get-stream@6.0.1: {} get-stream@8.0.1: {} @@ -6907,6 +7116,21 @@ snapshots: dependencies: get-intrinsic: 1.2.4 + got-cjs@12.5.4: + dependencies: + '@sindresorhus/is': 4.6.0 + '@szmarczak/http-timer': 4.0.6 + '@types/responselike': 1.0.0 + cacheable-lookup: 6.1.0 + cacheable-request: 7.0.2 + decompress-response: 6.0.0 + form-data-encoder: 1.7.2 + get-stream: 6.0.1 + http2-wrapper: 2.2.1 + lowercase-keys: 2.0.0 + p-cancelable: 2.1.1 + responselike: 2.0.1 + got@12.6.1: dependencies: '@sindresorhus/is': 5.6.0 @@ -7114,6 +7338,8 @@ snapshots: is-path-inside@3.0.3: {} + is-promise@2.2.2: {} + is-reference@3.0.2: dependencies: '@types/estree': 1.0.5 @@ -7284,6 +7510,8 @@ snapshots: dependencies: tslib: 2.6.2 + lowercase-keys@2.0.0: {} + lowercase-keys@3.0.0: {} lru-cache@10.2.2: {} @@ -7294,6 +7522,10 @@ snapshots: lru-cache@7.18.3: {} + lru-queue@0.1.0: + dependencies: + es5-ext: 0.10.64 + magic-string@0.30.10: dependencies: '@jridgewell/sourcemap-codec': 1.4.15 @@ -7354,6 +7586,17 @@ snapshots: mdn-data@2.0.30: {} + memoizee@0.4.15: + dependencies: + d: 1.0.2 + es5-ext: 0.10.64 + es6-weak-map: 2.0.3 + event-emitter: 0.3.5 + is-promise: 2.2.2 + lru-queue: 0.1.0 + next-tick: 1.1.0 + timers-ext: 0.1.7 + merge-stream@2.0.0: {} merge2@1.4.1: {} @@ -7375,6 +7618,8 @@ snapshots: mimic-fn@4.0.0: {} + mimic-response@1.0.1: {} + mimic-response@3.1.0: {} mimic-response@4.0.0: {} @@ -7472,6 +7717,8 @@ snapshots: negotiator@0.6.3: {} + next-tick@1.1.0: {} + no-case@3.0.4: dependencies: lower-case: 2.0.2 @@ -7515,6 +7762,8 @@ snapshots: semver: 7.6.2 validate-npm-package-license: 3.0.4 + normalize-url@6.1.0: {} + normalize-url@8.0.1: {} npm-bundled@3.0.1: @@ -7713,6 +7962,8 @@ snapshots: strip-ansi: 6.0.1 wcwidth: 1.0.1 + p-cancelable@2.1.1: {} + p-cancelable@3.0.0: {} p-limit@3.1.0: @@ -7921,6 +8172,11 @@ snapshots: prelude-ls@1.2.1: {} + prettier-plugin-organize-imports@3.2.4(prettier@2.8.8)(typescript@5.4.5): + dependencies: + prettier: 2.8.8 + typescript: 5.4.5 + prettier@2.8.8: {} pretty-format@29.7.0: @@ -7953,6 +8209,11 @@ snapshots: proxy-from-env@1.1.0: {} + pump@3.0.0: + dependencies: + end-of-stream: 1.4.4 + once: 1.4.0 + punycode@2.3.1: {} pupa@3.1.0: @@ -8058,6 +8319,10 @@ snapshots: path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 + responselike@2.0.1: + dependencies: + lowercase-keys: 2.0.0 + responselike@3.0.0: dependencies: lowercase-keys: 3.0.0 @@ -8392,6 +8657,11 @@ snapshots: through@2.3.8: {} + timers-ext@0.1.7: + dependencies: + es5-ext: 0.10.64 + next-tick: 1.1.0 + tinybench@2.8.0: {} tinypool@0.8.4: {} @@ -8473,6 +8743,8 @@ snapshots: type-fest@2.19.0: {} + type@2.7.2: {} + typedarray-to-buffer@3.1.5: dependencies: is-typedarray: 1.0.0 diff --git a/src/index.ts b/src/index.ts index 81f0e04..63f1269 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1 +1,2 @@ export * from './lib/sui-data-sync'; + diff --git a/src/lib/api/index.ts b/src/lib/api/index.ts new file mode 100644 index 0000000..5ca653b --- /dev/null +++ b/src/lib/api/index.ts @@ -0,0 +1,64 @@ +import got from 'got-cjs'; +import { env } from '../env'; +import { + SUIQueryRequest, + SUIQueryResponse, + SUIQuerySchema, +} from '../model/json-rpc'; + +class QueryInconsistencyError extends Error { + constructor(message: string) { + super(message); + this.name = 'QueryInconsistencyError'; + } +} + +export async function sui_query( + method: T['method'], + params: T['request'], +): Promise { + const randomID = Math.floor(Math.random() * 1000000); + const request = SUIQueryRequest.parse({ + jsonrpc: '2.0', + id: randomID, + method: method, + params: params, + }); + + const data = await got + .post(env().SUI_NODE_RPC_URL, { + json: request, + }) + .json(); + + const typedData = SUIQueryResponse.parse(data); + if (typedData.id !== randomID) { + throw new QueryInconsistencyError( + `Invalid response id: ${typedData.id}, expected: ${randomID}`, + ); + } + + const validator = SUIQuerySchema.parse({ + method, + request: params, + response: typedData.result, + }); + + return validator.response; +} + +// sui_query('suix_queryEvents', [ +// { +// MoveEventType: +// '0xceba50ec29ada96392373f340fe4eeffab45140ac66acc9459770e5a3c58abf8::simple_gift_box::GiftBoxMinted', +// }, +// { +// txDigest: 'DHs2b8Cipw2iT9G5cCh1vY1NxevyqerELYnAFo3Jn1dA', +// eventSeq: '2', +// }, +// 1, +// true, +// ]).then(a => { +// console.log(a); +// }); //? +// diff --git a/src/lib/env.ts b/src/lib/env.ts new file mode 100644 index 0000000..a3283d8 --- /dev/null +++ b/src/lib/env.ts @@ -0,0 +1,26 @@ +import { createEnv } from '@t3-oss/env-core'; +import memoizee from 'memoizee'; +import { z } from 'zod'; +import { EnvSUINodeRPCSchema, SUI_ENV } from './model/env.model'; + +export const env = memoizee(() => { + const envObj = createEnv({ + server: { + SUI_NODE_RPC_URL: z.string().optional(), + SUI_ENV: SUI_ENV.default('devnet'), + }, + runtimeEnv: process.env, + }); + + let SUI_NODE_RPC_URL = envObj.SUI_NODE_RPC_URL; + if (SUI_NODE_RPC_URL == null) { + SUI_NODE_RPC_URL = EnvSUINodeRPCSchema.parse(envObj.SUI_ENV); + } + + return { + ...envObj, + SUI_NODE_RPC_URL, + }; +}); + +env().SUI_NODE_RPC_URL; //? diff --git a/src/lib/model/env.model.ts b/src/lib/model/env.model.ts new file mode 100644 index 0000000..30135e1 --- /dev/null +++ b/src/lib/model/env.model.ts @@ -0,0 +1,22 @@ +import { z } from 'zod'; + +export const EnvSUINodeRPCSchema = z.preprocess((val, ctx) => { + if (typeof val === 'string') { + if (val === 'devnet') { + return 'https://fullnode.devnet.sui.io'; + } + if (val === 'testnet') { + return 'https://fullnode.testnet.sui.io'; + } + if (val === 'mainnet') { + return 'https://fullnode.mainnet.sui.io'; + } + } + ctx.addIssue({ + message: `val is not a string: ${val}`, + code: 'custom', + }); + return z.NEVER; +}, z.string()); + +export const SUI_ENV = z.enum(['devnet', 'testnet', 'mainnet']); \ No newline at end of file diff --git a/src/lib/model/json-rpc/base.model.ts b/src/lib/model/json-rpc/base.model.ts new file mode 100644 index 0000000..226afcc --- /dev/null +++ b/src/lib/model/json-rpc/base.model.ts @@ -0,0 +1,76 @@ +import { z } from 'zod'; + +export function makePaginationResponseSchema(data: z.ZodType) { + return z.object({ + data: z.array(data), + hasNextPage: z.boolean(), + nextCursor: z + .object({ + txDigest: z.string(), + eventSeq: z.string(), + }) + .nullish(), + }); +} + +const EventFilterTransaction = z.object({ + Transaction: z.string(), +}); +const EventFilterMoveModule = z.object({ + MoveModule: z.object({ + package: z.string(), + module: z.string(), + }), +}); +const EventFilterMoveEventModule = z.object({ + MoveEventModule: z.object({ + package: z.string(), + module: z.string(), + }), +}); +const EventFilterMoveEvent = z.object({ + MoveEvent: z.string(), +}); +const EventFilterEventType = z.object({ + EventType: z.string(), +}); +const EventFilterMoveEventType = z.object({ + MoveEventType: z.string(), +}); +const EventFilterSender = z.object({ + Sender: z.string(), +}); +const EventFilterRecipient = z.object({ + Recipient: z.object({ + AddressOwner: z.string(), + }), +}); +const EventFilterObject = z.object({ + Object: z.string(), +}); +const EventFilterTimeRange = z.object({ + TimeRange: z.object({ + startTime: z.number(), + endTime: z.number(), + }), +}); +const EventFilterAll = z.object({ + All: z.string(), +}); +export const EventFilter = z.union([ + EventFilterTransaction, + EventFilterMoveModule, + EventFilterMoveEventModule, + EventFilterMoveEvent, + EventFilterEventType, + EventFilterMoveEventType, + EventFilterSender, + EventFilterRecipient, + EventFilterObject, + EventFilterTimeRange, + EventFilterAll, +]); +export const PageCursorEvent = z.object({ + txDigest: z.string(), + eventSeq: z.string(), +}); \ No newline at end of file diff --git a/src/lib/model/json-rpc/index.ts b/src/lib/model/json-rpc/index.ts new file mode 100644 index 0000000..93b5e38 --- /dev/null +++ b/src/lib/model/json-rpc/index.ts @@ -0,0 +1,18 @@ +import { z } from 'zod'; +import { SUIMethod } from './query-schema.model'; + +export const SUIQueryRequest = z.object({ + jsonrpc: z.literal('2.0'), + id: z.number(), + method: SUIMethod, + params: z.array(z.any()), +}); + +export const SUIQueryResponse = z.object({ + jsonrpc: z.literal('2.0'), + id: z.number(), + result: z.any(), +}); + +export * from './base.model'; +export * from './query-schema.model'; diff --git a/src/lib/model/json-rpc/query-schema.model.ts b/src/lib/model/json-rpc/query-schema.model.ts new file mode 100644 index 0000000..8a908d6 --- /dev/null +++ b/src/lib/model/json-rpc/query-schema.model.ts @@ -0,0 +1,46 @@ +import { z } from 'zod'; +import { EventFilter, makePaginationResponseSchema, PageCursorEvent } from './base.model'; + +export const SUIMethod = z.enum([ + 'suix_queryEvents', + 'suix_queryTransactionBlocks', +]); + +/// - suix_queryEvents +const PageEvent = z.object({ + id: z.object({ + txDigest: z.string(), + eventSeq: z.string(), + }), + packageId: z.string(), + transactionModule: z.string(), + sender: z.string(), + type: z.string(), + parsedJson: z.any(), + bcs: z.string(), + timestampMs: z.string(), +}); +export const SUIQuerySchemaEvents = z.object({ + method: z.literal(SUIMethod.enum.suix_queryEvents), + request: z.tuple([ + EventFilter, //query + PageCursorEvent.nullish(), //cursor + z.number().nullish().default(50), //limit + z.boolean().nullish().default(true), //descending_order + ]), + response: makePaginationResponseSchema(PageEvent), +}); + +/// - suix_queryTransactionBlocks +export const SUIQuerySchemaTransactionBlocks = z.object({ + method: z.literal(SUIMethod.enum.suix_queryTransactionBlocks), + request: z.tuple([ + z.string(), //query + ]), + response: makePaginationResponseSchema(z.object({})), +}); +export const SUIQuerySchema = z.discriminatedUnion('method', [ + SUIQuerySchemaEvents, + SUIQuerySchemaTransactionBlocks, +]); +export type SUIQuerySchema = z.infer; \ No newline at end of file diff --git a/tools/bin/pkg-update b/tools/bin/pkg-update index b4f2029..aee85f4 100755 --- a/tools/bin/pkg-update +++ b/tools/bin/pkg-update @@ -1,4 +1,4 @@ #!/usr/bin/env bash set -euo pipefail -ncu -u -x prettier,eslint,eslint-config-prettier,@typescript-eslint/eslint-plugin,@typescript-eslint/parser +ncu -u -x prettier,eslint,eslint-config-prettier,@typescript-eslint/eslint-plugin,@typescript-eslint/parser,@t3-oss/env-core diff --git a/tsconfig.json b/tsconfig.json index cce4e6d..98fe746 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,12 +4,23 @@ "sourceMap": true, "declaration": false, "moduleResolution": "node", - "emitDecoratorMetadata": true, + "strict": true, + "noEmit": true, + "noImplicitReturns": true, + "noUnusedLocals": false, + "noUncheckedIndexedAccess": true, + "noFallthroughCasesInSwitch": true, + "noPropertyAccessFromIndexSignature": true, + "forceConsistentCasingInFileNames": true, + "exactOptionalPropertyTypes": false, + "esModuleInterop": true, "experimentalDecorators": true, + "emitDecoratorMetadata": true, + "resolveJsonModule": true, "importHelpers": true, - "target": "es2015", - "module": "commonjs", - "lib": ["es2020", "dom"], + "target": "es2022", + "module": "ES2022", + "lib": ["es2021", "dom"], "skipLibCheck": true, "skipDefaultLibCheck": true, "baseUrl": ".",