@leo-h/create-nodejs-app 1.0.51 → 1.0.53
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/package.json +1 -1
- package/templates/fastify/.lintstagedrc.json +1 -1
- package/templates/fastify/src/core/fastify/middleware.ts +20 -0
- package/templates/fastify/src/core/schema.ts +5 -0
- package/templates/fastify/src/http/controllers/hello-multipart.controller.ts +1 -1
- package/templates/fastify/src/http/controllers/hello.controller.ts +1 -1
- package/templates/nest/package.json +1 -1
- package/templates/nest/pnpm-lock.yaml +118 -10
- package/templates/react-vite/.lintstagedrc.json +3 -1
- package/templates/react-vite/.vscode/settings.json +9 -0
- package/templates/react-vite/api/errors.ts +3 -3
- package/templates/react-vite/api/swr-fetcher.ts +37 -10
- package/templates/react-vite/gitignore +0 -1
- package/templates/react-vite/src/app.tsx +1 -1
- package/templates/react-vite/src/hooks/use-current-route.ts +24 -0
- package/templates/react-vite/src/lib/react-router-config.tsx +32 -0
- package/templates/react-vite/src/pages/_layouts/app.tsx +4 -7
- package/templates/react-vite/src/pages/_layouts/auth.tsx +4 -7
- package/templates/react-vite/src/pages/app/dashboard/{dashboard.tsx → index.tsx} +1 -1
- package/templates/react-vite/src/pages/auth/sign-in/index.tsx +1 -1
- package/templates/react-vite/src/routes.ts +27 -0
- package/templates/react-vite/src/@types/routes.ts +0 -24
- package/templates/react-vite/src/routes.tsx +0 -49
- /package/templates/fastify/src/core/{create-controller-response-schema.ts → fastify/create-controller-response-schema.ts} +0 -0
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@leo-h/create-nodejs-app",
|
3
|
-
"version": "1.0.
|
3
|
+
"version": "1.0.53",
|
4
4
|
"packageManager": "pnpm@9.15.9",
|
5
5
|
"author": "Leonardo Henrique <leonardo0507.business@gmail.com>",
|
6
6
|
"description": "Create a modern Node.js app with TypeScript using one command.",
|
@@ -0,0 +1,20 @@
|
|
1
|
+
import { BaseError } from "@/http/errors";
|
2
|
+
import { Constructor } from "type-fest";
|
3
|
+
|
4
|
+
export type MiddlewareHandlerOutput<
|
5
|
+
Errors extends ReadonlyArray<Constructor<BaseError>>,
|
6
|
+
> = Promise<MiddlewareLeft<InstanceType<Errors[number]>> | void>;
|
7
|
+
|
8
|
+
export const middleware = Object.freeze({
|
9
|
+
left,
|
10
|
+
} as const);
|
11
|
+
|
12
|
+
class MiddlewareLeft<Error extends BaseError> {
|
13
|
+
public constructor(public readonly error: Error) {
|
14
|
+
throw error;
|
15
|
+
}
|
16
|
+
}
|
17
|
+
|
18
|
+
function left<Error extends BaseError>(error: Error) {
|
19
|
+
return new MiddlewareLeft<Error>(error);
|
20
|
+
}
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import { FastifyZodInstance } from "@/@types/fastify";
|
2
|
-
import { createControllerResponseSchema } from "@/core/create-controller-response-schema";
|
2
|
+
import { createControllerResponseSchema } from "@/core/fastify/create-controller-response-schema";
|
3
3
|
import { z } from "zod";
|
4
4
|
import { InternalServerError, ValidationError } from "../errors";
|
5
5
|
import {
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import { FastifyZodInstance } from "@/@types/fastify";
|
2
|
-
import { createControllerResponseSchema } from "@/core/create-controller-response-schema";
|
2
|
+
import { createControllerResponseSchema } from "@/core/fastify/create-controller-response-schema";
|
3
3
|
import { z } from "zod";
|
4
4
|
import { InternalServerError, ValidationError } from "../errors";
|
5
5
|
|
@@ -103,8 +103,8 @@ importers:
|
|
103
103
|
specifier: 3.5.3
|
104
104
|
version: 3.5.3
|
105
105
|
supertest:
|
106
|
-
specifier: 7.1.
|
107
|
-
version: 7.1.
|
106
|
+
specifier: 7.1.4
|
107
|
+
version: 7.1.4
|
108
108
|
type-fest:
|
109
109
|
specifier: 4.38.0
|
110
110
|
version: 4.38.0
|
@@ -1211,6 +1211,10 @@ packages:
|
|
1211
1211
|
resolution: {integrity: sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==}
|
1212
1212
|
engines: {node: '>=14.16'}
|
1213
1213
|
|
1214
|
+
call-bind-apply-helpers@1.0.2:
|
1215
|
+
resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
|
1216
|
+
engines: {node: '>= 0.4'}
|
1217
|
+
|
1214
1218
|
call-bind@1.0.7:
|
1215
1219
|
resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==}
|
1216
1220
|
engines: {node: '>= 0.4'}
|
@@ -1459,6 +1463,10 @@ packages:
|
|
1459
1463
|
resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==}
|
1460
1464
|
engines: {node: '>=12'}
|
1461
1465
|
|
1466
|
+
dunder-proto@1.0.1:
|
1467
|
+
resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
|
1468
|
+
engines: {node: '>= 0.4'}
|
1469
|
+
|
1462
1470
|
eastasianwidth@0.2.0:
|
1463
1471
|
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
|
1464
1472
|
|
@@ -1496,6 +1504,10 @@ packages:
|
|
1496
1504
|
resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==}
|
1497
1505
|
engines: {node: '>= 0.4'}
|
1498
1506
|
|
1507
|
+
es-define-property@1.0.1:
|
1508
|
+
resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==}
|
1509
|
+
engines: {node: '>= 0.4'}
|
1510
|
+
|
1499
1511
|
es-errors@1.3.0:
|
1500
1512
|
resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
|
1501
1513
|
engines: {node: '>= 0.4'}
|
@@ -1503,6 +1515,14 @@ packages:
|
|
1503
1515
|
es-module-lexer@1.5.4:
|
1504
1516
|
resolution: {integrity: sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==}
|
1505
1517
|
|
1518
|
+
es-object-atoms@1.1.1:
|
1519
|
+
resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==}
|
1520
|
+
engines: {node: '>= 0.4'}
|
1521
|
+
|
1522
|
+
es-set-tostringtag@2.1.0:
|
1523
|
+
resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==}
|
1524
|
+
engines: {node: '>= 0.4'}
|
1525
|
+
|
1506
1526
|
esbuild@0.21.5:
|
1507
1527
|
resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==}
|
1508
1528
|
engines: {node: '>=12'}
|
@@ -1752,6 +1772,10 @@ packages:
|
|
1752
1772
|
resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==}
|
1753
1773
|
engines: {node: '>= 6'}
|
1754
1774
|
|
1775
|
+
form-data@4.0.4:
|
1776
|
+
resolution: {integrity: sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==}
|
1777
|
+
engines: {node: '>= 6'}
|
1778
|
+
|
1755
1779
|
formidable@3.5.4:
|
1756
1780
|
resolution: {integrity: sha512-YikH+7CUTOtP44ZTnUhR7Ic2UASBPOqmaRkRKxRbywPTe5VxF7RRCck4af9wutiZ/QKM5nME9Bie2fFaPz5Gug==}
|
1757
1781
|
engines: {node: '>=14.0.0'}
|
@@ -1793,6 +1817,14 @@ packages:
|
|
1793
1817
|
resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==}
|
1794
1818
|
engines: {node: '>= 0.4'}
|
1795
1819
|
|
1820
|
+
get-intrinsic@1.3.0:
|
1821
|
+
resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
|
1822
|
+
engines: {node: '>= 0.4'}
|
1823
|
+
|
1824
|
+
get-proto@1.0.1:
|
1825
|
+
resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==}
|
1826
|
+
engines: {node: '>= 0.4'}
|
1827
|
+
|
1796
1828
|
get-stream@6.0.1:
|
1797
1829
|
resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==}
|
1798
1830
|
engines: {node: '>=10'}
|
@@ -1840,6 +1872,10 @@ packages:
|
|
1840
1872
|
gopd@1.0.1:
|
1841
1873
|
resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==}
|
1842
1874
|
|
1875
|
+
gopd@1.2.0:
|
1876
|
+
resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
|
1877
|
+
engines: {node: '>= 0.4'}
|
1878
|
+
|
1843
1879
|
got@13.0.0:
|
1844
1880
|
resolution: {integrity: sha512-XfBk1CxOOScDcMr9O1yKkNaQyy865NbYs+F7dr4H0LZMVgCj2Le59k6PqbNHoL5ToeaEQUYh6c6yMfVcc6SJxA==}
|
1845
1881
|
engines: {node: '>=16'}
|
@@ -1873,6 +1909,14 @@ packages:
|
|
1873
1909
|
resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==}
|
1874
1910
|
engines: {node: '>= 0.4'}
|
1875
1911
|
|
1912
|
+
has-symbols@1.1.0:
|
1913
|
+
resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==}
|
1914
|
+
engines: {node: '>= 0.4'}
|
1915
|
+
|
1916
|
+
has-tostringtag@1.0.2:
|
1917
|
+
resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==}
|
1918
|
+
engines: {node: '>= 0.4'}
|
1919
|
+
|
1876
1920
|
hasown@2.0.2:
|
1877
1921
|
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
|
1878
1922
|
engines: {node: '>= 0.4'}
|
@@ -2170,6 +2214,10 @@ packages:
|
|
2170
2214
|
resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==}
|
2171
2215
|
engines: {node: '>=10'}
|
2172
2216
|
|
2217
|
+
math-intrinsics@1.1.0:
|
2218
|
+
resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
|
2219
|
+
engines: {node: '>= 0.4'}
|
2220
|
+
|
2173
2221
|
media-typer@0.3.0:
|
2174
2222
|
resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==}
|
2175
2223
|
engines: {node: '>= 0.6'}
|
@@ -2881,12 +2929,12 @@ packages:
|
|
2881
2929
|
resolution: {integrity: sha512-FhwotcEqjr241ZbjFzjlIYg6c5/L/s4yBGWSMvJ9UoExiSqL+FnFA/CaeZx17WGaZMS/4SOZp8wH18jSS4R4lw==}
|
2882
2930
|
engines: {node: '>=16'}
|
2883
2931
|
|
2884
|
-
superagent@10.2.
|
2885
|
-
resolution: {integrity: sha512-
|
2932
|
+
superagent@10.2.3:
|
2933
|
+
resolution: {integrity: sha512-y/hkYGeXAj7wUMjxRbB21g/l6aAEituGXM9Rwl4o20+SX3e8YOSV6BxFXl+dL3Uk0mjSL3kCbNkwURm8/gEDig==}
|
2886
2934
|
engines: {node: '>=14.18.0'}
|
2887
2935
|
|
2888
|
-
supertest@7.1.
|
2889
|
-
resolution: {integrity: sha512-
|
2936
|
+
supertest@7.1.4:
|
2937
|
+
resolution: {integrity: sha512-tjLPs7dVyqgItVFirHYqe2T+MfWc2VOBQ8QFKKbWTA3PU7liZR8zoSpAi/C1k1ilm9RsXIKYf197oap9wXGVYg==}
|
2890
2938
|
engines: {node: '>=14.18.0'}
|
2891
2939
|
|
2892
2940
|
supports-color@5.5.0:
|
@@ -4393,6 +4441,11 @@ snapshots:
|
|
4393
4441
|
normalize-url: 8.0.1
|
4394
4442
|
responselike: 3.0.0
|
4395
4443
|
|
4444
|
+
call-bind-apply-helpers@1.0.2:
|
4445
|
+
dependencies:
|
4446
|
+
es-errors: 1.3.0
|
4447
|
+
function-bind: 1.1.2
|
4448
|
+
|
4396
4449
|
call-bind@1.0.7:
|
4397
4450
|
dependencies:
|
4398
4451
|
es-define-property: 1.0.0
|
@@ -4624,6 +4677,12 @@ snapshots:
|
|
4624
4677
|
|
4625
4678
|
dotenv@16.4.7: {}
|
4626
4679
|
|
4680
|
+
dunder-proto@1.0.1:
|
4681
|
+
dependencies:
|
4682
|
+
call-bind-apply-helpers: 1.0.2
|
4683
|
+
es-errors: 1.3.0
|
4684
|
+
gopd: 1.2.0
|
4685
|
+
|
4627
4686
|
eastasianwidth@0.2.0: {}
|
4628
4687
|
|
4629
4688
|
ee-first@1.1.1: {}
|
@@ -4654,10 +4713,23 @@ snapshots:
|
|
4654
4713
|
dependencies:
|
4655
4714
|
get-intrinsic: 1.2.4
|
4656
4715
|
|
4716
|
+
es-define-property@1.0.1: {}
|
4717
|
+
|
4657
4718
|
es-errors@1.3.0: {}
|
4658
4719
|
|
4659
4720
|
es-module-lexer@1.5.4: {}
|
4660
4721
|
|
4722
|
+
es-object-atoms@1.1.1:
|
4723
|
+
dependencies:
|
4724
|
+
es-errors: 1.3.0
|
4725
|
+
|
4726
|
+
es-set-tostringtag@2.1.0:
|
4727
|
+
dependencies:
|
4728
|
+
es-errors: 1.3.0
|
4729
|
+
get-intrinsic: 1.3.0
|
4730
|
+
has-tostringtag: 1.0.2
|
4731
|
+
hasown: 2.0.2
|
4732
|
+
|
4661
4733
|
esbuild@0.21.5:
|
4662
4734
|
optionalDependencies:
|
4663
4735
|
'@esbuild/aix-ppc64': 0.21.5
|
@@ -5035,6 +5107,14 @@ snapshots:
|
|
5035
5107
|
combined-stream: 1.0.8
|
5036
5108
|
mime-types: 2.1.35
|
5037
5109
|
|
5110
|
+
form-data@4.0.4:
|
5111
|
+
dependencies:
|
5112
|
+
asynckit: 0.4.0
|
5113
|
+
combined-stream: 1.0.8
|
5114
|
+
es-set-tostringtag: 2.1.0
|
5115
|
+
hasown: 2.0.2
|
5116
|
+
mime-types: 2.1.35
|
5117
|
+
|
5038
5118
|
formidable@3.5.4:
|
5039
5119
|
dependencies:
|
5040
5120
|
'@paralleldrive/cuid2': 2.2.2
|
@@ -5073,6 +5153,24 @@ snapshots:
|
|
5073
5153
|
has-symbols: 1.0.3
|
5074
5154
|
hasown: 2.0.2
|
5075
5155
|
|
5156
|
+
get-intrinsic@1.3.0:
|
5157
|
+
dependencies:
|
5158
|
+
call-bind-apply-helpers: 1.0.2
|
5159
|
+
es-define-property: 1.0.1
|
5160
|
+
es-errors: 1.3.0
|
5161
|
+
es-object-atoms: 1.1.1
|
5162
|
+
function-bind: 1.1.2
|
5163
|
+
get-proto: 1.0.1
|
5164
|
+
gopd: 1.2.0
|
5165
|
+
has-symbols: 1.1.0
|
5166
|
+
hasown: 2.0.2
|
5167
|
+
math-intrinsics: 1.1.0
|
5168
|
+
|
5169
|
+
get-proto@1.0.1:
|
5170
|
+
dependencies:
|
5171
|
+
dunder-proto: 1.0.1
|
5172
|
+
es-object-atoms: 1.1.1
|
5173
|
+
|
5076
5174
|
get-stream@6.0.1: {}
|
5077
5175
|
|
5078
5176
|
get-stream@8.0.1: {}
|
@@ -5127,6 +5225,8 @@ snapshots:
|
|
5127
5225
|
dependencies:
|
5128
5226
|
get-intrinsic: 1.2.4
|
5129
5227
|
|
5228
|
+
gopd@1.2.0: {}
|
5229
|
+
|
5130
5230
|
got@13.0.0:
|
5131
5231
|
dependencies:
|
5132
5232
|
'@sindresorhus/is': 5.6.0
|
@@ -5159,6 +5259,12 @@ snapshots:
|
|
5159
5259
|
|
5160
5260
|
has-symbols@1.0.3: {}
|
5161
5261
|
|
5262
|
+
has-symbols@1.1.0: {}
|
5263
|
+
|
5264
|
+
has-tostringtag@1.0.2:
|
5265
|
+
dependencies:
|
5266
|
+
has-symbols: 1.0.3
|
5267
|
+
|
5162
5268
|
hasown@2.0.2:
|
5163
5269
|
dependencies:
|
5164
5270
|
function-bind: 1.1.2
|
@@ -5471,6 +5577,8 @@ snapshots:
|
|
5471
5577
|
dependencies:
|
5472
5578
|
semver: 7.6.3
|
5473
5579
|
|
5580
|
+
math-intrinsics@1.1.0: {}
|
5581
|
+
|
5474
5582
|
media-typer@0.3.0: {}
|
5475
5583
|
|
5476
5584
|
memfs@3.5.3:
|
@@ -6157,13 +6265,13 @@ snapshots:
|
|
6157
6265
|
'@tokenizer/token': 0.3.0
|
6158
6266
|
peek-readable: 5.3.1
|
6159
6267
|
|
6160
|
-
superagent@10.2.
|
6268
|
+
superagent@10.2.3:
|
6161
6269
|
dependencies:
|
6162
6270
|
component-emitter: 1.3.1
|
6163
6271
|
cookiejar: 2.1.4
|
6164
6272
|
debug: 4.4.0
|
6165
6273
|
fast-safe-stringify: 2.1.1
|
6166
|
-
form-data: 4.0.
|
6274
|
+
form-data: 4.0.4
|
6167
6275
|
formidable: 3.5.4
|
6168
6276
|
methods: 1.1.2
|
6169
6277
|
mime: 2.6.0
|
@@ -6171,10 +6279,10 @@ snapshots:
|
|
6171
6279
|
transitivePeerDependencies:
|
6172
6280
|
- supports-color
|
6173
6281
|
|
6174
|
-
supertest@7.1.
|
6282
|
+
supertest@7.1.4:
|
6175
6283
|
dependencies:
|
6176
6284
|
methods: 1.1.2
|
6177
|
-
superagent: 10.2.
|
6285
|
+
superagent: 10.2.3
|
6178
6286
|
transitivePeerDependencies:
|
6179
6287
|
- supports-color
|
6180
6288
|
|
@@ -6,9 +6,9 @@ export class ApiError {
|
|
6
6
|
) {}
|
7
7
|
}
|
8
8
|
|
9
|
-
export class
|
9
|
+
export class ApiUnknownError {
|
10
10
|
static readonly message =
|
11
|
-
"Houve uma falha inesperada ao se comunicar com nosso servidor.
|
11
|
+
"Houve uma falha inesperada ao se comunicar com nosso servidor. Tente novamente em alguns segundos ou nos contate se o problema persistir.";
|
12
12
|
|
13
|
-
constructor(public message =
|
13
|
+
constructor(public message = ApiUnknownError.message) {}
|
14
14
|
}
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import { publicEnv } from "@/public-env";
|
2
|
-
import { ApiError,
|
2
|
+
import { ApiError, ApiUnknownError } from "./errors";
|
3
3
|
|
4
|
-
type SwrFetcherOutput = {
|
4
|
+
export type SwrFetcherOutput = {
|
5
5
|
body: unknown;
|
6
6
|
status: number;
|
7
7
|
headers: Headers;
|
@@ -11,16 +11,19 @@ export async function swrFetcher<Output extends SwrFetcherOutput>(
|
|
11
11
|
endpointUrl: RequestInfo | URL,
|
12
12
|
options: RequestInit,
|
13
13
|
): Promise<Output> {
|
14
|
-
const url =
|
14
|
+
const url = getFullUrlFromApiByEndpoint(endpointUrl);
|
15
|
+
let response: Response;
|
15
16
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
17
|
+
try {
|
18
|
+
response = await fetch(url, {
|
19
|
+
credentials: "include",
|
20
|
+
...options,
|
21
|
+
});
|
22
|
+
} catch {
|
23
|
+
throw new ApiUnknownError();
|
20
24
|
}
|
21
25
|
|
22
|
-
|
23
|
-
let body: unknown;
|
26
|
+
let body: unknown = null;
|
24
27
|
|
25
28
|
if (
|
26
29
|
response.headers.get("Content-Type")?.includes("application/json") &&
|
@@ -38,7 +41,7 @@ export async function swrFetcher<Output extends SwrFetcherOutput>(
|
|
38
41
|
|
39
42
|
if (error) throw new ApiError(error.statusCode, error.error, error.message);
|
40
43
|
|
41
|
-
throw new
|
44
|
+
throw new ApiUnknownError();
|
42
45
|
}
|
43
46
|
|
44
47
|
return {
|
@@ -47,3 +50,27 @@ export async function swrFetcher<Output extends SwrFetcherOutput>(
|
|
47
50
|
headers: response.headers,
|
48
51
|
} as Awaited<Output>;
|
49
52
|
}
|
53
|
+
|
54
|
+
function getFullUrlFromApiByEndpoint(endpointUrl: RequestInfo | URL) {
|
55
|
+
const url = new URL(publicEnv.API_BASE_URL);
|
56
|
+
const [pathname, stringifiedSearchParams] = endpointUrl.toString().split("?");
|
57
|
+
|
58
|
+
if (url.pathname.endsWith("/")) {
|
59
|
+
url.pathname = pathname;
|
60
|
+
} else {
|
61
|
+
url.pathname += pathname;
|
62
|
+
}
|
63
|
+
|
64
|
+
if (stringifiedSearchParams) {
|
65
|
+
const searchParams = new URLSearchParams(stringifiedSearchParams);
|
66
|
+
|
67
|
+
for (const searchParamKey of Array.from(searchParams.keys())) {
|
68
|
+
const searchParamValue = searchParams.get(searchParamKey);
|
69
|
+
|
70
|
+
if (searchParamValue)
|
71
|
+
url.searchParams.set(searchParamKey, searchParamValue);
|
72
|
+
}
|
73
|
+
}
|
74
|
+
|
75
|
+
return url;
|
76
|
+
}
|
@@ -0,0 +1,24 @@
|
|
1
|
+
import { routeGroups } from "@/routes";
|
2
|
+
import { useLocation } from "react-router";
|
3
|
+
|
4
|
+
type RouteGroup = (typeof routeGroups)[number];
|
5
|
+
|
6
|
+
type Route = RouteGroup extends Record<string, infer Route> ? Route : never;
|
7
|
+
|
8
|
+
export function useCurrentRoute() {
|
9
|
+
const { pathname } = useLocation();
|
10
|
+
let currentRoute: Route | null = null;
|
11
|
+
|
12
|
+
for (const routeGroup of routeGroups) {
|
13
|
+
const matchedRoute = Object.values(routeGroup).find(route => {
|
14
|
+
return route.path === pathname;
|
15
|
+
});
|
16
|
+
|
17
|
+
if (matchedRoute) {
|
18
|
+
currentRoute = matchedRoute;
|
19
|
+
break;
|
20
|
+
}
|
21
|
+
}
|
22
|
+
|
23
|
+
return currentRoute;
|
24
|
+
}
|
@@ -0,0 +1,32 @@
|
|
1
|
+
import { AppLayout } from "@/pages/_layouts/app";
|
2
|
+
import { AuthLayout } from "@/pages/_layouts/auth";
|
3
|
+
import { privateRoutes, publicRoutes } from "@/routes";
|
4
|
+
import { createBrowserRouter, RouteObject } from "react-router";
|
5
|
+
|
6
|
+
export const router = createBrowserRouter([
|
7
|
+
{
|
8
|
+
element: <AuthLayout />,
|
9
|
+
children: [
|
10
|
+
...Object.values(publicRoutes).map(
|
11
|
+
publicRoute =>
|
12
|
+
({
|
13
|
+
path: publicRoute.path,
|
14
|
+
element: <publicRoute.element />,
|
15
|
+
index: true,
|
16
|
+
}) satisfies RouteObject,
|
17
|
+
),
|
18
|
+
],
|
19
|
+
},
|
20
|
+
{
|
21
|
+
element: <AppLayout />,
|
22
|
+
children: [
|
23
|
+
...Object.values(privateRoutes).map(
|
24
|
+
publicRoute =>
|
25
|
+
({
|
26
|
+
path: publicRoute.path,
|
27
|
+
element: <publicRoute.element />,
|
28
|
+
}) satisfies RouteObject,
|
29
|
+
),
|
30
|
+
],
|
31
|
+
},
|
32
|
+
]);
|
@@ -1,15 +1,12 @@
|
|
1
|
-
import {
|
2
|
-
import { Outlet
|
1
|
+
import { useCurrentRoute } from "@/hooks/use-current-route";
|
2
|
+
import { Outlet } from "react-router";
|
3
3
|
|
4
4
|
export function AppLayout() {
|
5
|
-
const
|
6
|
-
const currentPublicRoute = Object.values(privateRoutes).find(privateRoute => {
|
7
|
-
return privateRoute.path === pathname;
|
8
|
-
});
|
5
|
+
const currentRoute = useCurrentRoute();
|
9
6
|
|
10
7
|
return (
|
11
8
|
<>
|
12
|
-
{
|
9
|
+
{currentRoute && <title>{currentRoute.title}</title>}
|
13
10
|
|
14
11
|
<div>
|
15
12
|
<Outlet />
|
@@ -1,15 +1,12 @@
|
|
1
|
-
import {
|
2
|
-
import { Outlet
|
1
|
+
import { useCurrentRoute } from "@/hooks/use-current-route";
|
2
|
+
import { Outlet } from "react-router";
|
3
3
|
|
4
4
|
export function AuthLayout() {
|
5
|
-
const
|
6
|
-
const currentPublicRoute = Object.values(publicRoutes).find(publicRoute => {
|
7
|
-
return publicRoute.path === pathname;
|
8
|
-
});
|
5
|
+
const currentRoute = useCurrentRoute();
|
9
6
|
|
10
7
|
return (
|
11
8
|
<>
|
12
|
-
{
|
9
|
+
{currentRoute && <title>{currentRoute.title}</title>}
|
13
10
|
|
14
11
|
<div>
|
15
12
|
<Outlet />
|
@@ -0,0 +1,27 @@
|
|
1
|
+
import { DashboardPage } from "./pages/app/dashboard";
|
2
|
+
import { SignInPage } from "./pages/auth/sign-in";
|
3
|
+
import { publicEnv } from "./public-env";
|
4
|
+
|
5
|
+
export const publicRoutes = Object.freeze({
|
6
|
+
signIn: {
|
7
|
+
path: "/",
|
8
|
+
element: SignInPage,
|
9
|
+
title: createPageTitleTemplate("Sign In"),
|
10
|
+
label: "Sign In",
|
11
|
+
},
|
12
|
+
} as const);
|
13
|
+
|
14
|
+
export const privateRoutes = Object.freeze({
|
15
|
+
dashboard: {
|
16
|
+
path: "/dashboard",
|
17
|
+
element: DashboardPage,
|
18
|
+
title: createPageTitleTemplate("Dashboard"),
|
19
|
+
label: "Dashboard",
|
20
|
+
},
|
21
|
+
} as const);
|
22
|
+
|
23
|
+
export const routeGroups = [publicRoutes, privateRoutes] as const;
|
24
|
+
|
25
|
+
function createPageTitleTemplate(title: string) {
|
26
|
+
return `${title} | ${publicEnv.APP_NAME}`;
|
27
|
+
}
|
@@ -1,24 +0,0 @@
|
|
1
|
-
import { RouteObject } from "react-router";
|
2
|
-
import { OverrideProperties } from "type-fest";
|
3
|
-
|
4
|
-
export type CustomRouteDefinition = {
|
5
|
-
path: string;
|
6
|
-
label: string;
|
7
|
-
};
|
8
|
-
|
9
|
-
export type ReactRouterRouteDefinition<Routes extends CustomRouteDefinition[]> =
|
10
|
-
OverrideProperties<
|
11
|
-
RouteObject,
|
12
|
-
{
|
13
|
-
path: Routes[number]["path"] | "*";
|
14
|
-
handle: ReactRouterRouteHandleDefinition;
|
15
|
-
}
|
16
|
-
>;
|
17
|
-
|
18
|
-
export type ReactRouterRouteHandleDefinition = {
|
19
|
-
metadata: {
|
20
|
-
title: string;
|
21
|
-
description?: string;
|
22
|
-
};
|
23
|
-
[K: string]: unknown;
|
24
|
-
};
|
@@ -1,49 +0,0 @@
|
|
1
|
-
import { createBrowserRouter, RouteObject } from "react-router";
|
2
|
-
import { AppLayout } from "./pages/_layouts/app";
|
3
|
-
import { AuthLayout } from "./pages/_layouts/auth";
|
4
|
-
import { Dashboard } from "./pages/app/dashboard/dashboard";
|
5
|
-
import { SignIn } from "./pages/auth/sign-in";
|
6
|
-
import { publicEnv } from "./public-env";
|
7
|
-
|
8
|
-
export const publicRoutes = Object.freeze({
|
9
|
-
signIn: {
|
10
|
-
path: "/",
|
11
|
-
element: <SignIn />,
|
12
|
-
title: createTitleTemplate("Sign In"),
|
13
|
-
},
|
14
|
-
} as const);
|
15
|
-
|
16
|
-
export const privateRoutes = Object.freeze({
|
17
|
-
dashboard: {
|
18
|
-
path: "/dashboard",
|
19
|
-
element: <Dashboard />,
|
20
|
-
title: createTitleTemplate("Dashboard"),
|
21
|
-
},
|
22
|
-
} as const);
|
23
|
-
|
24
|
-
export const router = createBrowserRouter([
|
25
|
-
{
|
26
|
-
element: <AuthLayout />,
|
27
|
-
children: [
|
28
|
-
...Object.values(publicRoutes).map<RouteObject>(publicRoute => ({
|
29
|
-
path: publicRoute.path,
|
30
|
-
element: publicRoute.element,
|
31
|
-
index: true,
|
32
|
-
})),
|
33
|
-
],
|
34
|
-
},
|
35
|
-
{
|
36
|
-
element: <AppLayout />,
|
37
|
-
children: [
|
38
|
-
...Object.values(privateRoutes).map<RouteObject>(publicRoute => ({
|
39
|
-
path: publicRoute.path,
|
40
|
-
element: publicRoute.element,
|
41
|
-
index: true,
|
42
|
-
})),
|
43
|
-
],
|
44
|
-
},
|
45
|
-
]);
|
46
|
-
|
47
|
-
function createTitleTemplate(title: string) {
|
48
|
-
return `${title} | ${publicEnv.APP_NAME}`;
|
49
|
-
}
|