fossyl 0.1.6 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +107 -0
- package/LICENSE +674 -0
- package/README.md +3 -99
- package/bin/fossyl.js +2 -0
- package/dist/index.d.mts +1 -203
- package/dist/index.d.ts +1 -203
- package/dist/index.js +1247 -69
- package/dist/index.mjs +1239 -60
- package/package.json +26 -24
- package/fossyl.svg +0 -2
- package/src/example.ts +0 -31
- package/src/index.ts +0 -22
- package/src/router/router.ts +0 -277
- package/src/router/tmp.sh +0 -15
- package/src/router/types/configuration.types.ts +0 -143
- package/src/router/types/params.types.ts +0 -13
- package/src/router/types/router-creation.types.ts +0 -36
- package/src/router/types/routes.types.ts +0 -124
package/package.json
CHANGED
|
@@ -1,50 +1,52 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fossyl",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
|
|
6
|
-
"
|
|
3
|
+
"version": "0.10.0",
|
|
4
|
+
"description": "CLI for scaffolding fossyl projects",
|
|
5
|
+
"bin": {
|
|
6
|
+
"fossyl": "./bin/fossyl.js"
|
|
7
7
|
},
|
|
8
|
-
"homepage": "https://github.com/YoyoSaur/fossyl#readme",
|
|
9
|
-
"bugs": {
|
|
10
|
-
"url": "https://github.com/YoyoSaur/fossyl/issues"
|
|
11
|
-
},
|
|
12
|
-
"description": "Type-safe REST API framework core - designed for AI-assisted development",
|
|
13
8
|
"main": "./dist/index.js",
|
|
14
9
|
"module": "./dist/index.mjs",
|
|
15
10
|
"types": "./dist/index.d.ts",
|
|
16
11
|
"exports": {
|
|
17
12
|
".": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
18
14
|
"import": "./dist/index.mjs",
|
|
19
|
-
"require": "./dist/index.js"
|
|
20
|
-
"types": "./dist/index.d.ts"
|
|
15
|
+
"require": "./dist/index.js"
|
|
21
16
|
}
|
|
22
17
|
},
|
|
23
18
|
"files": [
|
|
19
|
+
"bin",
|
|
24
20
|
"dist",
|
|
25
|
-
"
|
|
26
|
-
"CLAUDE.md",
|
|
27
|
-
"README.md",
|
|
28
|
-
"fossyl.svg"
|
|
21
|
+
"CLAUDE.md"
|
|
29
22
|
],
|
|
30
23
|
"keywords": [
|
|
31
|
-
"
|
|
24
|
+
"fossyl",
|
|
25
|
+
"cli",
|
|
26
|
+
"scaffolding",
|
|
32
27
|
"rest-api",
|
|
33
|
-
"
|
|
34
|
-
"router",
|
|
35
|
-
"framework",
|
|
36
|
-
"ai-assisted",
|
|
37
|
-
"functional"
|
|
28
|
+
"typescript"
|
|
38
29
|
],
|
|
39
30
|
"author": "YoyoSaur",
|
|
40
|
-
"license": "
|
|
31
|
+
"license": "GPL-3.0",
|
|
32
|
+
"repository": {
|
|
33
|
+
"type": "git",
|
|
34
|
+
"url": "https://github.com/YoyoSaur/fossyl.git",
|
|
35
|
+
"directory": "packages/cli"
|
|
36
|
+
},
|
|
37
|
+
"homepage": "https://github.com/YoyoSaur/fossyl#readme",
|
|
38
|
+
"bugs": {
|
|
39
|
+
"url": "https://github.com/YoyoSaur/fossyl/issues"
|
|
40
|
+
},
|
|
41
41
|
"publishConfig": {
|
|
42
42
|
"access": "public"
|
|
43
43
|
},
|
|
44
|
-
"dependencies": {
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"@clack/prompts": "^0.7.0"
|
|
46
|
+
},
|
|
45
47
|
"devDependencies": {
|
|
46
48
|
"tsup": "^8.0.0",
|
|
47
|
-
"typescript": "^5.8.
|
|
49
|
+
"typescript": "^5.8.0"
|
|
48
50
|
},
|
|
49
51
|
"scripts": {
|
|
50
52
|
"build": "tsup src/index.ts --format cjs,esm --dts",
|
package/fossyl.svg
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
-
<svg width="450mm" height="350mm" viewBox="0 0 450 350" version="1.1" id="svg1" xmlns="http://www.w3.org/2000/svg"><defs><radialGradient gradientUnits="userSpaceOnUse" cx="213.832" cy="203.054" r="251.632" id="gradient-1"><stop offset="0" style="stop-color: rgb(97.255% 90.98% 83.922%)"/><stop offset="1" style="stop-color: rgb(56.949% 51.436% 45.073%)"/></radialGradient></defs><g id="layer1" style="display: inline;" transform="matrix(0.749682, 0, 0, 0.749682, 56.32156, 43.805634)"><circle style="transform-origin: 213.832px 203.054px; fill: rgb(147, 82, 9);" cx="213.832" cy="203.054" r="251.632" transform="matrix(1.055191, -0.194654, 0.150423, 0.82458, 11.167999, -28.053988)"/><circle style="fill: rgb(98, 56, 9); transform-origin: 213.832px 203.054px;" cx="213.832" cy="203.054" r="231.764" transform="matrix(1.055191, -0.194654, 0.150423, 0.82458, 11.168001, -28.053976)"/><g transform="matrix(0.996725, -0.080867, 0.080867, 0.996725, 0.089563, -7.482402)" style="transform-origin: 224.91px 182.482px;"><path style="baseline-shift: baseline; display: inline; overflow: visible; vector-effect: none; fill: rgb(218, 136, 37); fill-rule: evenodd; stroke-width: 0.264583; stop-color: rgb(0, 0, 0); stroke: none; pointer-events: none;" d="m 354.69417,253.32154 -64.93941,-10.78033 0.14999,-6.92654 c 0.2449,-11.30872 -1.33154,-21.82798 -4.88543,-32.59962 -1.57414,-4.77117 -5.9346,-14.30266 -8.14517,-17.80441 l -1.05307,-1.66817 4.13176,-0.45241 c 14.28465,-1.56412 33.43659,-1.83922 47.55613,-0.6831 19.72903,1.61542 39.56296,5.1523 59.65777,10.63844 8.52303,2.32688 30.97602,9.63741 32.08084,10.44526 0.82481,0.60313 1.94048,7.75065 2.84684,18.23856 0.77298,8.94417 0.63709,30.0198 -0.24437,37.90383 -0.47337,4.23408 -0.5724,4.56213 -1.36345,4.51723 -0.46916,-0.0266 -30.07577,-4.89956 -65.79243,-10.82874 z" id="path58" clip-path="none" mask="none"/><path style="baseline-shift: baseline; display: inline; overflow: visible; vector-effect: none; fill: rgb(227, 188, 142); fill-rule: evenodd; stroke-width: 0.264583; stop-color: rgb(0, 0, 0); stroke: none; pointer-events: none;" d="m 411.31394,198.99225 c -26.67701,-9.33073 -53.98915,-15.3797 -80.35536,-17.79673 -16.48047,-1.51079 -42.4131,-1.11476 -54.60952,0.83397 -1.17896,0.18837 -1.41581,-0.0342 -4.65169,-4.37115 -4.09506,-5.48852 -10.5844,-12.06564 -15.72618,-15.93895 l -3.76332,-2.83492 8.22751,-4.07494 c 12.21877,-6.05173 21.46419,-9.72328 35.21554,-13.98484 25.96549,-8.04672 57.11264,-12.57494 86.52644,-12.57934 l 9.6207,-0.001 1.61222,2.7605 c 11.53771,19.75531 20.34743,42.64661 24.98407,64.91897 1.13504,5.45216 1.17888,5.79585 0.73192,5.7358 -0.1674,-0.0225 -3.68295,-1.22261 -7.81233,-2.66693 z" id="path56" clip-path="none" mask="none"/><path style="baseline-shift: baseline; display: inline; overflow: visible; vector-effect: none; fill: rgb(218, 136, 37); fill-rule: evenodd; stroke-width: 0.264583; stop-color: rgb(0, 0, 0); stroke: none; pointer-events: none;" d="m 246.9507,155.73452 c -4.7082,-2.8009 -12.57133,-6.171 -18.11866,-7.76557 -2.53246,-0.72795 -4.71037,-1.42944 -4.8398,-1.55886 -0.3944,-0.39441 7.86395,-9.49598 14.27374,-15.73116 21.15632,-20.58002 47.6814,-37.707933 79.50296,-51.337083 5.91061,-2.531507 19.23243,-7.682156 21.97357,-8.495686 0.68519,-0.203362 1.80644,0.507486 5.27585,3.344844 15.87642,12.984043 30.36178,29.082365 42.06404,46.747875 l 3.62931,5.47878 -10.97748,0.26565 c -12.44502,0.30117 -20.9605,0.83853 -31.51754,1.98885 -33.64923,3.66651 -64.81463,12.52634 -90.68736,25.78099 -3.66815,1.8792 -6.77279,3.39801 -6.8992,3.37513 -0.1264,-0.0229 -1.78215,-0.96507 -3.67943,-2.09376 z" id="path54" clip-path="none" mask="none"/><path style="baseline-shift: baseline; display: inline; overflow: visible; vector-effect: none; fill: rgb(227, 188, 142); fill-rule: evenodd; stroke-width: 0.264583; stop-color: rgb(0, 0, 0); stroke: none; pointer-events: none;" d="m 216.71598,145.4651 c -3.95031,-0.56221 -15.19596,-0.69375 -18.97279,-0.22194 -1.28346,0.16034 -2.33356,0.17919 -2.33356,0.0419 0,-0.55138 2.44815,-7.37991 4.26343,-11.89183 2.34624,-5.83162 7.73828,-16.86589 11.16804,-22.85428 6.31996,-11.034698 16.39722,-25.170763 25.7532,-36.125786 8.60136,-10.071441 23.85286,-25.031054 34.86989,-34.202563 l 4.36986,-3.637825 5.8819,2.031794 c 18.1888,6.282973 36.27988,15.688328 52.38787,27.235885 4.25987,3.053837 5.20665,3.963204 4.12631,3.963204 -0.24162,0 -3.36323,1.096614 -6.93693,2.436921 -27.23486,10.214367 -52.89489,24.001219 -73.18203,39.31991 -11.51773,8.69697 -26.40899,22.57061 -33.27848,31.00433 -1.92166,2.35924 -3.10347,3.47679 -3.65252,3.45392 -0.44642,-0.0186 -2.4553,-0.26773 -4.46419,-0.55363 z" id="path52" clip-path="none" mask="none"/><path style="baseline-shift: baseline; display: inline; overflow: visible; vector-effect: none; fill: rgb(218, 136, 37); fill-rule: evenodd; stroke-width: 0.264583; stop-color: rgb(0, 0, 0); stroke: none; pointer-events: none;" d="m 170.90734,151.73163 c -0.38984,-1.9492 -0.2981,-12.08265 0.16672,-18.41478 1.67519,-22.82071 7.26325,-44.911162 17.47421,-69.078224 3.18852,-7.54652 11.2954,-23.657441 15.75986,-31.319824 l 3.40176,-5.838457 10.79349,0.230954 c 14.30385,0.306065 24.39067,1.442538 38.04838,4.28688 6.90129,1.437254 17.23441,4.187661 17.08842,4.548481 -0.059,0.14578 -1.38565,1.331831 -2.94812,2.635671 -25.45648,21.242797 -46.92679,46.176945 -61.30809,71.198999 -5.66419,9.85514 -11.97047,23.79966 -14.82653,32.78459 -0.70739,2.22537 -1.14436,2.99929 -1.76847,3.13212 -8.045,1.71209 -14.92165,3.88953 -19.3824,6.13726 -1.05282,0.53051 -1.98878,0.96456 -2.07991,0.96456 -0.0911,0 -0.27982,-0.5707 -0.41932,-1.26823 z" id="path50" clip-path="none" mask="none"/><path style="baseline-shift: baseline; display: inline; overflow: visible; vector-effect: none; fill: rgb(227, 188, 142); fill-rule: evenodd; stroke-width: 0.264583; stop-color: rgb(0, 0, 0); stroke: none; pointer-events: none;" d="m 150.03743,161.42552 c -5.60594,-14.14853 -9.12719,-29.36229 -10.89376,-47.06709 -0.95693,-9.5904 -0.95588,-29.723541 0.002,-40.090593 1.24858,-13.51207 4.59013,-34.510861 5.66287,-35.586339 0.51297,-0.514273 10.41216,-3.551065 17.11962,-5.251818 9.27629,-2.352106 21.86808,-4.512982 31.45223,-5.397507 7.23941,-0.668132 12.17505,-0.948952 12.17505,-0.692719 0,0.13476 -1.74445,3.306773 -3.87655,7.048918 -16.62252,29.174897 -27.40262,59.756796 -31.03421,88.040488 -0.96623,7.5253 -1.5935,19.99308 -1.34409,26.71557 l 0.18068,4.87002 -4.16421,2.63793 c -2.63966,1.67215 -5.74974,4.16255 -8.49495,6.80231 l -4.33074,4.16439 z" id="path48" clip-path="none" mask="none"/><path style="baseline-shift: baseline; display: inline; overflow: visible; vector-effect: none; fill: rgb(218, 136, 37); fill-rule: evenodd; stroke-width: 0.264583; stop-color: rgb(0, 0, 0); stroke: none; pointer-events: none;" d="M 138.25659,182.74451 C 114.67667,157.25265 98.730481,120.46298 92.145944,76.361982 c -0.569769,-3.816141 -1.029927,-7.446446 -1.022569,-8.067349 0.01106,-0.933617 0.555164,-1.524238 3.145221,-3.414133 9.066774,-6.615779 17.671144,-11.782901 28.293624,-16.990981 7.68387,-3.767312 19.56181,-8.779986 19.93072,-8.411072 0.0936,0.09363 -0.47688,3.804814 -1.2678,8.247065 -1.50527,8.454342 -2.63547,16.645403 -3.52231,25.527738 -0.70987,7.109822 -0.71298,35.17118 -0.005,42.00394 1.96056,18.91232 6.17553,35.96514 12.57561,50.87813 l 1.19593,2.78668 -2.12735,3.09793 c -2.39562,3.4886 -4.97698,8.49051 -6.10178,11.8234 -0.4143,1.22766 -0.87434,2.38086 -1.0223,2.56269 -0.14795,0.18183 -1.93072,-1.46585 -3.9617,-3.66151 z" id="path46" clip-path="none" mask="none"/><path style="baseline-shift: baseline; display: inline; overflow: visible; vector-effect: none; fill: rgb(227, 188, 142); fill-rule: evenodd; stroke-width: 0.264583; stop-color: rgb(0, 0, 0); stroke: none; pointer-events: none;" d="m 136.56353,205.23052 c -5.30159,-2.39471 -11.3959,-5.87059 -17.65382,-10.06884 -24.715663,-16.58099 -47.266508,-43.6726 -64.028309,-76.92084 l -3.713073,-7.36515 1.56077,-2.37489 C 58.584845,99.590573 66.262847,90.173097 74.052704,82.346265 80.907656,75.458777 89.152485,68.39841 89.522847,69.098588 c 0.146084,0.27618 0.392326,1.689211 0.547206,3.140072 0.154879,1.450861 0.816578,5.833883 1.47044,9.740045 7.116212,42.512035 23.670657,79.251025 46.084097,102.273605 l 4.15158,4.2644 -0.65284,2.63479 c -0.46238,1.86616 -0.65546,4.55867 -0.66185,9.22962 -0.005,3.62715 -0.0166,6.59393 -0.0258,6.59285 -0.009,-0.001 -1.75169,-0.78563 -3.87218,-1.74345 z" id="path44" clip-path="none" mask="none"/><path style="baseline-shift: baseline; display: inline; overflow: visible; vector-effect: none; fill: rgb(218, 136, 37); fill-rule: evenodd; stroke-width: 0.264583; stop-color: rgb(0, 0, 0); stroke: none; pointer-events: none;" d="m 136.96937,223.9642 c -33.02761,-3.39692 -69.849664,-22.86145 -101.159935,-53.47423 -6.944754,-6.79004 -6.451181,-4.93016 -3.94145,-14.85218 2.702603,-10.68451 5.83266,-19.19603 10.745518,-29.22013 3.016292,-6.15439 7.12453,-13.59685 7.503797,-13.59385 0.113443,8e-4 1.519484,2.60332 3.124534,5.78315 14.903748,29.52647 34.546682,54.52816 56.534016,71.95698 6.01235,4.76584 15.46273,10.71682 22.84034,14.38275 4.04291,2.00892 7.58239,3.65259 7.8655,3.65259 0.28311,0 0.71016,0.77616 0.94901,1.7248 1.03443,4.1086 2.29083,7.55904 3.90259,10.71775 l 1.72725,3.38502 -3.32078,-0.0539 c -1.82643,-0.0297 -4.87311,-0.21358 -6.77039,-0.40872 z" id="path42" clip-path="none" mask="none"/><path style="baseline-shift: baseline; display: inline; overflow: visible; vector-effect: none; fill: rgb(227, 188, 142); fill-rule: evenodd; stroke-width: 0.264583; stop-color: rgb(0, 0, 0); stroke: none; pointer-events: none;" d="m 105.11131,243.65716 c -15.339588,-1.52007 -28.589144,-4.27872 -42.898152,-8.93171 -8.359065,-2.71819 -19.595239,-7.1689 -26.962208,-10.67988 l -5.332566,-2.54142 -0.436639,-2.29263 c -1.812205,-9.51523 -2.656377,-23.11663 -2.085022,-33.59415 0.366247,-6.71629 1.296249,-15.54985 1.884664,-17.90136 0.20284,-0.81063 0.867627,-0.30251 6.170567,4.71633 17.301361,16.37447 33.807003,28.35835 51.623912,37.4814 18.481364,9.46329 36.178774,14.6227 54.087834,15.76846 l 6.96614,0.44568 1.3924,1.68595 c 1.99663,2.41757 5.62845,5.81371 7.65326,7.15661 l 1.74062,1.15443 -3.23556,1.24776 c -6.2683,2.41731 -13.65802,4.27858 -22.15654,5.58062 -3.88253,0.59483 -24.38712,1.10282 -28.41271,0.70391 z" id="path40" clip-path="none" mask="none"/><path style="baseline-shift: baseline; display: inline; overflow: visible; vector-effect: none; fill: rgb(218, 136, 37); fill-rule: evenodd; stroke-width: 0.264583; stop-color: rgb(0, 0, 0); stroke: none; pointer-events: none;" d="m 66.354052,273.96516 c -3.013327,-0.17092 -7.961413,-0.54549 -10.99575,-0.83238 -4.811242,-0.45487 -5.583735,-0.62849 -6.038882,-1.35731 -4.95336,-7.93158 -10.751732,-20.36437 -14.038257,-30.10062 -2.047446,-6.06552 -5.205592,-17.62996 -4.898459,-17.9371 0.07536,-0.0754 2.675311,1.02636 5.777667,2.44825 22.122206,10.13921 42.910812,16.07847 65.095509,18.59766 6.96346,0.79074 24.89395,0.67122 31.2493,-0.20829 9.52981,-1.31882 18.89169,-3.66942 25.27921,-6.34716 l 2.75535,-1.15509 2.52051,1.13363 c 2.63889,1.18688 7.14918,2.44516 8.83688,2.46532 0.85699,0.0102 0.54927,0.43801 -2.31069,3.21224 -16.27702,15.78912 -43.36895,26.50213 -74.418092,29.42725 -7.929845,0.74705 -21.671594,1.05879 -28.814296,0.6536 z" id="path38" clip-path="none" mask="none"/><path style="baseline-shift: baseline; display: inline; overflow: visible; vector-effect: none; fill: rgb(227, 188, 142); fill-rule: evenodd; stroke-width: 0.264583; stop-color: rgb(0, 0, 0); stroke: none; pointer-events: none;" d="m 80.558282,307.13997 c -5.950424,-4.76575 -16.25433,-15.06008 -20.842605,-20.82326 -4.151987,-5.21515 -8.551383,-11.52771 -8.246483,-11.83262 0.116872,-0.11687 2.646304,0.0322 5.620959,0.33129 7.209187,0.72485 32.098599,0.73183 38.686949,0.0108 26.176658,-2.86453 46.481838,-9.463 63.310288,-20.57367 4.21276,-2.7814 11.9599,-9.10955 14.58453,-11.91321 1.02647,-1.09647 1.47728,-1.27534 3.24668,-1.28819 1.13009,-0.008 3.33309,-0.26374 4.89556,-0.56787 1.56246,-0.30412 2.89319,-0.50378 2.95718,-0.44368 0.22759,0.21377 -1.6341,4.53205 -3.62388,8.40573 -4.10907,7.99951 -9.59321,15.20682 -17.25185,22.67255 -17.01338,16.58479 -39.86165,29.06532 -67.915591,37.09786 -11.313308,3.23929 -9.911932,3.33706 -15.421737,-1.0758 z" id="path36" clip-path="none" mask="none"/><path style="baseline-shift: baseline; display: inline; overflow: visible; vector-effect: none; fill: rgb(218, 136, 37); fill-rule: evenodd; stroke-width: 0.264583; stop-color: rgb(0, 0, 0); stroke: none; pointer-events: none;" d="m 124.181,330.97919 c -11.56841,-3.89876 -22.82075,-9.4045 -33.226435,-16.25756 -1.943523,-1.27997 -3.461213,-2.39969 -3.372649,-2.48827 0.08856,-0.0886 2.881842,-0.89506 6.207281,-1.79226 13.122243,-3.54029 23.841173,-7.61405 35.875143,-13.63448 28.01338,-14.01474 47.49228,-32.9376 55.98627,-54.38808 1.0717,-2.70643 1.53144,-3.40532 2.50541,-3.80876 0.65608,-0.27175 2.21341,-1.10864 3.46074,-1.85974 1.24733,-0.7511 2.36545,-1.36564 2.48471,-1.36564 0.58625,0 -0.38189,12.35411 -1.32839,16.95127 -5.5992,27.19545 -26.77399,55.39242 -57.78877,76.95323 -2.76584,1.92278 -5.13998,3.49007 -5.27585,3.48293 -0.13587,-0.007 -2.62323,-0.81386 -5.52746,-1.79264 z" id="path34" clip-path="none" mask="none"/><path style="baseline-shift: baseline; display: inline; overflow: visible; vector-effect: none; fill: rgb(227, 188, 142); fill-rule: evenodd; stroke-width: 0.264583; stop-color: rgb(0, 0, 0); stroke: none; pointer-events: none;" d="m 158.19806,337.63809 c -6.32764,-0.46516 -15.27111,-1.76879 -21.22869,-3.09435 -2.56691,-0.57116 -4.71737,-1.08339 -4.7788,-1.13834 -0.0614,-0.055 2.22138,-1.76049 5.07293,-3.79008 27.01909,-19.23076 46.72751,-43.58203 54.438,-67.26236 2.67635,-8.21958 4.63394,-21.40209 3.94708,-26.5799 -0.21065,-1.58795 -0.11595,-1.99689 0.61477,-2.65476 0.47507,-0.42771 1.36519,-1.65352 1.97804,-2.72401 l 1.11427,-1.94635 1.4392,3.36677 c 3.22058,7.53406 4.6961,14.40024 5.04982,23.49889 0.89698,23.07296 -8.00081,49.9128 -24.67378,74.42748 -1.97353,2.90171 -4.09715,5.88224 -4.71917,6.62339 l -1.13094,1.34755 -6.08752,0.14489 c -3.34814,0.0797 -8.31399,-0.0188 -11.03521,-0.21882 z" id="path32" clip-path="none" mask="none"/><path style="baseline-shift: baseline; display: inline; overflow: visible; vector-effect: none; fill: rgb(218, 136, 37); fill-rule: evenodd; stroke-width: 0.264583; stop-color: rgb(0, 0, 0); stroke: none; pointer-events: none;" d="m 179.21112,335.31608 c 14.46545,-19.86539 23.96605,-41.88385 27.20242,-63.04404 1.24497,-8.13983 1.24552,-19.96629 10e-4,-26.90344 -0.94276,-5.25622 -2.85948,-11.37686 -4.98513,-15.91892 -1.16154,-2.48197 -1.33352,-3.242 -1.21568,-5.37243 0.12644,-2.28589 0.19749,-2.44925 0.90135,-2.07255 1.37446,0.73558 6.25075,5.80594 8.57429,8.91551 5.89879,7.89432 10.11056,17.87566 12.50888,29.64441 3.88007,19.03982 2.14795,43.99447 -4.49261,64.72489 l -1.18613,3.70287 -4.97484,1.66624 c -10.73434,3.59524 -17.81596,5.08688 -32.08293,6.75786 l -1.94632,0.22796 z" id="path30" clip-path="none" mask="none"/><path style="baseline-shift: baseline; display: inline; overflow: visible; vector-effect: none; fill: rgb(227, 188, 142); fill-rule: evenodd; stroke-width: 0.264583; stop-color: rgb(0, 0, 0); stroke: none; pointer-events: none;" d="m 218.71176,327.25145 c 0.16077,-0.41637 0.81735,-2.62419 1.45908,-4.90627 7.28837,-25.91856 7.50142,-52.3752 0.58866,-73.1017 -1.83788,-5.51053 -5.26177,-12.65195 -8.13921,-16.97647 -2.63389,-3.9585 -7.65578,-9.39333 -10.80696,-11.69559 -2.24355,-1.63915 -4.42929,-4.66711 -3.36896,-4.66711 0.29275,0 1.73644,0.37193 3.20819,0.82651 17.6925,5.46465 32.86631,23.25336 41.80463,49.00882 3.93717,11.3448 6.73539,27.58088 6.72884,39.04258 l -0.003,4.66709 -4.15279,3.10782 c -6.48289,4.85172 -11.2939,7.79756 -18.76269,11.48874 -3.79456,1.87534 -7.33774,3.53409 -7.87372,3.68615 -0.83268,0.23622 -0.93197,0.16629 -0.68222,-0.48057 z" id="path28" clip-path="none" mask="none"/><path style="baseline-shift: baseline; display: inline; overflow: visible; vector-effect: none; fill: rgb(218, 136, 37); fill-rule: evenodd; stroke-width: 0.264583; stop-color: rgb(0, 0, 0); stroke: none; pointer-events: none;" d="m 251.49873,300.01366 c -0.27117,-4.18518 -0.86061,-9.98355 -1.30988,-12.88526 -4.27195,-27.59134 -16.74864,-51.66462 -33.26995,-64.19304 -4.47232,-3.39145 -11.3253,-6.7685 -16.03049,-7.8996 -5.05804,-1.21592 -6.10768,-1.61227 -5.36719,-2.02667 1.39275,-0.77943 8.27512,-1.23959 11.91697,-0.79678 25.67301,3.12153 52.1576,28.68405 64.79393,62.53811 2.15373,5.77001 2.1563,5.79345 0.87937,8.00875 -3.56691,6.18802 -10.24491,14.55717 -16.52042,20.70407 -2.33576,2.28791 -4.32615,4.15983 -4.42308,4.15983 -0.0969,0 -0.3981,-3.42423 -0.66926,-7.60941 z" id="path26" clip-path="none" mask="none"/><path style="baseline-shift: baseline; display: inline; overflow: visible; vector-effect: none; fill: rgb(227, 188, 142); fill-rule: evenodd; stroke-width: 0.264583; stop-color: rgb(0, 0, 0); stroke: none; pointer-events: none;" d="m 274.57236,276.67812 c -0.83286,-2.81966 -3.88163,-10.06194 -6.13138,-14.56492 -13.31508,-26.65059 -35.21154,-46.35675 -56.27987,-50.6502 -4.90057,-0.99868 -11.60248,-1.09448 -15.70889,-0.22457 -1.54707,0.32773 -2.88162,0.52711 -2.96567,0.44306 -0.6363,-0.6363 6.97368,-4.34934 11.46021,-5.59164 2.81328,-0.77899 4.24894,-0.89884 10.75464,-0.89783 6.22619,10e-4 8.19078,0.15257 11.50766,0.88799 21.05796,4.66897 41.71529,18.28733 56.29084,37.10976 1.62459,2.09796 2.68303,3.83674 2.59392,4.26127 -0.0828,0.39444 -0.45476,2.3608 -0.82664,4.36968 -0.787,4.25133 -2.88215,11.42217 -4.60303,15.75423 -1.74308,4.38793 -4.86664,10.82799 -5.25182,10.82799 -0.1818,0 -0.55978,-0.77618 -0.83997,-1.72482 z" id="path24" clip-path="none" mask="none"/><path style="baseline-shift: baseline; display: inline; overflow: visible; vector-effect: none; fill: rgb(218, 136, 37); fill-rule: evenodd; stroke-width: 0.264583; stop-color: rgb(0, 0, 0); stroke: none; pointer-events: none;" d="m 283.60206,240.72698 c -24.00814,-30.37863 -64.67022,-45.56546 -87.62657,-32.72753 -1.40764,0.7872 -2.66946,1.60945 -2.80406,1.82722 -0.30721,0.49707 -1.00848,0.51879 -1.00848,0.0312 0,-0.74786 5.91072,-6.65976 8.23968,-8.24133 10.89796,-7.40066 28.1614,-9.79513 45.9825,-6.37787 12.14983,2.32978 24.70298,7.38501 34.15366,13.75389 l 3.95166,2.66305 0.86688,4.3136 c 1.5752,7.8383 2.11862,16.71393 1.50556,24.58956 -0.14335,1.84147 -0.37055,3.34775 -0.50488,3.34727 -0.1343,-5.3e-4 -1.37451,-1.43106 -2.75595,-3.17909 z" id="path22" clip-path="none" mask="none"/><path style="baseline-shift: baseline; display: inline; overflow: visible; vector-effect: none; fill: rgb(227, 188, 142); fill-rule: evenodd; stroke-width: 0.264583; stop-color: rgb(0, 0, 0); stroke: none; pointer-events: none;" d="m 190.33774,208.59928 c 2.60346,-12.21532 17.37667,-23.76609 36.3093,-28.38927 13.68621,-3.34205 29.95226,-3.18456 41.56563,0.40244 2.68685,0.82989 2.74733,0.88048 4.73914,3.96347 3.07229,4.75544 7.45535,13.92235 9.25404,19.35436 0.88659,2.67747 1.56136,4.91878 1.49945,4.98068 -0.0619,0.0619 -1.73683,-0.91251 -3.72206,-2.16536 -11.57753,-7.30644 -25.49599,-12.22169 -39.51525,-13.95463 -5.08702,-0.62882 -15.67781,-0.52384 -20.57945,0.20398 -12.51138,1.85776 -22.41215,7.00849 -28.04449,14.58974 -1.73873,2.34036 -1.79728,2.3798 -1.50631,1.01459 z" id="path20" clip-path="none" mask="none"/><path style="baseline-shift: baseline; display: inline; overflow: visible; vector-effect: none; fill: rgb(218, 136, 37); fill-rule: evenodd; stroke-width: 0.264583; stop-color: rgb(0, 0, 0); stroke: none; pointer-events: none;" d="m 188.1046,206.11426 c 0,-8.88553 4.05257,-17.05662 12.75916,-25.72599 5.60959,-5.58563 10.54608,-9.10848 18.08833,-12.90846 8.65399,-4.36012 16.32732,-6.67898 24.95485,-7.54132 4.17234,-0.41703 3.87033,-0.51879 8.72545,2.93998 3.47972,2.47893 13.6675,12.27808 15.43008,14.84148 l 0.95202,1.38456 -1.19038,-0.25872 c -6.94398,-1.50921 -9.77271,-1.95296 -15.04905,-2.36077 -20.87388,-1.61335 -42.82237,5.11954 -54.8637,16.8299 -4.41999,4.2985 -7.52837,9.22032 -8.73055,13.82398 -0.33764,1.29297 -0.71792,2.45487 -0.84505,2.582 -0.12714,0.12714 -0.23116,-1.49585 -0.23116,-3.60664 z" id="path18" clip-path="none" mask="none"/><path style="baseline-shift: baseline; display: inline; overflow: visible; vector-effect: none; fill: rgb(227, 188, 142); fill-rule: evenodd; stroke-width: 0.264583; stop-color: rgb(0, 0, 0); stroke: none; pointer-events: none;" d="m 185.65542,208.45885 c -1.54201,-3.48597 -2.11949,-7.06798 -1.87476,-11.62879 0.92007,-17.14672 15.22094,-37.10646 33.02238,-46.08938 l 3.73957,-1.88706 3.1573,0.70244 c 4.8015,1.06823 11.92869,3.65002 17.10546,6.19635 l 4.65373,2.28907 -5.44319,0.90315 c -8.70122,1.44373 -15.58142,3.73534 -23.00557,7.66251 -14.93645,7.90097 -25.59183,19.31593 -29.36701,31.46044 -0.74376,2.39262 -0.94195,3.97653 -0.94955,7.58851 -0.005,2.51062 -0.0655,4.56516 -0.13388,4.56564 -0.0684,5.3e-4 -0.47537,-0.79281 -0.90448,-1.76288 z" id="path16" clip-path="none" mask="none"/><path style="baseline-shift: baseline; display: inline; overflow: visible; vector-effect: none; fill: rgb(218, 136, 37); fill-rule: evenodd; stroke-width: 0.264583; stop-color: rgb(0, 0, 0); stroke: none; pointer-events: none;" d="m 183.2695,209.53185 c -2.16695,-2.50436 -4.27048,-6.7686 -5.36486,-10.87553 -1.23312,-4.62757 -1.23914,-13.74199 -0.0129,-19.52232 2.31358,-10.90596 7.13381,-20.60885 13.75649,-27.69118 l 2.74683,-2.93746 3.04376,-0.37815 c 5.51259,-0.68486 19.88592,-0.4063 19.88592,0.38541 0,0.14693 -0.86747,0.6848 -1.92771,1.19525 -7.66235,3.68905 -18.1749,13.18146 -23.5671,21.28016 -9.2139,13.8386 -12.0801,28.10033 -7.60975,37.86486 0.5804,1.26775 0.98301,2.37725 0.8947,2.46556 -0.0883,0.0883 -0.91873,-0.71566 -1.84538,-1.7866 z" id="path14" clip-path="none" mask="none"/><path style="baseline-shift: baseline; display: inline; overflow: visible; vector-effect: none; fill: rgb(227, 188, 142); fill-rule: evenodd; stroke-width: 0.264583; stop-color: rgb(0, 0, 0); stroke: none; pointer-events: none;" d="m 181.61124,211.61224 c -10.236,-5.80454 -16.51025,-23.85777 -14.02382,-40.35148 1.03543,-6.86851 3.99192,-14.67828 6.07281,-16.04174 1.78489,-1.1695 7.69754,-3.48141 11.97829,-4.68364 5.99574,-1.68388 6.19962,-1.63225 3.82577,0.96882 -5.77476,6.32751 -10.76475,16.59229 -12.99532,26.73237 -0.57087,2.59518 -0.74234,5.10888 -0.74234,10.88262 0,6.64032 0.10842,7.88252 0.93824,10.74922 1.34331,4.64067 3.04122,7.95127 5.40365,10.53615 1.13255,1.23919 1.90388,2.25087 1.71408,2.24818 -0.18981,-0.003 -1.16692,-0.47091 -2.17136,-1.0405 z" id="path12" clip-path="none" mask="none"/><path style="baseline-shift: baseline; display: inline; overflow: visible; vector-effect: none; fill: rgb(218, 136, 37); fill-rule: evenodd; stroke-width: 0.264583; stop-color: rgb(0, 0, 0); stroke: none; pointer-events: none;" d="m 178.72465,213.72233 c -7.2282,-2.5516 -13.80465,-9.21005 -18.43649,-18.66637 -4.0306,-8.2288 -5.60889,-17.8222 -4.07004,-24.73903 0.67487,-3.03343 0.74515,-3.14582 3.60504,-5.76493 3.03872,-2.78288 9.45661,-7.37965 9.80995,-7.0263 0.11195,0.11194 -0.33553,1.68063 -0.9944,3.48597 -3.53874,9.69639 -4.04225,20.67406 -1.42443,31.05599 2.67113,10.59334 8.09365,18.42053 15.00571,21.66016 l 2.02918,0.95106 -1.42042,-0.005 c -0.78124,-0.002 -2.62808,-0.4309 -4.1041,-0.95195 z" id="path10" clip-path="none" mask="none"/><path style="baseline-shift: baseline; display: inline; overflow: visible; vector-effect: none; fill: rgb(227, 188, 142); fill-rule: evenodd; stroke-width: 0.264583; stop-color: rgb(0, 0, 0); stroke: none; pointer-events: none;" d="M 177.04749,217.06351 C 166.5085,215.9852 154.4907,206.6255 149.34497,195.48825 c -2.65258,-5.74115 -3.29674,-10.84682 -1.80698,-14.32229 0.9445,-2.20342 4.36159,-7.9204 5.75338,-9.62571 l 0.93254,-1.14261 0.0403,5.6068 c 0.0567,7.88296 1.2907,13.00476 4.90741,20.36841 5.10731,10.39851 13.98595,18.26046 22.14178,19.60633 1.51027,0.24922 2.67476,0.52431 2.58776,0.61131 -0.44351,0.44351 -4.44375,0.71959 -6.85369,0.47302 z" id="path8" clip-path="none" mask="none"/><path style="baseline-shift: baseline; display: inline; overflow: visible; vector-effect: none; fill: rgb(218, 136, 37); fill-rule: evenodd; stroke-width: 0.264583; stop-color: rgb(0, 0, 0); stroke: none; pointer-events: none;" d="m 169.23327,221.16201 c -12.53807,-1.94272 -24.0782,-10.75946 -25.73144,-19.65901 -0.44237,-2.38131 0.0441,-7.89129 1.04925,-11.88479 l 0.68743,-2.73111 0.49305,2.63793 c 2.41511,12.92116 15.92093,26.21628 29.28704,28.83013 2.4341,0.47601 7.23555,0.35944 9.43349,-0.22904 0.95112,-0.25465 0.93843,-0.21804 -0.20292,0.58523 -2.99185,2.10563 -9.93232,3.23835 -15.0159,2.45066 z" id="path6" clip-path="none" mask="none"/><path style="baseline-shift: baseline; display: inline; overflow: visible; vector-effect: none; fill: rgb(227, 188, 142); fill-rule: evenodd; stroke-width: 0.264583; stop-color: rgb(0, 0, 0); stroke: none; pointer-events: none;" d="m 164.47218,227.57427 c -3.56029,-0.36207 -5.92262,-0.86108 -8.49886,-1.79528 -2.37939,-0.86282 -4.98074,-2.35925 -6.68177,-3.8437 -0.78866,-0.68826 -0.79254,-0.69396 -1.66035,-2.44513 -1.43664,-2.89904 -2.47658,-5.74329 -3.25484,-8.90203 -0.35976,-1.46016 -0.84591,-4.05501 -0.79074,-4.22054 0.0187,-0.056 0.17342,0.15981 0.34388,0.47962 2.76039,5.17902 8.98803,10.27443 16.05774,13.13833 10.41809,4.22031 21.38818,3.59405 26.8798,-1.53452 0.40455,-0.3778 0.73555,-0.64825 0.73555,-0.60098 0,0.0473 -0.20644,0.44239 -0.45875,0.87806 -2.60152,4.49212 -8.53065,7.67505 -16.15266,8.6712 -1.14799,0.15003 -5.59145,0.2693 -6.519,0.17497 z" id="path3" clip-path="none" mask="none"/><path style="baseline-shift: baseline; display: inline; overflow: visible; vector-effect: none; fill: rgb(218, 136, 37); fill-rule: evenodd; stroke-width: 0.264583; stop-color: rgb(0, 0, 0); stroke: none; pointer-events: none;" d="m 173.93681,238.34894 c -2.23397,-0.21858 -5.11257,-0.84541 -7.25964,-1.58085 -4.69479,-1.60808 -8.63582,-4.08679 -12.20244,-7.67471 -1.50977,-1.51878 -3.9684,-4.45317 -3.73117,-4.45317 0.0258,0 0.37984,0.19685 0.78678,0.43744 2.79405,1.65189 6.05704,2.78407 9.70648,3.36794 2.82755,0.45237 4.42983,0.52255 7.91337,0.34662 5.58049,-0.28185 10.92988,-2.00633 14.78243,-4.76542 2.2396,-1.60394 4.45861,-4.31832 4.94625,-6.05045 0.41613,-1.4781 0.5587,-2.07619 0.5587,-2.34379 0,-0.25586 0.0246,-0.27858 0.24253,-0.22388 0.19653,0.0493 0.30002,-0.005 0.54552,-0.2842 0.43587,-0.49643 0.7984,-0.65878 1.31345,-0.58819 1.49909,0.20548 3.99988,2.56467 5.26792,4.96967 0.53805,1.02045 0.74312,2.02422 0.74312,3.6373 0,4.9979 -3.1529,9.30114 -8.98175,12.25875 -4.4477,2.25681 -10.08355,3.39192 -14.63155,2.94694 z" id="path1" clip-path="none" mask="none"/></g><path d="M 311.778 -28.803 C 319.305 -25.62 232.35 23.762 143.933 70.3 C 55.516 116.838 -34.364 160.532 -32.688 152.342 C -31.012 144.152 -28.938 136.106 -26.487 128.227 C -24.036 120.348 -21.208 112.635 -18.025 105.108 C -14.841 97.582 -11.302 90.243 -7.429 83.112 C -3.555 75.981 0.653 69.059 5.175 62.365 C 9.697 55.672 14.533 49.207 19.661 42.993 C 24.789 36.779 30.209 30.816 35.901 25.123 C 41.594 19.431 47.557 14.011 53.771 8.883 C 59.985 3.755 66.45 -1.081 73.143 -5.603 C 79.837 -10.125 86.759 -14.333 93.89 -18.207 C 101.021 -22.08 108.36 -25.619 115.886 -28.803 C 123.413 -31.986 131.126 -34.814 139.005 -37.265 C 146.884 -39.716 154.93 -41.79 163.12 -43.466 C 171.31 -45.142 179.645 -46.42 188.104 -47.279 C 196.564 -48.138 205.147 -48.578 213.832 -48.578 C 222.518 -48.578 231.101 -48.138 239.56 -47.279 C 248.019 -46.42 256.355 -45.142 264.545 -43.466 C 272.735 -41.79 280.78 -39.716 288.66 -37.265 C 296.539 -34.814 304.252 -31.986 311.778 -28.803 Z" style="fill-rule: nonzero; fill-opacity: 0.36; fill: url("#gradient-1");" transform="matrix(1.05519104, -0.19465397, 0.15042301, 0.82458001, -31.17761, 49.18898721)"/></g></svg>
|
package/src/example.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { createRouter } from "./router/router";
|
|
2
|
-
import { authWrapper } from "./router/types/routes.types";
|
|
3
|
-
|
|
4
|
-
const authenticationMiddleware = (headers: Record<string, string>) => {
|
|
5
|
-
return authWrapper({
|
|
6
|
-
status: headers.authorization,
|
|
7
|
-
});
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
const baseRouter = createRouter("/status");
|
|
11
|
-
const endpoint = baseRouter.createEndpoint("/status");
|
|
12
|
-
|
|
13
|
-
const getter = endpoint.get({
|
|
14
|
-
authenticator: authenticationMiddleware,
|
|
15
|
-
handler: async (params, auth) => {
|
|
16
|
-
return {
|
|
17
|
-
status: "ok",
|
|
18
|
-
};
|
|
19
|
-
},
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
const poster = endpoint.post({
|
|
23
|
-
validator: (): { a: string } => ({ a: "hello" }),
|
|
24
|
-
queryValidator: (): {b: string} => ({b: "OKAY"}),
|
|
25
|
-
handler: async (params, body) => {
|
|
26
|
-
return {
|
|
27
|
-
status: "ok",
|
|
28
|
-
};
|
|
29
|
-
},
|
|
30
|
-
});
|
|
31
|
-
|
package/src/index.ts
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
// Router creation
|
|
2
|
-
export { createRouter } from "./router/router";
|
|
3
|
-
|
|
4
|
-
// Type exports
|
|
5
|
-
export type {
|
|
6
|
-
Authentication,
|
|
7
|
-
OpenRoute,
|
|
8
|
-
AuthenticatedRoute,
|
|
9
|
-
ValidatedRoute,
|
|
10
|
-
FullRoute,
|
|
11
|
-
RestMethod,
|
|
12
|
-
} from "./router/types/routes.types";
|
|
13
|
-
|
|
14
|
-
export type {
|
|
15
|
-
ValidatorFunction,
|
|
16
|
-
AuthenticationFunction,
|
|
17
|
-
} from "./router/types/configuration.types";
|
|
18
|
-
|
|
19
|
-
export type { Endpoint, Router } from "./router/types/router-creation.types";
|
|
20
|
-
|
|
21
|
-
// Utility exports
|
|
22
|
-
export { authWrapper } from "./router/types/routes.types";
|
package/src/router/router.ts
DELETED
|
@@ -1,277 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Authentication,
|
|
3
|
-
FullRoute,
|
|
4
|
-
ValidatedRoute,
|
|
5
|
-
AuthenticatedRoute,
|
|
6
|
-
OpenRoute,
|
|
7
|
-
} from "./types/routes.types";
|
|
8
|
-
import { Endpoint, Router } from "./types/router-creation.types";
|
|
9
|
-
import { AuthenticationFunction, ValidatorFunction } from "./types/configuration.types";
|
|
10
|
-
import { Params } from "./types/params.types";
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Creates an endpoint which can be used to create final routes from.
|
|
14
|
-
* Routes must be fully qualified. This is provided as a helper function
|
|
15
|
-
* @param path
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
// Function overloads in TypeScript are only allowed for functions, not for object properties.
|
|
19
|
-
// When you try to declare multiple properties with the same name (like `get`) in an object literal,
|
|
20
|
-
// you get a syntax error: "An object literal cannot have multiple properties with the same name."
|
|
21
|
-
// Additionally, the type signatures for overloaded methods must be declared as overloads on a function, not as separate properties.
|
|
22
|
-
// The correct way is to define a single function for `get` that matches the overload signatures, and then assign it as the property.
|
|
23
|
-
//
|
|
24
|
-
|
|
25
|
-
function createEndpoint<Path extends string>(path: Path): Endpoint<Path> {
|
|
26
|
-
// Open route: no auth, no query
|
|
27
|
-
function get<Res extends unknown>(config: {
|
|
28
|
-
authenticator?: never;
|
|
29
|
-
queryValidator?: never;
|
|
30
|
-
handler: (params: { url: Params<Path> }) => Promise<Res>;
|
|
31
|
-
}): OpenRoute<Path, "GET", Res, undefined>;
|
|
32
|
-
|
|
33
|
-
// Open route: no auth, with query
|
|
34
|
-
function get<Res extends unknown, Query extends unknown>(config: {
|
|
35
|
-
authenticator?: never;
|
|
36
|
-
queryValidator: ValidatorFunction<Query>;
|
|
37
|
-
handler: (params: { url: Params<Path>; query: Query }) => Promise<Res>;
|
|
38
|
-
}): OpenRoute<Path, "GET", Res, Query>;
|
|
39
|
-
|
|
40
|
-
// Authenticated route: auth, no query
|
|
41
|
-
function get<Res extends unknown, Auth extends Authentication>(config: {
|
|
42
|
-
authenticator: AuthenticationFunction<Auth>;
|
|
43
|
-
queryValidator?: never;
|
|
44
|
-
handler: (params: { url: Params<Path> }, auth: Auth) => Promise<Res>;
|
|
45
|
-
}): AuthenticatedRoute<Path, "GET", Res, Auth, undefined>;
|
|
46
|
-
|
|
47
|
-
// Authenticated route: auth, with query
|
|
48
|
-
function get<Res extends unknown, Auth extends Authentication, Query extends unknown>(config: {
|
|
49
|
-
authenticator: AuthenticationFunction<Auth>;
|
|
50
|
-
queryValidator: ValidatorFunction<Query>;
|
|
51
|
-
handler: (params: { url: Params<Path>; query: Query }, auth: Auth) => Promise<Res>;
|
|
52
|
-
}): AuthenticatedRoute<Path, "GET", Res, Auth, Query>;
|
|
53
|
-
|
|
54
|
-
function get(
|
|
55
|
-
config:
|
|
56
|
-
| { handler: (params: { url: Params<Path> }) => Promise<any> }
|
|
57
|
-
| { queryValidator: ValidatorFunction<any>; handler: (params: { url: Params<Path>; query: any }) => Promise<any> }
|
|
58
|
-
| { authenticator: AuthenticationFunction<any>; handler: (params: { url: Params<Path> }, auth: any) => Promise<any> }
|
|
59
|
-
| { authenticator: AuthenticationFunction<any>; queryValidator: ValidatorFunction<any>; handler: (params: { url: Params<Path>; query: any }, auth: any) => Promise<any> }
|
|
60
|
-
): OpenRoute<Path, "GET", any, any> | AuthenticatedRoute<Path, "GET", any, any, any> {
|
|
61
|
-
if ("authenticator" in config) {
|
|
62
|
-
return { ...config, type: "authenticated", path, method: "GET" } satisfies AuthenticatedRoute<
|
|
63
|
-
Path,
|
|
64
|
-
"GET",
|
|
65
|
-
any,
|
|
66
|
-
any,
|
|
67
|
-
any
|
|
68
|
-
>;
|
|
69
|
-
} else {
|
|
70
|
-
return { ...config, type: "open", path, method: "GET" } satisfies OpenRoute<
|
|
71
|
-
Path,
|
|
72
|
-
"GET",
|
|
73
|
-
any,
|
|
74
|
-
any
|
|
75
|
-
>;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// Validated route: no auth, no query
|
|
80
|
-
function put<Res extends unknown, RequestBody extends unknown>(config: {
|
|
81
|
-
authenticator?: never;
|
|
82
|
-
validator: ValidatorFunction<RequestBody>;
|
|
83
|
-
queryValidator?: never;
|
|
84
|
-
handler: (params: { url: Params<Path> }, body: RequestBody) => Promise<Res>;
|
|
85
|
-
}): ValidatedRoute<Path, "PUT", Res, RequestBody, undefined>;
|
|
86
|
-
|
|
87
|
-
// Validated route: no auth, with query
|
|
88
|
-
function put<Res extends unknown, RequestBody extends unknown, Query extends unknown>(config: {
|
|
89
|
-
authenticator?: never;
|
|
90
|
-
validator: ValidatorFunction<RequestBody>;
|
|
91
|
-
queryValidator: ValidatorFunction<Query>;
|
|
92
|
-
handler: (params: { url: Params<Path>; query: Query }, body: RequestBody) => Promise<Res>;
|
|
93
|
-
}): ValidatedRoute<Path, "PUT", Res, RequestBody, Query>;
|
|
94
|
-
|
|
95
|
-
// Full route: auth + body validation, no query
|
|
96
|
-
function put<Res extends unknown, RequestBody extends unknown, Auth extends Authentication>(config: {
|
|
97
|
-
authenticator: AuthenticationFunction<Auth>;
|
|
98
|
-
validator: ValidatorFunction<RequestBody>;
|
|
99
|
-
queryValidator?: never;
|
|
100
|
-
handler: (params: { url: Params<Path> }, auth: Auth, body: RequestBody) => Promise<Res>;
|
|
101
|
-
}): FullRoute<Path, "PUT", Res, RequestBody, Auth, undefined>;
|
|
102
|
-
|
|
103
|
-
// Full route: auth + body validation, with query
|
|
104
|
-
function put<
|
|
105
|
-
Res extends unknown,
|
|
106
|
-
RequestBody extends unknown,
|
|
107
|
-
Auth extends Authentication,
|
|
108
|
-
Query extends unknown,
|
|
109
|
-
>(config: {
|
|
110
|
-
authenticator: AuthenticationFunction<Auth>;
|
|
111
|
-
validator: ValidatorFunction<RequestBody>;
|
|
112
|
-
queryValidator: ValidatorFunction<Query>;
|
|
113
|
-
handler: (params: { url: Params<Path>; query: Query }, auth: Auth, body: RequestBody) => Promise<Res>;
|
|
114
|
-
}): FullRoute<Path, "PUT", Res, RequestBody, Auth, Query>;
|
|
115
|
-
|
|
116
|
-
function put(
|
|
117
|
-
config:
|
|
118
|
-
| { validator: ValidatorFunction<any>; handler: (params: { url: Params<Path> }, body: any) => Promise<any> }
|
|
119
|
-
| { validator: ValidatorFunction<any>; queryValidator: ValidatorFunction<any>; handler: (params: { url: Params<Path>; query: any }, body: any) => Promise<any> }
|
|
120
|
-
| { authenticator: AuthenticationFunction<any>; validator: ValidatorFunction<any>; handler: (params: { url: Params<Path> }, auth: any, body: any) => Promise<any> }
|
|
121
|
-
| { authenticator: AuthenticationFunction<any>; validator: ValidatorFunction<any>; queryValidator: ValidatorFunction<any>; handler: (params: { url: Params<Path>; query: any }, auth: any, body: any) => Promise<any> }
|
|
122
|
-
): ValidatedRoute<Path, "PUT", any, any, any> | FullRoute<Path, "PUT", any, any, any, any> {
|
|
123
|
-
if ("authenticator" in config) {
|
|
124
|
-
return { ...config, type: "full", path, method: "PUT" } satisfies FullRoute<
|
|
125
|
-
Path,
|
|
126
|
-
"PUT",
|
|
127
|
-
any,
|
|
128
|
-
any,
|
|
129
|
-
any,
|
|
130
|
-
any
|
|
131
|
-
>;
|
|
132
|
-
} else {
|
|
133
|
-
return { ...config, type: "validated", path, method: "PUT" } satisfies ValidatedRoute<
|
|
134
|
-
Path,
|
|
135
|
-
"PUT",
|
|
136
|
-
any,
|
|
137
|
-
any,
|
|
138
|
-
any
|
|
139
|
-
>;
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// Validated route: no auth, no query
|
|
144
|
-
function post<Res extends unknown, RequestBody extends unknown>(config: {
|
|
145
|
-
authenticator?: never;
|
|
146
|
-
validator: ValidatorFunction<RequestBody>;
|
|
147
|
-
queryValidator?: never;
|
|
148
|
-
handler: (params: { url: Params<Path> }, body: RequestBody) => Promise<Res>;
|
|
149
|
-
}): ValidatedRoute<Path, "POST", Res, RequestBody, undefined>;
|
|
150
|
-
|
|
151
|
-
// Validated route: no auth, with query
|
|
152
|
-
function post<Res extends unknown, RequestBody extends unknown, Query extends unknown>(config: {
|
|
153
|
-
authenticator?: never;
|
|
154
|
-
validator: ValidatorFunction<RequestBody>;
|
|
155
|
-
queryValidator: ValidatorFunction<Query>;
|
|
156
|
-
handler: (params: { url: Params<Path>; query: Query }, body: RequestBody) => Promise<Res>;
|
|
157
|
-
}): ValidatedRoute<Path, "POST", Res, RequestBody, Query>;
|
|
158
|
-
|
|
159
|
-
// Full route: auth + body validation, no query
|
|
160
|
-
function post<Res extends unknown, RequestBody extends unknown, Auth extends Authentication>(config: {
|
|
161
|
-
authenticator: AuthenticationFunction<Auth>;
|
|
162
|
-
validator: ValidatorFunction<RequestBody>;
|
|
163
|
-
queryValidator?: never;
|
|
164
|
-
handler: (params: { url: Params<Path> }, auth: Auth, body: RequestBody) => Promise<Res>;
|
|
165
|
-
}): FullRoute<Path, "POST", Res, RequestBody, Auth, undefined>;
|
|
166
|
-
|
|
167
|
-
// Full route: auth + body validation, with query
|
|
168
|
-
function post<
|
|
169
|
-
Res extends unknown,
|
|
170
|
-
RequestBody extends unknown,
|
|
171
|
-
Auth extends Authentication,
|
|
172
|
-
Query extends unknown,
|
|
173
|
-
>(config: {
|
|
174
|
-
authenticator: AuthenticationFunction<Auth>;
|
|
175
|
-
validator: ValidatorFunction<RequestBody>;
|
|
176
|
-
queryValidator: ValidatorFunction<Query>;
|
|
177
|
-
handler: (params: { url: Params<Path>; query: Query }, auth: Auth, body: RequestBody) => Promise<Res>;
|
|
178
|
-
}): FullRoute<Path, "POST", Res, RequestBody, Auth, Query>;
|
|
179
|
-
|
|
180
|
-
function post(
|
|
181
|
-
config:
|
|
182
|
-
| { validator: ValidatorFunction<any>; handler: (params: { url: Params<Path> }, body: any) => Promise<any> }
|
|
183
|
-
| { validator: ValidatorFunction<any>; queryValidator: ValidatorFunction<any>; handler: (params: { url: Params<Path>; query: any }, body: any) => Promise<any> }
|
|
184
|
-
| { authenticator: AuthenticationFunction<any>; validator: ValidatorFunction<any>; handler: (params: { url: Params<Path> }, auth: any, body: any) => Promise<any> }
|
|
185
|
-
| { authenticator: AuthenticationFunction<any>; validator: ValidatorFunction<any>; queryValidator: ValidatorFunction<any>; handler: (params: { url: Params<Path>; query: any }, auth: any, body: any) => Promise<any> }
|
|
186
|
-
): ValidatedRoute<Path, "POST", any, any, any> | FullRoute<Path, "POST", any, any, any, any> {
|
|
187
|
-
if ("authenticator" in config) {
|
|
188
|
-
return { ...config, type: "full", path, method: "POST" } satisfies FullRoute<
|
|
189
|
-
Path,
|
|
190
|
-
"POST",
|
|
191
|
-
any,
|
|
192
|
-
any,
|
|
193
|
-
any,
|
|
194
|
-
any
|
|
195
|
-
>;
|
|
196
|
-
} else {
|
|
197
|
-
return { ...config, type: "validated", path, method: "POST" } satisfies ValidatedRoute<
|
|
198
|
-
Path,
|
|
199
|
-
"POST",
|
|
200
|
-
any,
|
|
201
|
-
any,
|
|
202
|
-
any
|
|
203
|
-
>;
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
// Open route: no auth, no query
|
|
208
|
-
function del<Res extends unknown>(config: {
|
|
209
|
-
authenticator?: never;
|
|
210
|
-
queryValidator?: never;
|
|
211
|
-
handler: (params: { url: Params<Path> }) => Promise<Res>;
|
|
212
|
-
}): OpenRoute<Path, "DELETE", Res, undefined>;
|
|
213
|
-
|
|
214
|
-
// Open route: no auth, with query
|
|
215
|
-
function del<Res extends unknown, Query extends unknown>(config: {
|
|
216
|
-
authenticator?: never;
|
|
217
|
-
queryValidator: ValidatorFunction<Query>;
|
|
218
|
-
handler: (params: { url: Params<Path>; query: Query }) => Promise<Res>;
|
|
219
|
-
}): OpenRoute<Path, "DELETE", Res, Query>;
|
|
220
|
-
|
|
221
|
-
// Authenticated route: auth, no query
|
|
222
|
-
function del<Res extends unknown, Auth extends Authentication>(config: {
|
|
223
|
-
authenticator: AuthenticationFunction<Auth>;
|
|
224
|
-
queryValidator?: never;
|
|
225
|
-
handler: (params: { url: Params<Path> }, auth: Auth) => Promise<Res>;
|
|
226
|
-
}): AuthenticatedRoute<Path, "DELETE", Res, Auth, undefined>;
|
|
227
|
-
|
|
228
|
-
// Authenticated route: auth, with query
|
|
229
|
-
function del<Res extends unknown, Auth extends Authentication, Query extends unknown>(config: {
|
|
230
|
-
authenticator: AuthenticationFunction<Auth>;
|
|
231
|
-
queryValidator: ValidatorFunction<Query>;
|
|
232
|
-
handler: (params: { url: Params<Path>; query: Query }, auth: Auth) => Promise<Res>;
|
|
233
|
-
}): AuthenticatedRoute<Path, "DELETE", Res, Auth, Query>;
|
|
234
|
-
|
|
235
|
-
function del(
|
|
236
|
-
config:
|
|
237
|
-
| { handler: (params: { url: Params<Path> }) => Promise<any> }
|
|
238
|
-
| { queryValidator: ValidatorFunction<any>; handler: (params: { url: Params<Path>; query: any }) => Promise<any> }
|
|
239
|
-
| { authenticator: AuthenticationFunction<any>; handler: (params: { url: Params<Path> }, auth: any) => Promise<any> }
|
|
240
|
-
| { authenticator: AuthenticationFunction<any>; queryValidator: ValidatorFunction<any>; handler: (params: { url: Params<Path>; query: any }, auth: any) => Promise<any> }
|
|
241
|
-
): OpenRoute<Path, "DELETE", any, any> | AuthenticatedRoute<Path, "DELETE", any, any, any> {
|
|
242
|
-
if ("authenticator" in config) {
|
|
243
|
-
return {
|
|
244
|
-
...config,
|
|
245
|
-
type: "authenticated",
|
|
246
|
-
path,
|
|
247
|
-
method: "DELETE",
|
|
248
|
-
} satisfies AuthenticatedRoute<Path, "DELETE", any, any, any>;
|
|
249
|
-
} else {
|
|
250
|
-
return { ...config, type: "open", path, method: "DELETE" } satisfies OpenRoute<
|
|
251
|
-
Path,
|
|
252
|
-
"DELETE",
|
|
253
|
-
any,
|
|
254
|
-
any
|
|
255
|
-
>;
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
return {
|
|
260
|
-
get,
|
|
261
|
-
post,
|
|
262
|
-
put,
|
|
263
|
-
delete: del,
|
|
264
|
-
};
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
/**
|
|
268
|
-
* Provides an Ednpoint creater. Would maybe like some other internal stuff? Lowkey... I think we
|
|
269
|
-
* all might just end up using the helper functions of get and del and such.
|
|
270
|
-
* @param _ - this param is still needed because the type is determined at compile time.
|
|
271
|
-
*/
|
|
272
|
-
export function createRouter<BasePath extends string>(_: BasePath): Router<BasePath> {
|
|
273
|
-
return {
|
|
274
|
-
createEndpoint: <Path extends `${BasePath}${string}`>(path: Path) => createEndpoint(path),
|
|
275
|
-
createSubrouter: <Path extends `${BasePath}${string}`>(path: Path) => createRouter(path),
|
|
276
|
-
};
|
|
277
|
-
}
|
package/src/router/tmp.sh
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
curl \
|
|
3
|
-
--user "euuoxeqo:3351126f-00d2-4964-840f-a8e29fb4f2c5" \
|
|
4
|
-
--digest \
|
|
5
|
-
--header 'Accept: application/vnd.atlas.2024-11-13+json' \
|
|
6
|
-
--header 'Content-Type: application/json' \
|
|
7
|
-
--request GET "https://cloud.mongodb.com/api/atlas/v2/groups/64619e3fea3ebc1bb3d691f3/streams/accountDetails?cloudProvider=aws®ionName=US_EAST_1"
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
{
|
|
11
|
-
"awsAccountId":"821274765805",
|
|
12
|
-
"cidrBlock":"192.168.248.0/21",
|
|
13
|
-
"vpcId":"vpc-04a8f4b80f14357ef",
|
|
14
|
-
"cloudProvider":"aws"
|
|
15
|
-
}
|
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
import { Params } from "./params.types";
|
|
2
|
-
import {
|
|
3
|
-
Authentication,
|
|
4
|
-
AuthenticatedRoute,
|
|
5
|
-
FullRoute,
|
|
6
|
-
OpenRoute,
|
|
7
|
-
ValidatedRoute,
|
|
8
|
-
} from "./routes.types";
|
|
9
|
-
import { RestMethod } from "./routes.types";
|
|
10
|
-
|
|
11
|
-
export type ValidatorFunction<T extends unknown = unknown> = (data: unknown) => T;
|
|
12
|
-
export type AuthenticationFunction<T extends Authentication> = (
|
|
13
|
-
headers: Record<string, string>
|
|
14
|
-
) => T;
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* This is the most confusing part of the type system, but also key.
|
|
18
|
-
* This type is used to force type inferenece when creating your endpoints.
|
|
19
|
-
* This is the structure to provide `function overload`s. This is so you can have the same function
|
|
20
|
-
* (in our case get,put,post,delete) but allow differnt configurations.
|
|
21
|
-
*
|
|
22
|
-
* These configurations need to be strongly typed force the developers into using the tools.
|
|
23
|
-
*
|
|
24
|
-
* Want to allow Auth? - Gotta pass in authenticator and the type system handles it
|
|
25
|
-
*
|
|
26
|
-
* Also, this is where the core of the Zod system is. We force the body to be a zod validated input.
|
|
27
|
-
* Luckily, this is pretty easy to replace.
|
|
28
|
-
* PART of me wanted to further abstract it such that you needed a translation function but
|
|
29
|
-
* that seemed overengineerd
|
|
30
|
-
*
|
|
31
|
-
*/
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Configuration type for POST/PUT/DELETE endpoints.
|
|
35
|
-
* These methods require a request body, so they always need a validator.
|
|
36
|
-
*
|
|
37
|
-
* Four variants (with/without auth × with/without query):
|
|
38
|
-
* 1. Validated only, no query: validator + handler(params, body)
|
|
39
|
-
* 2. Validated only, with query: validator + queryValidator + handler(params, body)
|
|
40
|
-
* 3. Full (auth + validated), no query: authenticator + validator + handler(params, auth, body)
|
|
41
|
-
* 4. Full (auth + validated), with query: authenticator + validator + queryValidator + handler(params, auth, body)
|
|
42
|
-
*/
|
|
43
|
-
export type EndpointCreationFunction<Path extends string, Method extends RestMethod> = {
|
|
44
|
-
// Validated route: no auth, no query
|
|
45
|
-
<Res extends unknown, RequestBody extends unknown>(
|
|
46
|
-
config: {
|
|
47
|
-
authenticator?: never;
|
|
48
|
-
validator: ValidatorFunction<RequestBody>;
|
|
49
|
-
queryValidator?: never;
|
|
50
|
-
handler: (params: { url: Params<Path> }, body: RequestBody) => Promise<Res>;
|
|
51
|
-
}
|
|
52
|
-
): ValidatedRoute<Path, Method, Res, RequestBody, undefined>;
|
|
53
|
-
|
|
54
|
-
// Validated route: no auth, with query
|
|
55
|
-
<Res extends unknown, RequestBody extends unknown, Query extends unknown>(
|
|
56
|
-
config: {
|
|
57
|
-
authenticator?: never;
|
|
58
|
-
validator: ValidatorFunction<RequestBody>;
|
|
59
|
-
queryValidator: ValidatorFunction<Query>;
|
|
60
|
-
handler: (
|
|
61
|
-
params: { url: Params<Path>; query: Query },
|
|
62
|
-
body: RequestBody
|
|
63
|
-
) => Promise<Res>;
|
|
64
|
-
}
|
|
65
|
-
): ValidatedRoute<Path, Method, Res, RequestBody, Query>;
|
|
66
|
-
|
|
67
|
-
// Full route: auth + body validation, no query
|
|
68
|
-
<Res extends unknown, RequestBody extends unknown, Auth extends Authentication>(
|
|
69
|
-
config: {
|
|
70
|
-
authenticator: AuthenticationFunction<Auth>;
|
|
71
|
-
validator: ValidatorFunction<RequestBody>;
|
|
72
|
-
queryValidator?: never;
|
|
73
|
-
handler: (params: { url: Params<Path> }, auth: Auth, body: RequestBody) => Promise<Res>;
|
|
74
|
-
}
|
|
75
|
-
): FullRoute<Path, Method, Res, RequestBody, Auth, undefined>;
|
|
76
|
-
|
|
77
|
-
// Full route: auth + body validation, with query
|
|
78
|
-
<
|
|
79
|
-
Res extends unknown,
|
|
80
|
-
RequestBody extends unknown,
|
|
81
|
-
Auth extends Authentication,
|
|
82
|
-
Query extends unknown,
|
|
83
|
-
>(
|
|
84
|
-
config: {
|
|
85
|
-
authenticator: AuthenticationFunction<Auth>;
|
|
86
|
-
validator: ValidatorFunction<RequestBody>;
|
|
87
|
-
queryValidator: ValidatorFunction<Query>;
|
|
88
|
-
handler: (
|
|
89
|
-
params: { url: Params<Path>; query: Query },
|
|
90
|
-
auth: Auth,
|
|
91
|
-
body: RequestBody
|
|
92
|
-
) => Promise<Res>;
|
|
93
|
-
}
|
|
94
|
-
): FullRoute<Path, Method, Res, RequestBody, Auth, Query>;
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Configuration type for GET/DELETE endpoints.
|
|
99
|
-
* These methods cannot have a request body, so no validator.
|
|
100
|
-
*
|
|
101
|
-
* Four variants (with/without auth × with/without query):
|
|
102
|
-
* 1. Open, no query: just handler(params)
|
|
103
|
-
* 2. Open, with query: queryValidator + handler(params)
|
|
104
|
-
* 3. Authenticated, no query: authenticator + handler(params, auth)
|
|
105
|
-
* 4. Authenticated, with query: authenticator + queryValidator + handler(params, auth)
|
|
106
|
-
*/
|
|
107
|
-
export type GetEndpointCreationFunction<Path extends string, Method extends RestMethod> = {
|
|
108
|
-
// Open route: no auth, no query
|
|
109
|
-
<Res extends unknown>(
|
|
110
|
-
config: {
|
|
111
|
-
authenticator?: never;
|
|
112
|
-
queryValidator?: never;
|
|
113
|
-
handler: (params: { url: Params<Path> }) => Promise<Res>;
|
|
114
|
-
}
|
|
115
|
-
): OpenRoute<Path, Method, Res, undefined>;
|
|
116
|
-
|
|
117
|
-
// Open route: no auth, with query
|
|
118
|
-
<Res extends unknown, Query extends unknown>(
|
|
119
|
-
config: {
|
|
120
|
-
authenticator?: never;
|
|
121
|
-
queryValidator: ValidatorFunction<Query>;
|
|
122
|
-
handler: (params: { url: Params<Path>; query: Query }) => Promise<Res>;
|
|
123
|
-
}
|
|
124
|
-
): OpenRoute<Path, Method, Res, Query>;
|
|
125
|
-
|
|
126
|
-
// Authenticated route: auth, no query
|
|
127
|
-
<Res extends unknown, Auth extends Authentication>(
|
|
128
|
-
config: {
|
|
129
|
-
authenticator: AuthenticationFunction<Auth>;
|
|
130
|
-
queryValidator?: never;
|
|
131
|
-
handler: (params: { url: Params<Path> }, auth: Auth) => Promise<Res>;
|
|
132
|
-
}
|
|
133
|
-
): AuthenticatedRoute<Path, Method, Res, Auth, undefined>;
|
|
134
|
-
|
|
135
|
-
// Authenticated route: auth, with query
|
|
136
|
-
<Res extends unknown, Auth extends Authentication, Query extends unknown>(
|
|
137
|
-
config: {
|
|
138
|
-
authenticator: AuthenticationFunction<Auth>;
|
|
139
|
-
queryValidator: ValidatorFunction<Query>;
|
|
140
|
-
handler: (params: { url: Params<Path>; query: Query }, auth: Auth) => Promise<Res>;
|
|
141
|
-
}
|
|
142
|
-
): AuthenticatedRoute<Path, Method, Res, Auth, Query>;
|
|
143
|
-
};
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
type ExtractUrlParams<Path extends string> = Path extends `${string}/:${infer Param}/${infer Rest}`
|
|
2
|
-
? Param | ExtractUrlParams<Rest>
|
|
3
|
-
: Path extends `${string}/:${infer Param}`
|
|
4
|
-
? Param
|
|
5
|
-
: never;
|
|
6
|
-
|
|
7
|
-
// Yields the full object. Otherwise, we end up with a bunch of & during type inference
|
|
8
|
-
type Expand<T> = T extends infer O ? { [K in keyof O]: O[K] } : never;
|
|
9
|
-
|
|
10
|
-
// Helper to use Expand with Path
|
|
11
|
-
export type Params<Path extends string> = Expand<{
|
|
12
|
-
[K in ExtractUrlParams<Path>]: string;
|
|
13
|
-
}>;
|