exnet-routing 1.2.9 → 1.2.11
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/dist/@test/routes/ops.test.js +147 -0
- package/dist/core/api/_helpers.d.ts +123 -0
- package/dist/core/api/_helpers.js +151 -0
- package/dist/core/api/_utils.d.ts +54 -0
- package/dist/core/api/_utils.js +203 -0
- package/dist/routes/ops.d.ts +1139 -0
- package/dist/routes/ops.js +28 -0
- package/package.json +1 -1
|
@@ -537,4 +537,151 @@ describe("Ops Routes", () => {
|
|
|
537
537
|
expect(response.data.action).toBe("create");
|
|
538
538
|
});
|
|
539
539
|
});
|
|
540
|
+
describe("manifest", () => {
|
|
541
|
+
it("should get manifest list", async () => {
|
|
542
|
+
const mockResponse = {
|
|
543
|
+
data: {
|
|
544
|
+
data: [
|
|
545
|
+
{
|
|
546
|
+
id: 1,
|
|
547
|
+
description: "Manifest Test",
|
|
548
|
+
mawb: "MAWB123",
|
|
549
|
+
dateManifest: new Date("2024-01-01"),
|
|
550
|
+
isParis: true,
|
|
551
|
+
isMedical: false,
|
|
552
|
+
isService: false,
|
|
553
|
+
isActif: true,
|
|
554
|
+
destination: "Paris",
|
|
555
|
+
origine: "London",
|
|
556
|
+
compagnie: "Air France",
|
|
557
|
+
numVol: "AF123",
|
|
558
|
+
numLta: "LTA123",
|
|
559
|
+
numCamion: "CAM123",
|
|
560
|
+
numContainer: "CONT123",
|
|
561
|
+
numPlomb: "PLB123",
|
|
562
|
+
numDeclaration: "DEC123",
|
|
563
|
+
numDossier: "DOS123",
|
|
564
|
+
},
|
|
565
|
+
],
|
|
566
|
+
meta: {
|
|
567
|
+
currentPage: 1,
|
|
568
|
+
totalPages: 1,
|
|
569
|
+
totalCount: 1,
|
|
570
|
+
},
|
|
571
|
+
},
|
|
572
|
+
message: "Manifest list retrieved successfully",
|
|
573
|
+
};
|
|
574
|
+
mockedAxios.mockResolvedValueOnce({ data: mockResponse });
|
|
575
|
+
const response = await api.routes().ops.manifest.liste({
|
|
576
|
+
searchParams: {},
|
|
577
|
+
});
|
|
578
|
+
expect(response.data.data).toHaveLength(1);
|
|
579
|
+
expect(response.data.data[0].description).toBe("Manifest Test");
|
|
580
|
+
});
|
|
581
|
+
it("should get manifest detail", async () => {
|
|
582
|
+
const mockResponse = {
|
|
583
|
+
data: {
|
|
584
|
+
id: 1,
|
|
585
|
+
description: "Manifest Test",
|
|
586
|
+
mawb: "MAWB123",
|
|
587
|
+
dateManifest: new Date("2024-01-01"),
|
|
588
|
+
isParis: true,
|
|
589
|
+
isMedical: false,
|
|
590
|
+
isService: false,
|
|
591
|
+
isActif: true,
|
|
592
|
+
destination: "Paris",
|
|
593
|
+
origine: "London",
|
|
594
|
+
compagnie: "Air France",
|
|
595
|
+
numVol: "AF123",
|
|
596
|
+
numLta: "LTA123",
|
|
597
|
+
numCamion: "CAM123",
|
|
598
|
+
numContainer: "CONT123",
|
|
599
|
+
numPlomb: "PLB123",
|
|
600
|
+
numDeclaration: "DEC123",
|
|
601
|
+
numDossier: "DOS123",
|
|
602
|
+
},
|
|
603
|
+
message: "Manifest detail retrieved successfully",
|
|
604
|
+
};
|
|
605
|
+
mockedAxios.mockResolvedValueOnce({ data: mockResponse });
|
|
606
|
+
const response = await api.routes().ops.manifest.detail({
|
|
607
|
+
queryParams: { id: "1" },
|
|
608
|
+
});
|
|
609
|
+
expect(response.data.description).toBe("Manifest Test");
|
|
610
|
+
expect(response.data.mawb).toBe("MAWB123");
|
|
611
|
+
});
|
|
612
|
+
it("should create manifest", async () => {
|
|
613
|
+
const mockResponse = {
|
|
614
|
+
data: {
|
|
615
|
+
id: 1,
|
|
616
|
+
description: "New Manifest",
|
|
617
|
+
mawb: "MAWB456",
|
|
618
|
+
dateManifest: new Date("2024-01-15"),
|
|
619
|
+
isParis: true,
|
|
620
|
+
isMedical: false,
|
|
621
|
+
isService: false,
|
|
622
|
+
isActif: true,
|
|
623
|
+
destination: "Paris",
|
|
624
|
+
origine: "London",
|
|
625
|
+
compagnie: "Air France",
|
|
626
|
+
numVol: "AF456",
|
|
627
|
+
numLta: "LTA456",
|
|
628
|
+
numCamion: "CAM456",
|
|
629
|
+
numContainer: "CONT456",
|
|
630
|
+
numPlomb: "PLB456",
|
|
631
|
+
numDeclaration: "DEC456",
|
|
632
|
+
numDossier: "DOS456",
|
|
633
|
+
},
|
|
634
|
+
message: "Manifest created successfully",
|
|
635
|
+
};
|
|
636
|
+
mockedAxios.mockResolvedValueOnce({ data: mockResponse });
|
|
637
|
+
const response = await api.routes().ops.manifest.create({
|
|
638
|
+
body: {
|
|
639
|
+
description: "New Manifest",
|
|
640
|
+
mawb: "MAWB456",
|
|
641
|
+
dateManifest: new Date("2024-01-15"),
|
|
642
|
+
isParis: true,
|
|
643
|
+
isMedical: false,
|
|
644
|
+
isService: false,
|
|
645
|
+
isActif: true,
|
|
646
|
+
},
|
|
647
|
+
});
|
|
648
|
+
expect(response.data.description).toBe("New Manifest");
|
|
649
|
+
expect(response.data.mawb).toBe("MAWB456");
|
|
650
|
+
});
|
|
651
|
+
it("should update manifest", async () => {
|
|
652
|
+
const mockResponse = {
|
|
653
|
+
data: {
|
|
654
|
+
id: 1,
|
|
655
|
+
description: "Updated Manifest",
|
|
656
|
+
mawb: "MAWB789",
|
|
657
|
+
dateManifest: new Date("2024-01-20"),
|
|
658
|
+
isParis: false,
|
|
659
|
+
isMedical: true,
|
|
660
|
+
isService: false,
|
|
661
|
+
isActif: true,
|
|
662
|
+
destination: "Lyon",
|
|
663
|
+
origine: "Paris",
|
|
664
|
+
compagnie: "Air France",
|
|
665
|
+
numVol: "AF789",
|
|
666
|
+
numLta: "LTA789",
|
|
667
|
+
numCamion: "CAM789",
|
|
668
|
+
numContainer: "CONT789",
|
|
669
|
+
numPlomb: "PLB789",
|
|
670
|
+
numDeclaration: "DEC789",
|
|
671
|
+
numDossier: "DOS789",
|
|
672
|
+
},
|
|
673
|
+
message: "Manifest updated successfully",
|
|
674
|
+
};
|
|
675
|
+
mockedAxios.mockResolvedValueOnce({ data: mockResponse });
|
|
676
|
+
const response = await api.routes().ops.manifest.update({
|
|
677
|
+
queryParams: { id: "1" },
|
|
678
|
+
body: {
|
|
679
|
+
description: "Updated Manifest",
|
|
680
|
+
mawb: "MAWB789",
|
|
681
|
+
},
|
|
682
|
+
});
|
|
683
|
+
expect(response.data.description).toBe("Updated Manifest");
|
|
684
|
+
expect(response.data.mawb).toBe("MAWB789");
|
|
685
|
+
});
|
|
686
|
+
});
|
|
540
687
|
});
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { IRoute } from "./_type";
|
|
3
|
+
/**
|
|
4
|
+
* Helper functions to simplify route definitions
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Common user interface types used across routes
|
|
8
|
+
*/
|
|
9
|
+
export declare const UserInterfaceEnum: z.ZodEnum<["paris", "medical", "service"]>;
|
|
10
|
+
export type UserInterface = z.infer<typeof UserInterfaceEnum>;
|
|
11
|
+
/**
|
|
12
|
+
* Common URL parameter schemas
|
|
13
|
+
*/
|
|
14
|
+
export declare const CommonParams: {
|
|
15
|
+
/** User interface parameter */
|
|
16
|
+
readonly userInterface: z.ZodObject<{
|
|
17
|
+
userInterface: z.ZodEnum<["paris", "medical", "service"]>;
|
|
18
|
+
}, "strip", z.ZodTypeAny, {
|
|
19
|
+
userInterface: "paris" | "medical" | "service";
|
|
20
|
+
}, {
|
|
21
|
+
userInterface: "paris" | "medical" | "service";
|
|
22
|
+
}>;
|
|
23
|
+
/** ID parameter */
|
|
24
|
+
readonly id: z.ZodObject<{
|
|
25
|
+
id: z.ZodString;
|
|
26
|
+
}, "strip", z.ZodTypeAny, {
|
|
27
|
+
id: string;
|
|
28
|
+
}, {
|
|
29
|
+
id: string;
|
|
30
|
+
}>;
|
|
31
|
+
/** UUID parameter */
|
|
32
|
+
readonly uuid: z.ZodObject<{
|
|
33
|
+
uuid: z.ZodString;
|
|
34
|
+
}, "strip", z.ZodTypeAny, {
|
|
35
|
+
uuid: string;
|
|
36
|
+
}, {
|
|
37
|
+
uuid: string;
|
|
38
|
+
}>;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Create a GET route definition
|
|
42
|
+
*/
|
|
43
|
+
export declare const createGetRoute: <TResponse extends z.ZodObject<any> | z.ZodArray<any> | z.ZodNull, TSearchParams extends z.ZodObject<any> | undefined = undefined, TParams extends z.ZodObject<any> | undefined = undefined>(config: {
|
|
44
|
+
url: string;
|
|
45
|
+
response: TResponse;
|
|
46
|
+
searchParams?: TSearchParams;
|
|
47
|
+
params?: TParams;
|
|
48
|
+
}) => IRoute;
|
|
49
|
+
/**
|
|
50
|
+
* Create a POST route definition
|
|
51
|
+
*/
|
|
52
|
+
export declare const createPostRoute: <TResponse extends z.ZodObject<any> | z.ZodArray<any> | z.ZodNull, TBody extends z.ZodObject<any> | undefined = undefined, TSearchParams extends z.ZodObject<any> | undefined = undefined, TParams extends z.ZodObject<any> | undefined = undefined>(config: {
|
|
53
|
+
url: string;
|
|
54
|
+
response: TResponse;
|
|
55
|
+
body?: TBody;
|
|
56
|
+
searchParams?: TSearchParams;
|
|
57
|
+
params?: TParams;
|
|
58
|
+
}) => IRoute;
|
|
59
|
+
/**
|
|
60
|
+
* Create a PUT route definition
|
|
61
|
+
*/
|
|
62
|
+
export declare const createPutRoute: <TResponse extends z.ZodObject<any> | z.ZodArray<any> | z.ZodNull, TBody extends z.ZodObject<any> | undefined = undefined, TSearchParams extends z.ZodObject<any> | undefined = undefined, TParams extends z.ZodObject<any> | undefined = undefined>(config: {
|
|
63
|
+
url: string;
|
|
64
|
+
response: TResponse;
|
|
65
|
+
body?: TBody;
|
|
66
|
+
searchParams?: TSearchParams;
|
|
67
|
+
params?: TParams;
|
|
68
|
+
}) => IRoute;
|
|
69
|
+
/**
|
|
70
|
+
* Create a DELETE route definition
|
|
71
|
+
*/
|
|
72
|
+
export declare const createDeleteRoute: <TResponse extends z.ZodObject<any> | z.ZodArray<any> | z.ZodNull, TBody extends z.ZodObject<any> | undefined = undefined, TSearchParams extends z.ZodObject<any> | undefined = undefined, TParams extends z.ZodObject<any> | undefined = undefined>(config: {
|
|
73
|
+
url: string;
|
|
74
|
+
response: TResponse;
|
|
75
|
+
body?: TBody;
|
|
76
|
+
searchParams?: TSearchParams;
|
|
77
|
+
params?: TParams;
|
|
78
|
+
}) => IRoute;
|
|
79
|
+
/**
|
|
80
|
+
* Create a PATCH route definition
|
|
81
|
+
*/
|
|
82
|
+
export declare const createPatchRoute: <TResponse extends z.ZodObject<any> | z.ZodArray<any> | z.ZodNull, TBody extends z.ZodObject<any> | undefined = undefined, TSearchParams extends z.ZodObject<any> | undefined = undefined, TParams extends z.ZodObject<any> | undefined = undefined>(config: {
|
|
83
|
+
url: string;
|
|
84
|
+
response: TResponse;
|
|
85
|
+
body?: TBody;
|
|
86
|
+
searchParams?: TSearchParams;
|
|
87
|
+
params?: TParams;
|
|
88
|
+
}) => IRoute;
|
|
89
|
+
/**
|
|
90
|
+
* Create a standard CRUD route group for a resource
|
|
91
|
+
* @param baseUrl - The base URL for the resource
|
|
92
|
+
* @param schema - The Zod schema for the resource
|
|
93
|
+
* @param createSchema - The Zod schema for creating the resource
|
|
94
|
+
* @param updateSchema - The Zod schema for updating the resource
|
|
95
|
+
* @param paginationSchema - The Zod schema for paginated list response
|
|
96
|
+
* @param searchParamsSchema - The Zod schema for search parameters
|
|
97
|
+
* @returns An object with liste, detail, create, update, and delete routes
|
|
98
|
+
*/
|
|
99
|
+
export declare const createCrudRoutes: <TSchema extends z.ZodObject<any>, TCreateSchema extends z.ZodObject<any>, TUpdateSchema extends z.ZodObject<any>, TPaginationSchema extends z.ZodObject<any> | z.ZodArray<any>, TSearchParamsSchema extends z.ZodObject<any>>(config: {
|
|
100
|
+
baseUrl: string;
|
|
101
|
+
schema: TSchema;
|
|
102
|
+
createSchema: TCreateSchema;
|
|
103
|
+
updateSchema: TUpdateSchema;
|
|
104
|
+
paginationSchema: TPaginationSchema;
|
|
105
|
+
searchParamsSchema: TSearchParamsSchema;
|
|
106
|
+
}) => {
|
|
107
|
+
liste: IRoute;
|
|
108
|
+
detail: IRoute;
|
|
109
|
+
create: IRoute;
|
|
110
|
+
update: IRoute;
|
|
111
|
+
delete: IRoute;
|
|
112
|
+
};
|
|
113
|
+
/**
|
|
114
|
+
* Create routes with user interface parameter
|
|
115
|
+
* Useful for routes that require paris/medical/service interface selection
|
|
116
|
+
*/
|
|
117
|
+
export declare const createUserInterfaceRoute: <TResponse extends z.ZodObject<any> | z.ZodArray<any> | z.ZodNull, TMethod extends "GET" | "POST" | "PUT" | "DELETE" | "PATCH" = "GET">(config: {
|
|
118
|
+
method?: TMethod;
|
|
119
|
+
url: string;
|
|
120
|
+
response: TResponse;
|
|
121
|
+
body?: z.ZodObject<any>;
|
|
122
|
+
searchParams?: z.ZodObject<any>;
|
|
123
|
+
}) => IRoute;
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createUserInterfaceRoute = exports.createCrudRoutes = exports.createPatchRoute = exports.createDeleteRoute = exports.createPutRoute = exports.createPostRoute = exports.createGetRoute = exports.CommonParams = exports.UserInterfaceEnum = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const _type_1 = require("./_type");
|
|
6
|
+
/**
|
|
7
|
+
* Helper functions to simplify route definitions
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Common user interface types used across routes
|
|
11
|
+
*/
|
|
12
|
+
exports.UserInterfaceEnum = zod_1.z.enum(["paris", "medical", "service"]);
|
|
13
|
+
/**
|
|
14
|
+
* Common URL parameter schemas
|
|
15
|
+
*/
|
|
16
|
+
exports.CommonParams = {
|
|
17
|
+
/** User interface parameter */
|
|
18
|
+
userInterface: zod_1.z.object({
|
|
19
|
+
userInterface: exports.UserInterfaceEnum,
|
|
20
|
+
}),
|
|
21
|
+
/** ID parameter */
|
|
22
|
+
id: zod_1.z.object({
|
|
23
|
+
id: zod_1.z.string(),
|
|
24
|
+
}),
|
|
25
|
+
/** UUID parameter */
|
|
26
|
+
uuid: zod_1.z.object({
|
|
27
|
+
uuid: zod_1.z.string(),
|
|
28
|
+
}),
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Create a GET route definition
|
|
32
|
+
*/
|
|
33
|
+
const createGetRoute = (config) => ({
|
|
34
|
+
method: "GET",
|
|
35
|
+
url: config.url,
|
|
36
|
+
response: (0, _type_1.response)(config.response),
|
|
37
|
+
...(config.searchParams && { searchParams: config.searchParams }),
|
|
38
|
+
...(config.params && { params: config.params }),
|
|
39
|
+
});
|
|
40
|
+
exports.createGetRoute = createGetRoute;
|
|
41
|
+
/**
|
|
42
|
+
* Create a POST route definition
|
|
43
|
+
*/
|
|
44
|
+
const createPostRoute = (config) => ({
|
|
45
|
+
method: "POST",
|
|
46
|
+
url: config.url,
|
|
47
|
+
response: (0, _type_1.response)(config.response),
|
|
48
|
+
...(config.body && { body: config.body }),
|
|
49
|
+
...(config.searchParams && { searchParams: config.searchParams }),
|
|
50
|
+
...(config.params && { params: config.params }),
|
|
51
|
+
});
|
|
52
|
+
exports.createPostRoute = createPostRoute;
|
|
53
|
+
/**
|
|
54
|
+
* Create a PUT route definition
|
|
55
|
+
*/
|
|
56
|
+
const createPutRoute = (config) => ({
|
|
57
|
+
method: "PUT",
|
|
58
|
+
url: config.url,
|
|
59
|
+
response: (0, _type_1.response)(config.response),
|
|
60
|
+
...(config.body && { body: config.body }),
|
|
61
|
+
...(config.searchParams && { searchParams: config.searchParams }),
|
|
62
|
+
...(config.params && { params: config.params }),
|
|
63
|
+
});
|
|
64
|
+
exports.createPutRoute = createPutRoute;
|
|
65
|
+
/**
|
|
66
|
+
* Create a DELETE route definition
|
|
67
|
+
*/
|
|
68
|
+
const createDeleteRoute = (config) => ({
|
|
69
|
+
method: "DELETE",
|
|
70
|
+
url: config.url,
|
|
71
|
+
response: (0, _type_1.response)(config.response),
|
|
72
|
+
...(config.body && { body: config.body }),
|
|
73
|
+
...(config.searchParams && { searchParams: config.searchParams }),
|
|
74
|
+
...(config.params && { params: config.params }),
|
|
75
|
+
});
|
|
76
|
+
exports.createDeleteRoute = createDeleteRoute;
|
|
77
|
+
/**
|
|
78
|
+
* Create a PATCH route definition
|
|
79
|
+
*/
|
|
80
|
+
const createPatchRoute = (config) => ({
|
|
81
|
+
method: "PATCH",
|
|
82
|
+
url: config.url,
|
|
83
|
+
response: (0, _type_1.response)(config.response),
|
|
84
|
+
...(config.body && { body: config.body }),
|
|
85
|
+
...(config.searchParams && { searchParams: config.searchParams }),
|
|
86
|
+
...(config.params && { params: config.params }),
|
|
87
|
+
});
|
|
88
|
+
exports.createPatchRoute = createPatchRoute;
|
|
89
|
+
/**
|
|
90
|
+
* Create a standard CRUD route group for a resource
|
|
91
|
+
* @param baseUrl - The base URL for the resource
|
|
92
|
+
* @param schema - The Zod schema for the resource
|
|
93
|
+
* @param createSchema - The Zod schema for creating the resource
|
|
94
|
+
* @param updateSchema - The Zod schema for updating the resource
|
|
95
|
+
* @param paginationSchema - The Zod schema for paginated list response
|
|
96
|
+
* @param searchParamsSchema - The Zod schema for search parameters
|
|
97
|
+
* @returns An object with liste, detail, create, update, and delete routes
|
|
98
|
+
*/
|
|
99
|
+
const createCrudRoutes = (config) => ({
|
|
100
|
+
liste: (0, exports.createGetRoute)({
|
|
101
|
+
url: `${config.baseUrl}/liste`,
|
|
102
|
+
response: config.paginationSchema,
|
|
103
|
+
searchParams: config.searchParamsSchema,
|
|
104
|
+
}),
|
|
105
|
+
detail: (0, exports.createGetRoute)({
|
|
106
|
+
url: `${config.baseUrl}/detail/:id`,
|
|
107
|
+
response: config.schema,
|
|
108
|
+
params: exports.CommonParams.id,
|
|
109
|
+
}),
|
|
110
|
+
create: (0, exports.createPostRoute)({
|
|
111
|
+
url: `${config.baseUrl}/create`,
|
|
112
|
+
response: config.schema,
|
|
113
|
+
body: config.createSchema,
|
|
114
|
+
}),
|
|
115
|
+
update: (0, exports.createPutRoute)({
|
|
116
|
+
url: `${config.baseUrl}/update/:id`,
|
|
117
|
+
response: config.schema,
|
|
118
|
+
body: config.updateSchema,
|
|
119
|
+
params: exports.CommonParams.id,
|
|
120
|
+
}),
|
|
121
|
+
delete: (0, exports.createDeleteRoute)({
|
|
122
|
+
url: `${config.baseUrl}/delete/:id`,
|
|
123
|
+
response: zod_1.z.null(),
|
|
124
|
+
params: exports.CommonParams.id,
|
|
125
|
+
}),
|
|
126
|
+
});
|
|
127
|
+
exports.createCrudRoutes = createCrudRoutes;
|
|
128
|
+
/**
|
|
129
|
+
* Create routes with user interface parameter
|
|
130
|
+
* Useful for routes that require paris/medical/service interface selection
|
|
131
|
+
*/
|
|
132
|
+
const createUserInterfaceRoute = (config) => {
|
|
133
|
+
const baseConfig = {
|
|
134
|
+
url: config.url,
|
|
135
|
+
response: (0, _type_1.response)(config.response),
|
|
136
|
+
params: exports.CommonParams.userInterface,
|
|
137
|
+
...(config.searchParams && { searchParams: config.searchParams }),
|
|
138
|
+
};
|
|
139
|
+
if (config.method === "POST" || config.method === "PUT" || config.method === "PATCH" || config.method === "DELETE") {
|
|
140
|
+
return {
|
|
141
|
+
...baseConfig,
|
|
142
|
+
method: config.method,
|
|
143
|
+
...(config.body && { body: config.body }),
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
return {
|
|
147
|
+
...baseConfig,
|
|
148
|
+
method: "GET",
|
|
149
|
+
};
|
|
150
|
+
};
|
|
151
|
+
exports.createUserInterfaceRoute = createUserInterfaceRoute;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { AxiosHeaders } from "axios";
|
|
2
|
+
import { IRoute, IRouteFunction, IRouteGroup, IRouterApi } from "./_type";
|
|
3
|
+
import { NestedRoute } from "./_type";
|
|
4
|
+
/**
|
|
5
|
+
* Build a complete API URL from host, base path and segment
|
|
6
|
+
* @param segment - The API endpoint segment
|
|
7
|
+
* @param baseUrl - The base path (e.g., "/api/v1")
|
|
8
|
+
* @param host - The host URL (e.g., "http://localhost:3000")
|
|
9
|
+
* @returns The complete URL
|
|
10
|
+
*/
|
|
11
|
+
export declare const apiUrlBuilder: (segment?: string, baseUrl?: string, host?: string) => string;
|
|
12
|
+
/**
|
|
13
|
+
* API fetch utility with configurable host, base URL and headers
|
|
14
|
+
*/
|
|
15
|
+
export declare const createApiFetch: (host: string, baseUrl: string, headers?: AxiosHeaders) => {
|
|
16
|
+
/**
|
|
17
|
+
* Perform an HTTP request to the API
|
|
18
|
+
* @param urlInput - The endpoint path
|
|
19
|
+
* @param method - HTTP method
|
|
20
|
+
* @param body - Request body
|
|
21
|
+
* @param searchParams - Search/query parameters
|
|
22
|
+
* @param queryParams - URL path parameters to replace
|
|
23
|
+
* @returns Response data
|
|
24
|
+
*/
|
|
25
|
+
fetch: (urlInput: string, method?: RequestInit["method"] | undefined, body?: any, searchParams?: any, queryParams?: Record<string, string>) => Promise<any>;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Type guard to check if a value is a route definition
|
|
29
|
+
*/
|
|
30
|
+
export declare const isRoute: (value: NestedRoute | IRoute) => value is IRoute;
|
|
31
|
+
/**
|
|
32
|
+
* Type guard to check if a value is a nested route
|
|
33
|
+
*/
|
|
34
|
+
export declare const isSubRoute: (value: NestedRoute | IRoute) => value is NestedRoute;
|
|
35
|
+
/**
|
|
36
|
+
* Recursively parse API route definitions and create executable functions
|
|
37
|
+
* @param key - The current route key
|
|
38
|
+
* @param subRoute - The route or nested routes definition
|
|
39
|
+
* @param result - The result object to populate
|
|
40
|
+
* @param hostApi - The API host URL
|
|
41
|
+
* @param basePath - The API base path
|
|
42
|
+
* @param headers - Optional headers to include in requests
|
|
43
|
+
* @returns The populated result object
|
|
44
|
+
*/
|
|
45
|
+
export declare const parseApiRoute: <T extends NestedRoute | IRoute, K extends IRouteGroup>(key: string | undefined, subRoute: T, result: K, hostApi: string, basePath: string, headers?: AxiosHeaders) => K | IRouteFunction;
|
|
46
|
+
/**
|
|
47
|
+
* Parse the entire API route structure and create an executable API client
|
|
48
|
+
* @param api - The API route definitions
|
|
49
|
+
* @param hostApi - The API host URL
|
|
50
|
+
* @param basePath - The API base path
|
|
51
|
+
* @param headers - Optional headers to include in requests
|
|
52
|
+
* @returns The parsed API router with executable methods
|
|
53
|
+
*/
|
|
54
|
+
export declare const parseApiRoutes: <T extends NestedRoute>(api: T, hostApi: string, basePath: string, headers?: AxiosHeaders) => IRouterApi;
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.parseApiRoutes = exports.parseApiRoute = exports.isSubRoute = exports.isRoute = exports.createApiFetch = exports.apiUrlBuilder = void 0;
|
|
7
|
+
const path_1 = require("path");
|
|
8
|
+
const axios_1 = __importDefault(require("axios"));
|
|
9
|
+
/**
|
|
10
|
+
* Build a complete API URL from host, base path and segment
|
|
11
|
+
* @param segment - The API endpoint segment
|
|
12
|
+
* @param baseUrl - The base path (e.g., "/api/v1")
|
|
13
|
+
* @param host - The host URL (e.g., "http://localhost:3000")
|
|
14
|
+
* @returns The complete URL
|
|
15
|
+
*/
|
|
16
|
+
const apiUrlBuilder = (segment = "", baseUrl = "", host = "") => {
|
|
17
|
+
const path = (0, path_1.join)(baseUrl, segment);
|
|
18
|
+
return host + path;
|
|
19
|
+
};
|
|
20
|
+
exports.apiUrlBuilder = apiUrlBuilder;
|
|
21
|
+
/**
|
|
22
|
+
* Default headers applied to all requests
|
|
23
|
+
*/
|
|
24
|
+
const DEFAULT_HEADERS = {
|
|
25
|
+
"Content-Type": "application/json",
|
|
26
|
+
Accept: "application/json",
|
|
27
|
+
"Access-Control-Allow-Origin": "*",
|
|
28
|
+
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
|
|
29
|
+
"Access-Control-Allow-Headers": "Content-Type, Authorization",
|
|
30
|
+
"Access-Control-Allow-Credentials": "true",
|
|
31
|
+
"Access-Control-Allow-Private-Network": "true",
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Build query parameters string from object
|
|
35
|
+
* @param queryParams - Object containing query parameters to replace in URL
|
|
36
|
+
* @param url - The URL with placeholders (e.g., "/user/:id")
|
|
37
|
+
* @returns URL with replaced parameters
|
|
38
|
+
*/
|
|
39
|
+
const replaceQueryParams = (url, queryParams) => {
|
|
40
|
+
if (!queryParams)
|
|
41
|
+
return url;
|
|
42
|
+
let result = url;
|
|
43
|
+
Object.entries(queryParams).forEach(([key, value]) => {
|
|
44
|
+
if (value !== undefined && value !== null) {
|
|
45
|
+
result = result.replace(`:${key}`, encodeURIComponent(String(value)));
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
return result;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Build search parameters string from object
|
|
52
|
+
* @param searchParams - Object or string of search parameters
|
|
53
|
+
* @returns Query string to append to URL
|
|
54
|
+
*/
|
|
55
|
+
const buildSearchParams = (searchParams) => {
|
|
56
|
+
if (!searchParams)
|
|
57
|
+
return "";
|
|
58
|
+
if (typeof searchParams === "string")
|
|
59
|
+
return searchParams;
|
|
60
|
+
const params = Object.entries(searchParams)
|
|
61
|
+
.filter(([_, value]) => value !== undefined && value !== null)
|
|
62
|
+
.map(([key, value]) => {
|
|
63
|
+
const encodedKey = encodeURIComponent(key);
|
|
64
|
+
const encodedValue = Array.isArray(value) || typeof value === "object"
|
|
65
|
+
? encodeURIComponent(JSON.stringify(value))
|
|
66
|
+
: encodeURIComponent(String(value !== null && value !== void 0 ? value : ""));
|
|
67
|
+
return `${encodedKey}=${encodedValue}`;
|
|
68
|
+
})
|
|
69
|
+
.join("&");
|
|
70
|
+
return params;
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* API fetch utility with configurable host, base URL and headers
|
|
74
|
+
*/
|
|
75
|
+
const createApiFetch = (host, baseUrl, headers) => {
|
|
76
|
+
return {
|
|
77
|
+
/**
|
|
78
|
+
* Perform an HTTP request to the API
|
|
79
|
+
* @param urlInput - The endpoint path
|
|
80
|
+
* @param method - HTTP method
|
|
81
|
+
* @param body - Request body
|
|
82
|
+
* @param searchParams - Search/query parameters
|
|
83
|
+
* @param queryParams - URL path parameters to replace
|
|
84
|
+
* @returns Response data
|
|
85
|
+
*/
|
|
86
|
+
fetch: async (urlInput, method, body, searchParams, queryParams) => {
|
|
87
|
+
var _a, _b;
|
|
88
|
+
try {
|
|
89
|
+
let url = (0, exports.apiUrlBuilder)(urlInput, baseUrl, host);
|
|
90
|
+
// Replace path parameters (e.g., :id)
|
|
91
|
+
url = replaceQueryParams(url, queryParams);
|
|
92
|
+
// Add search parameters
|
|
93
|
+
const searchParamsString = buildSearchParams(searchParams);
|
|
94
|
+
if (searchParamsString) {
|
|
95
|
+
url += (url.includes("?") ? "&" : "?") + searchParamsString;
|
|
96
|
+
}
|
|
97
|
+
const res = await (0, axios_1.default)({
|
|
98
|
+
headers: {
|
|
99
|
+
...DEFAULT_HEADERS,
|
|
100
|
+
...headers,
|
|
101
|
+
},
|
|
102
|
+
method,
|
|
103
|
+
url,
|
|
104
|
+
data: body,
|
|
105
|
+
});
|
|
106
|
+
return res.data;
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
// Enhanced error handling
|
|
110
|
+
if (axios_1.default.isAxiosError(error)) {
|
|
111
|
+
const axiosError = error;
|
|
112
|
+
const errorMessage = ((_a = axiosError.response) === null || _a === void 0 ? void 0 : _a.data) ? JSON.stringify(axiosError.response.data) : axiosError.message;
|
|
113
|
+
throw new Error(`API request failed [${((_b = axiosError.response) === null || _b === void 0 ? void 0 : _b.status) || "UNKNOWN"}]: ${errorMessage}`);
|
|
114
|
+
}
|
|
115
|
+
throw new Error(`Request failed: ${error}`);
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
};
|
|
120
|
+
exports.createApiFetch = createApiFetch;
|
|
121
|
+
/**
|
|
122
|
+
* Type guard to check if a value is a route definition
|
|
123
|
+
*/
|
|
124
|
+
const isRoute = (value) => {
|
|
125
|
+
return "method" in value;
|
|
126
|
+
};
|
|
127
|
+
exports.isRoute = isRoute;
|
|
128
|
+
/**
|
|
129
|
+
* Type guard to check if a value is a nested route
|
|
130
|
+
*/
|
|
131
|
+
const isSubRoute = (value) => {
|
|
132
|
+
return !(0, exports.isRoute)(value);
|
|
133
|
+
};
|
|
134
|
+
exports.isSubRoute = isSubRoute;
|
|
135
|
+
/**
|
|
136
|
+
* Create a function that executes the API call for a given route
|
|
137
|
+
* @param route - The route definition
|
|
138
|
+
* @param apiFetch - The fetch utility
|
|
139
|
+
* @returns A function that can be called to execute the API request
|
|
140
|
+
*/
|
|
141
|
+
const createRouteFunction = (route, apiFetch) => {
|
|
142
|
+
const createFetchFunction = (paramTypes) => {
|
|
143
|
+
return async (...args) => {
|
|
144
|
+
const params = paramTypes.reduce((acc, type) => {
|
|
145
|
+
var _a;
|
|
146
|
+
acc[type] = ((_a = args[0]) === null || _a === void 0 ? void 0 : _a[type]) || null;
|
|
147
|
+
return acc;
|
|
148
|
+
}, {});
|
|
149
|
+
return await apiFetch.fetch(route.url, route.method, params.body, params.searchParams, params.queryParams);
|
|
150
|
+
};
|
|
151
|
+
};
|
|
152
|
+
// Determine which parameters are needed based on route definition
|
|
153
|
+
if (route.body) {
|
|
154
|
+
if (route.searchParams) {
|
|
155
|
+
return route.params
|
|
156
|
+
? createFetchFunction(["body", "searchParams", "queryParams"])
|
|
157
|
+
: createFetchFunction(["body", "searchParams"]);
|
|
158
|
+
}
|
|
159
|
+
return route.params ? createFetchFunction(["body", "queryParams"]) : createFetchFunction(["body"]);
|
|
160
|
+
}
|
|
161
|
+
if (route.searchParams) {
|
|
162
|
+
return route.params ? createFetchFunction(["searchParams", "queryParams"]) : createFetchFunction(["searchParams"]);
|
|
163
|
+
}
|
|
164
|
+
return route.params ? createFetchFunction(["queryParams"]) : createFetchFunction([]);
|
|
165
|
+
};
|
|
166
|
+
/**
|
|
167
|
+
* Recursively parse API route definitions and create executable functions
|
|
168
|
+
* @param key - The current route key
|
|
169
|
+
* @param subRoute - The route or nested routes definition
|
|
170
|
+
* @param result - The result object to populate
|
|
171
|
+
* @param hostApi - The API host URL
|
|
172
|
+
* @param basePath - The API base path
|
|
173
|
+
* @param headers - Optional headers to include in requests
|
|
174
|
+
* @returns The populated result object
|
|
175
|
+
*/
|
|
176
|
+
const parseApiRoute = (key, subRoute, result, hostApi, basePath, headers) => {
|
|
177
|
+
var _a;
|
|
178
|
+
const apiFetch = (0, exports.createApiFetch)(hostApi, basePath, headers);
|
|
179
|
+
if ((0, exports.isRoute)(subRoute) && key) {
|
|
180
|
+
return createRouteFunction(subRoute, apiFetch);
|
|
181
|
+
}
|
|
182
|
+
else if ((0, exports.isSubRoute)(subRoute)) {
|
|
183
|
+
for (const [key, value] of Object.entries(subRoute)) {
|
|
184
|
+
;
|
|
185
|
+
result[key] = (0, exports.parseApiRoute)(key, value, ((_a = result[key]) !== null && _a !== void 0 ? _a : {}), hostApi, basePath, headers);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return result;
|
|
189
|
+
};
|
|
190
|
+
exports.parseApiRoute = parseApiRoute;
|
|
191
|
+
/**
|
|
192
|
+
* Parse the entire API route structure and create an executable API client
|
|
193
|
+
* @param api - The API route definitions
|
|
194
|
+
* @param hostApi - The API host URL
|
|
195
|
+
* @param basePath - The API base path
|
|
196
|
+
* @param headers - Optional headers to include in requests
|
|
197
|
+
* @returns The parsed API router with executable methods
|
|
198
|
+
*/
|
|
199
|
+
const parseApiRoutes = (api, hostApi, basePath, headers) => {
|
|
200
|
+
const result = {};
|
|
201
|
+
return (0, exports.parseApiRoute)(undefined, api, result, hostApi, basePath, headers);
|
|
202
|
+
};
|
|
203
|
+
exports.parseApiRoutes = parseApiRoutes;
|