tspace-spear 1.2.5-beta.3 → 1.2.5-beta.5
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/cli/app.d.ts +1 -0
- package/dist/cli/app.js +24 -0
- package/dist/cli/app.js.map +1 -0
- package/dist/cli/controller.d.ts +1 -0
- package/dist/cli/controller.js +158 -0
- package/dist/cli/controller.js.map +1 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +138 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/lib/core/client/index.d.ts +68 -10
- package/dist/lib/core/client/index.js +100 -10
- package/dist/lib/core/client/index.js.map +1 -1
- package/dist/lib/core/compiler/generator.d.ts +1 -1
- package/dist/lib/core/compiler/generator.js +167 -3
- package/dist/lib/core/compiler/generator.js.map +1 -1
- package/dist/lib/core/compiler/index.d.ts +2 -2
- package/dist/lib/core/compiler/index.js +2 -1
- package/dist/lib/core/compiler/index.js.map +1 -1
- package/dist/lib/core/compiler/pre-routes.d.ts +196 -43
- package/dist/lib/core/compiler/pre-routes.js +155 -0
- package/dist/lib/core/compiler/pre-routes.js.map +1 -1
- package/dist/lib/core/decorators/context.d.ts +50 -1
- package/dist/lib/core/decorators/context.js +86 -2
- package/dist/lib/core/decorators/context.js.map +1 -1
- package/dist/lib/core/server/index.d.ts +10 -2
- package/dist/lib/core/server/index.js +46 -28
- package/dist/lib/core/server/index.js.map +1 -1
- package/dist/lib/core/server/parser-factory.d.ts +2 -2
- package/dist/lib/core/server/parser-factory.js +139 -1
- package/dist/lib/core/server/parser-factory.js.map +1 -1
- package/dist/lib/core/types/index.d.ts +2 -1
- package/dist/tests/e2e..test.d.ts +1 -0
- package/dist/tests/e2e..test.js +16 -0
- package/dist/tests/e2e..test.js.map +1 -0
- package/package.json +24 -9
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const app = "\nimport Spear from \"tspace-spear\";\n\nexport const app = new Spear({\n logger: true,\n controllers: {\n folder: `${__dirname}/controllers`,\n name: /controller\\\\.(ts|js)$/i,\n preRouteTypes: true\n }\n})\n\napp.useGlobalPrefix(\"api\");\n\napp.useBodyParser();\n\napp.listen(8000 , ({ port , server }) => {\n console.log(`server listening on : http://localhost:${port}`)\n})\n";
|
package/dist/cli/app.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.app = void 0;
|
|
4
|
+
exports.app = `
|
|
5
|
+
import Spear from "tspace-spear";
|
|
6
|
+
|
|
7
|
+
export const app = new Spear({
|
|
8
|
+
logger: true,
|
|
9
|
+
controllers: {
|
|
10
|
+
folder: \`\${__dirname}/controllers\`,
|
|
11
|
+
name: /controller\\\\.(ts|js)$/i,
|
|
12
|
+
preRouteTypes: true
|
|
13
|
+
}
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
app.useGlobalPrefix("api");
|
|
17
|
+
|
|
18
|
+
app.useBodyParser();
|
|
19
|
+
|
|
20
|
+
app.listen(8000 , ({ port , server }) => {
|
|
21
|
+
console.log(\`server listening on : http://localhost:\${port}\`)
|
|
22
|
+
})
|
|
23
|
+
`;
|
|
24
|
+
//# sourceMappingURL=app.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app.js","sourceRoot":"","sources":["../../src/cli/app.ts"],"names":[],"mappings":";;;AAAa,QAAA,GAAG,GAAG;;;;;;;;;;;;;;;;;;;CAmBlB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const CatController = "\nimport {\n type T,\n Controller,\n Get,\n Post,\n Put,\n Delete\n} from \"tspace-spear\";\n\ntype Cat = {\n id: number;\n name: string;\n age: number;\n};\n\nlet cats: Cat[] = [\n {\n id: 1,\n name: \"cat 1\",\n age: 2\n },\n {\n id: 2,\n name: \"cat 2\",\n age: 4\n }\n];\n\n@Controller(\"/cats\")\nexport default class CatController {\n\n @Get(\"/\")\n async index() {\n return {\n cats\n };\n }\n\n @Get(\"/:id\")\n async show({\n res,\n params\n }: T.Context<{\n params: {\n id: number;\n };\n }>) {\n\n const cat = cats.find(\n d => d.id === Number(params.id)\n );\n\n if (!cat) {\n throw res.notFound(\n \"Cat not found\"\n );\n }\n\n return {\n cat\n };\n }\n\n @Post(\"/\")\n async create({\n body\n }: T.Context<{\n body: {\n name: string;\n age: number;\n };\n }>) {\n\n const cat: Cat = {\n id: cats.length + 1,\n name: body.name,\n age: body.age\n };\n\n cats.push(cat);\n\n return {\n message: \"Created\",\n cat\n };\n }\n\n @Put(\"/:id\")\n async update({\n res,\n params,\n body\n }: T.Context<{\n params: {\n id: number;\n };\n body: Partial<{\n name: string;\n age: number;\n }>;\n }>) {\n\n const index = cats.findIndex(\n d => d.id === Number(params.id)\n );\n\n if (index === -1) {\n throw res.notFound(\n \"Cat not found\"\n );\n }\n\n cats[index] = {\n ...cats[index],\n ...body\n };\n\n return {\n message: \"Updated\",\n cat: cats[index]\n };\n }\n\n @Delete(\"/:id\")\n async remove({\n res,\n params\n }: T.Context<{\n params: {\n id: number;\n };\n }>) {\n\n const index = cats.findIndex(\n d => d.id === Number(params.id)\n );\n\n if (index === -1) {\n thorw res.notFound(\n \"Cat not found\"\n );\n }\n\n cats = cats.filter(\n d => d.id !== Number(params.id)\n );\n\n return {\n message: \"Deleted\"\n };\n }\n}\n";
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CatController = void 0;
|
|
4
|
+
exports.CatController = `
|
|
5
|
+
import {
|
|
6
|
+
type T,
|
|
7
|
+
Controller,
|
|
8
|
+
Get,
|
|
9
|
+
Post,
|
|
10
|
+
Put,
|
|
11
|
+
Delete
|
|
12
|
+
} from "tspace-spear";
|
|
13
|
+
|
|
14
|
+
type Cat = {
|
|
15
|
+
id: number;
|
|
16
|
+
name: string;
|
|
17
|
+
age: number;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
let cats: Cat[] = [
|
|
21
|
+
{
|
|
22
|
+
id: 1,
|
|
23
|
+
name: "cat 1",
|
|
24
|
+
age: 2
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
id: 2,
|
|
28
|
+
name: "cat 2",
|
|
29
|
+
age: 4
|
|
30
|
+
}
|
|
31
|
+
];
|
|
32
|
+
|
|
33
|
+
@Controller("/cats")
|
|
34
|
+
export default class CatController {
|
|
35
|
+
|
|
36
|
+
@Get("/")
|
|
37
|
+
async index() {
|
|
38
|
+
return {
|
|
39
|
+
cats
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
@Get("/:id")
|
|
44
|
+
async show({
|
|
45
|
+
res,
|
|
46
|
+
params
|
|
47
|
+
}: T.Context<{
|
|
48
|
+
params: {
|
|
49
|
+
id: number;
|
|
50
|
+
};
|
|
51
|
+
}>) {
|
|
52
|
+
|
|
53
|
+
const cat = cats.find(
|
|
54
|
+
d => d.id === Number(params.id)
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
if (!cat) {
|
|
58
|
+
throw res.notFound(
|
|
59
|
+
"Cat not found"
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return {
|
|
64
|
+
cat
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
@Post("/")
|
|
69
|
+
async create({
|
|
70
|
+
body
|
|
71
|
+
}: T.Context<{
|
|
72
|
+
body: {
|
|
73
|
+
name: string;
|
|
74
|
+
age: number;
|
|
75
|
+
};
|
|
76
|
+
}>) {
|
|
77
|
+
|
|
78
|
+
const cat: Cat = {
|
|
79
|
+
id: cats.length + 1,
|
|
80
|
+
name: body.name,
|
|
81
|
+
age: body.age
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
cats.push(cat);
|
|
85
|
+
|
|
86
|
+
return {
|
|
87
|
+
message: "Created",
|
|
88
|
+
cat
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
@Put("/:id")
|
|
93
|
+
async update({
|
|
94
|
+
res,
|
|
95
|
+
params,
|
|
96
|
+
body
|
|
97
|
+
}: T.Context<{
|
|
98
|
+
params: {
|
|
99
|
+
id: number;
|
|
100
|
+
};
|
|
101
|
+
body: Partial<{
|
|
102
|
+
name: string;
|
|
103
|
+
age: number;
|
|
104
|
+
}>;
|
|
105
|
+
}>) {
|
|
106
|
+
|
|
107
|
+
const index = cats.findIndex(
|
|
108
|
+
d => d.id === Number(params.id)
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
if (index === -1) {
|
|
112
|
+
throw res.notFound(
|
|
113
|
+
"Cat not found"
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
cats[index] = {
|
|
118
|
+
...cats[index],
|
|
119
|
+
...body
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
return {
|
|
123
|
+
message: "Updated",
|
|
124
|
+
cat: cats[index]
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
@Delete("/:id")
|
|
129
|
+
async remove({
|
|
130
|
+
res,
|
|
131
|
+
params
|
|
132
|
+
}: T.Context<{
|
|
133
|
+
params: {
|
|
134
|
+
id: number;
|
|
135
|
+
};
|
|
136
|
+
}>) {
|
|
137
|
+
|
|
138
|
+
const index = cats.findIndex(
|
|
139
|
+
d => d.id === Number(params.id)
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
if (index === -1) {
|
|
143
|
+
thorw res.notFound(
|
|
144
|
+
"Cat not found"
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
cats = cats.filter(
|
|
149
|
+
d => d.id !== Number(params.id)
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
return {
|
|
153
|
+
message: "Deleted"
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
`;
|
|
158
|
+
//# sourceMappingURL=controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"controller.js","sourceRoot":"","sources":["../../src/cli/controller.ts"],"names":[],"mappings":";;;AAAa,QAAA,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyJ5B,CAAC"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const app_1 = require("./app");
|
|
10
|
+
const controller_1 = require("./controller");
|
|
11
|
+
const [, , action, type, target] = process.argv;
|
|
12
|
+
switch (`${action}:${type}`) {
|
|
13
|
+
case "create:app":
|
|
14
|
+
createApp(target);
|
|
15
|
+
break;
|
|
16
|
+
case "create:controller":
|
|
17
|
+
createController(target);
|
|
18
|
+
break;
|
|
19
|
+
default:
|
|
20
|
+
console.log(`
|
|
21
|
+
Usage:
|
|
22
|
+
|
|
23
|
+
tspace-spear create app ./src
|
|
24
|
+
tspace-spear create controller cats
|
|
25
|
+
`);
|
|
26
|
+
}
|
|
27
|
+
function createApp(targetPath) {
|
|
28
|
+
if (!targetPath) {
|
|
29
|
+
console.log("Missing target path");
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
const root = path_1.default.resolve(process.cwd(), targetPath);
|
|
33
|
+
fs_1.default.mkdirSync(root, {
|
|
34
|
+
recursive: true
|
|
35
|
+
});
|
|
36
|
+
fs_1.default.mkdirSync(path_1.default.join(root, "controllers"), {
|
|
37
|
+
recursive: true
|
|
38
|
+
});
|
|
39
|
+
fs_1.default.writeFileSync(path_1.default.join(root, "index.ts"), app_1.app);
|
|
40
|
+
fs_1.default.writeFileSync(path_1.default.join(root, "controllers", "home.controller.ts"), controller_1.CatController);
|
|
41
|
+
console.log(`App created at: ${root}`);
|
|
42
|
+
}
|
|
43
|
+
function createController(name) {
|
|
44
|
+
if (!name) {
|
|
45
|
+
console.log("Missing controller name");
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
const fileName = `${name}.controller.ts`;
|
|
49
|
+
const target = path_1.default.resolve(process.cwd(), "controllers", fileName);
|
|
50
|
+
fs_1.default.mkdirSync(path_1.default.dirname(target), {
|
|
51
|
+
recursive: true
|
|
52
|
+
});
|
|
53
|
+
const className = capitalize(name) + "Controller";
|
|
54
|
+
fs_1.default.writeFileSync(target, `
|
|
55
|
+
import {
|
|
56
|
+
type T,
|
|
57
|
+
Controller,
|
|
58
|
+
Get,
|
|
59
|
+
Post,
|
|
60
|
+
Put,
|
|
61
|
+
Delete
|
|
62
|
+
} from "tspace-spear";
|
|
63
|
+
|
|
64
|
+
@Controller("/${name}")
|
|
65
|
+
export default class ${className} {
|
|
66
|
+
|
|
67
|
+
@Get("/")
|
|
68
|
+
async index() {
|
|
69
|
+
|
|
70
|
+
return {};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
@Get("/:id")
|
|
74
|
+
async show({
|
|
75
|
+
params
|
|
76
|
+
}: T.Context<{
|
|
77
|
+
params: {
|
|
78
|
+
id: number;
|
|
79
|
+
};
|
|
80
|
+
}>) {
|
|
81
|
+
|
|
82
|
+
return {
|
|
83
|
+
id: params.id
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
@Post("/")
|
|
88
|
+
async create({
|
|
89
|
+
body
|
|
90
|
+
}: T.Context<{
|
|
91
|
+
body: {};
|
|
92
|
+
}>) {
|
|
93
|
+
|
|
94
|
+
return {
|
|
95
|
+
body
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
@Put("/:id")
|
|
100
|
+
async update({
|
|
101
|
+
params,
|
|
102
|
+
body
|
|
103
|
+
}: T.Context<{
|
|
104
|
+
params: {
|
|
105
|
+
id: number;
|
|
106
|
+
};
|
|
107
|
+
body: {};
|
|
108
|
+
}>) {
|
|
109
|
+
|
|
110
|
+
return {
|
|
111
|
+
id: params.id,
|
|
112
|
+
body
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
@Delete("/:id")
|
|
117
|
+
async remove({
|
|
118
|
+
params
|
|
119
|
+
}: T.Context<{
|
|
120
|
+
params: {
|
|
121
|
+
id: number;
|
|
122
|
+
};
|
|
123
|
+
}>) {
|
|
124
|
+
|
|
125
|
+
return {
|
|
126
|
+
id: params.id
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
}
|
|
131
|
+
`);
|
|
132
|
+
console.log(`Controller created: ${fileName}`);
|
|
133
|
+
}
|
|
134
|
+
function capitalize(value) {
|
|
135
|
+
return (value.charAt(0).toUpperCase() +
|
|
136
|
+
value.slice(1));
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";;;;;;AAEA,4CAAoB;AACpB,gDAAwB;AACxB,+BAA4B;AAC5B,6CAA6C;AAE7C,MAAM,CAAC,EAAE,AAAD,EAAG,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;AAEhD,QAAQ,GAAG,MAAM,IAAI,IAAI,EAAE,EAAE,CAAC;IAE5B,KAAK,YAAY;QACf,SAAS,CAAC,MAAM,CAAC,CAAC;QAClB,MAAM;IAER,KAAK,mBAAmB;QACtB,gBAAgB,CAAC,MAAM,CAAC,CAAC;QACzB,MAAM;IAER;QACE,OAAO,CAAC,GAAG,CAAC;;;;;CAKf,CAAC,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAC,UAAmB;IAEpC,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;QACnC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,IAAI,GAAG,cAAI,CAAC,OAAO,CACvB,OAAO,CAAC,GAAG,EAAE,EACb,UAAU,CACX,CAAC;IAEF,YAAE,CAAC,SAAS,CAAC,IAAI,EAAE;QACjB,SAAS,EAAE,IAAI;KAChB,CAAC,CAAC;IAEH,YAAE,CAAC,SAAS,CACV,cAAI,CAAC,IAAI,CAAC,IAAI,EAAE,aAAa,CAAC,EAC9B;QACE,SAAS,EAAE,IAAI;KAChB,CACF,CAAC;IAEF,YAAE,CAAC,aAAa,CACd,cAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,EAC3B,SAAG,CACJ,CAAC;IAEF,YAAE,CAAC,aAAa,CACd,cAAI,CAAC,IAAI,CACP,IAAI,EACJ,aAAa,EACb,oBAAoB,CACrB,EAAC,0BAAa,CAChB,CAAC;IAEF,OAAO,CAAC,GAAG,CACT,mBAAmB,IAAI,EAAE,CAC1B,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAa;IAErC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;QACvC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,QAAQ,GACZ,GAAG,IAAI,gBAAgB,CAAC;IAE1B,MAAM,MAAM,GAAG,cAAI,CAAC,OAAO,CACzB,OAAO,CAAC,GAAG,EAAE,EACb,aAAa,EACb,QAAQ,CACT,CAAC;IAEF,YAAE,CAAC,SAAS,CACV,cAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EACpB;QACE,SAAS,EAAE,IAAI;KAChB,CACF,CAAC;IAEF,MAAM,SAAS,GACb,UAAU,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC;IAElC,YAAE,CAAC,aAAa,CACd,MAAM,EACV;;;;;;;;;;gBAUgB,IAAI;uBACG,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkE/B,CACE,CAAC;IAEF,OAAO,CAAC,GAAG,CACT,uBAAuB,QAAQ,EAAE,CAClC,CAAC;AACJ,CAAC;AAED,SAAS,UAAU,CACjB,KAAa;IAEb,OAAO,CACL,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE;QAC7B,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CACf,CAAC;AACJ,CAAC"}
|
|
@@ -1,24 +1,82 @@
|
|
|
1
|
-
import type { AppRoutes } from "../compiler/pre-routes";
|
|
2
1
|
import type { AnyRoutes, RoutesWithMethod, RequestBody, RequestQuery, RequestParams, RequestFiles, ResponseType } from "../compiler/types";
|
|
3
2
|
type RequestInput<TRoutes extends AnyRoutes, TPath extends keyof TRoutes, TMethod extends keyof TRoutes[TPath]> = RequestParams<TRoutes, TPath, TMethod> extends never ? {
|
|
4
|
-
|
|
3
|
+
params?: never;
|
|
5
4
|
query?: RequestQuery<TRoutes, TPath, TMethod>;
|
|
5
|
+
body?: RequestBody<TRoutes, TPath, TMethod>;
|
|
6
6
|
files?: RequestFiles<TRoutes, TPath, TMethod>;
|
|
7
7
|
} : {
|
|
8
8
|
params: RequestParams<TRoutes, TPath, TMethod>;
|
|
9
|
-
body?: RequestBody<TRoutes, TPath, TMethod>;
|
|
10
9
|
query?: RequestQuery<TRoutes, TPath, TMethod>;
|
|
10
|
+
body?: RequestBody<TRoutes, TPath, TMethod>;
|
|
11
11
|
files?: RequestFiles<TRoutes, TPath, TMethod>;
|
|
12
12
|
};
|
|
13
|
-
|
|
13
|
+
/**
|
|
14
|
+
* Type-safe HTTP client built on top of the native Fetch API.
|
|
15
|
+
*
|
|
16
|
+
* `ApiClient` provides end-to-end type safety for your API routes,
|
|
17
|
+
* including:
|
|
18
|
+
*
|
|
19
|
+
* - `params` typing
|
|
20
|
+
* - `query` typing
|
|
21
|
+
* - `body` typing
|
|
22
|
+
* - typed file uploads
|
|
23
|
+
* - fully inferred response types
|
|
24
|
+
*
|
|
25
|
+
* Route types are inferred from your server route definitions,
|
|
26
|
+
* giving you autocomplete and compile-time validation across
|
|
27
|
+
* the entire request lifecycle.
|
|
28
|
+
*
|
|
29
|
+
* @template TRoutes Application route definitions.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```ts
|
|
33
|
+
* import app from '../server/app';
|
|
34
|
+
*
|
|
35
|
+
* const client = new ApiClient<typeof app.contract>()
|
|
36
|
+
*
|
|
37
|
+
* const res = await client.get("/cats", {
|
|
38
|
+
* query: {
|
|
39
|
+
* id: "1",
|
|
40
|
+
* },
|
|
41
|
+
* })
|
|
42
|
+
*
|
|
43
|
+
* // fully typed response
|
|
44
|
+
* console.log(res.cats)
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
declare class ApiClient<TRoutes extends AnyRoutes> {
|
|
14
48
|
private baseURL;
|
|
15
49
|
constructor(baseURL: string);
|
|
16
|
-
protected request<TPath extends keyof TRoutes, TMethod extends keyof TRoutes[TPath]>(method: TMethod, path: TPath, input?: RequestInput<TRoutes, TPath, TMethod>): Promise<
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
50
|
+
protected request<TPath extends keyof TRoutes, TMethod extends keyof TRoutes[TPath]>(method: TMethod, path: TPath, input?: RequestInput<TRoutes, TPath, TMethod>): Promise<{
|
|
51
|
+
ok: boolean;
|
|
52
|
+
status: number;
|
|
53
|
+
data: ResponseType<TRoutes, TPath, TMethod>;
|
|
54
|
+
}>;
|
|
55
|
+
get<TPath extends RoutesWithMethod<TRoutes, "GET">>(path: TPath, input?: RequestInput<TRoutes, TPath, "GET">): Promise<{
|
|
56
|
+
ok: boolean;
|
|
57
|
+
status: number;
|
|
58
|
+
data: ResponseType<TRoutes, TPath, "GET">;
|
|
59
|
+
}>;
|
|
60
|
+
post<TPath extends RoutesWithMethod<TRoutes, "POST">>(path: TPath, input: RequestInput<TRoutes, TPath, "POST">): Promise<{
|
|
61
|
+
ok: boolean;
|
|
62
|
+
status: number;
|
|
63
|
+
data: ResponseType<TRoutes, TPath, "POST">;
|
|
64
|
+
}>;
|
|
65
|
+
put<TPath extends RoutesWithMethod<TRoutes, "PUT">>(path: TPath, input: RequestInput<TRoutes, TPath, "PUT">): Promise<{
|
|
66
|
+
ok: boolean;
|
|
67
|
+
status: number;
|
|
68
|
+
data: ResponseType<TRoutes, TPath, "PUT">;
|
|
69
|
+
}>;
|
|
70
|
+
patch<TPath extends RoutesWithMethod<TRoutes, "PATCH">>(path: TPath, input: RequestInput<TRoutes, TPath, "PATCH">): Promise<{
|
|
71
|
+
ok: boolean;
|
|
72
|
+
status: number;
|
|
73
|
+
data: ResponseType<TRoutes, TPath, "PATCH">;
|
|
74
|
+
}>;
|
|
75
|
+
delete<TPath extends RoutesWithMethod<TRoutes, "DELETE">>(path: TPath, input?: RequestInput<TRoutes, TPath, "DELETE">): Promise<{
|
|
76
|
+
ok: boolean;
|
|
77
|
+
status: number;
|
|
78
|
+
data: ResponseType<TRoutes, TPath, "DELETE">;
|
|
79
|
+
}>;
|
|
22
80
|
}
|
|
23
81
|
export { ApiClient };
|
|
24
82
|
export default ApiClient;
|
|
@@ -1,14 +1,98 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
2
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
26
|
exports.ApiClient = void 0;
|
|
27
|
+
let fetchFn = null;
|
|
28
|
+
async function getFetch() {
|
|
29
|
+
if (fetchFn)
|
|
30
|
+
return fetchFn;
|
|
31
|
+
if (globalThis.fetch) {
|
|
32
|
+
fetchFn = globalThis.fetch;
|
|
33
|
+
return fetchFn;
|
|
34
|
+
}
|
|
35
|
+
const mod = await Promise.resolve().then(() => __importStar(require("node-fetch")));
|
|
36
|
+
fetchFn = mod.default;
|
|
37
|
+
return fetchFn;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Type-safe HTTP client built on top of the native Fetch API.
|
|
41
|
+
*
|
|
42
|
+
* `ApiClient` provides end-to-end type safety for your API routes,
|
|
43
|
+
* including:
|
|
44
|
+
*
|
|
45
|
+
* - `params` typing
|
|
46
|
+
* - `query` typing
|
|
47
|
+
* - `body` typing
|
|
48
|
+
* - typed file uploads
|
|
49
|
+
* - fully inferred response types
|
|
50
|
+
*
|
|
51
|
+
* Route types are inferred from your server route definitions,
|
|
52
|
+
* giving you autocomplete and compile-time validation across
|
|
53
|
+
* the entire request lifecycle.
|
|
54
|
+
*
|
|
55
|
+
* @template TRoutes Application route definitions.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```ts
|
|
59
|
+
* import app from '../server/app';
|
|
60
|
+
*
|
|
61
|
+
* const client = new ApiClient<typeof app.contract>()
|
|
62
|
+
*
|
|
63
|
+
* const res = await client.get("/cats", {
|
|
64
|
+
* query: {
|
|
65
|
+
* id: "1",
|
|
66
|
+
* },
|
|
67
|
+
* })
|
|
68
|
+
*
|
|
69
|
+
* // fully typed response
|
|
70
|
+
* console.log(res.cats)
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
4
73
|
class ApiClient {
|
|
5
74
|
baseURL;
|
|
6
75
|
constructor(baseURL) {
|
|
7
76
|
this.baseURL = baseURL;
|
|
8
77
|
}
|
|
9
78
|
async request(method, path, input) {
|
|
10
|
-
|
|
11
|
-
|
|
79
|
+
let url = this.baseURL + path;
|
|
80
|
+
if (input?.params) {
|
|
81
|
+
for (const key in input.params) {
|
|
82
|
+
url = url.replace(`:${key}`, encodeURIComponent(input.params[key]));
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (input?.query) {
|
|
86
|
+
const queryString = new URLSearchParams(input.query).toString();
|
|
87
|
+
if (queryString) {
|
|
88
|
+
url += `?${queryString}`;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
fetchFn = await getFetch();
|
|
92
|
+
if (!fetchFn) {
|
|
93
|
+
throw new Error("Fetch is not available. Use Node 18+ or polyfill.");
|
|
94
|
+
}
|
|
95
|
+
const res = await fetchFn(url, {
|
|
12
96
|
method: method,
|
|
13
97
|
headers: {
|
|
14
98
|
"Content-Type": "application/json",
|
|
@@ -22,14 +106,20 @@ class ApiClient {
|
|
|
22
106
|
const data = isJson
|
|
23
107
|
? await res.json()
|
|
24
108
|
: await res.text();
|
|
25
|
-
if (!res.ok) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}
|
|
32
|
-
|
|
109
|
+
// if (!res.ok) {
|
|
110
|
+
// throw new Error(
|
|
111
|
+
// data?.message ||
|
|
112
|
+
// data?.error ||
|
|
113
|
+
// (typeof data === "string"
|
|
114
|
+
// ? data
|
|
115
|
+
// : `HTTP ${res.status}`),
|
|
116
|
+
// );
|
|
117
|
+
// }
|
|
118
|
+
return {
|
|
119
|
+
ok: res.ok,
|
|
120
|
+
status: res.status,
|
|
121
|
+
data,
|
|
122
|
+
};
|
|
33
123
|
}
|
|
34
124
|
async get(path, input) {
|
|
35
125
|
return this.request("GET", path, input);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/lib/core/client/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/lib/core/client/index.ts"],"names":[],"mappings":"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"}
|