tspace-spear 1.2.5-beta.4 → 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.
Files changed (35) hide show
  1. package/dist/cli/app.d.ts +1 -0
  2. package/dist/cli/app.js +24 -0
  3. package/dist/cli/app.js.map +1 -0
  4. package/dist/cli/controller.d.ts +1 -0
  5. package/dist/cli/controller.js +158 -0
  6. package/dist/cli/controller.js.map +1 -0
  7. package/dist/cli/index.d.ts +2 -0
  8. package/dist/cli/index.js +138 -0
  9. package/dist/cli/index.js.map +1 -0
  10. package/dist/lib/core/client/index.d.ts +68 -10
  11. package/dist/lib/core/client/index.js +90 -14
  12. package/dist/lib/core/client/index.js.map +1 -1
  13. package/dist/lib/core/compiler/generator.d.ts +1 -1
  14. package/dist/lib/core/compiler/generator.js +167 -3
  15. package/dist/lib/core/compiler/generator.js.map +1 -1
  16. package/dist/lib/core/compiler/index.d.ts +2 -2
  17. package/dist/lib/core/compiler/index.js +2 -1
  18. package/dist/lib/core/compiler/index.js.map +1 -1
  19. package/dist/lib/core/compiler/pre-routes.d.ts +186 -45
  20. package/dist/lib/core/compiler/pre-routes.js +155 -0
  21. package/dist/lib/core/compiler/pre-routes.js.map +1 -1
  22. package/dist/lib/core/decorators/context.d.ts +50 -1
  23. package/dist/lib/core/decorators/context.js +86 -2
  24. package/dist/lib/core/decorators/context.js.map +1 -1
  25. package/dist/lib/core/server/index.d.ts +10 -2
  26. package/dist/lib/core/server/index.js +46 -28
  27. package/dist/lib/core/server/index.js.map +1 -1
  28. package/dist/lib/core/server/parser-factory.d.ts +2 -2
  29. package/dist/lib/core/server/parser-factory.js +139 -1
  30. package/dist/lib/core/server/parser-factory.js.map +1 -1
  31. package/dist/lib/core/types/index.d.ts +2 -1
  32. package/dist/tests/e2e..test.d.ts +1 -0
  33. package/dist/tests/e2e..test.js +16 -0
  34. package/dist/tests/e2e..test.js.map +1 -0
  35. package/package.json +19 -6
@@ -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";
@@ -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,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -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
- body?: RequestBody<TRoutes, TPath, TMethod>;
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
- declare class ApiClient<TRoutes extends AnyRoutes = AppRoutes> {
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<ResponseType<TRoutes, TPath, TMethod>>;
17
- get<TPath extends RoutesWithMethod<TRoutes, "GET">>(path: TPath, input?: RequestInput<TRoutes, TPath, "GET">): Promise<ResponseType<TRoutes, TPath, "GET">>;
18
- post<TPath extends RoutesWithMethod<TRoutes, "POST">>(path: TPath, input: RequestInput<TRoutes, TPath, "POST">): Promise<ResponseType<TRoutes, TPath, "POST">>;
19
- put<TPath extends RoutesWithMethod<TRoutes, "PUT">>(path: TPath, input: RequestInput<TRoutes, TPath, "PUT">): Promise<ResponseType<TRoutes, TPath, "PUT">>;
20
- patch<TPath extends RoutesWithMethod<TRoutes, "PATCH">>(path: TPath, input: RequestInput<TRoutes, TPath, "PATCH">): Promise<ResponseType<TRoutes, TPath, "PATCH">>;
21
- delete<TPath extends RoutesWithMethod<TRoutes, "DELETE">>(path: TPath, input?: RequestInput<TRoutes, TPath, "DELETE">): Promise<ResponseType<TRoutes, TPath, "DELETE">>;
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,6 +1,75 @@
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) {
@@ -8,12 +77,9 @@ class ApiClient {
8
77
  }
9
78
  async request(method, path, input) {
10
79
  let url = this.baseURL + path;
11
- //@ts-ignore
12
80
  if (input?.params) {
13
- //@ts-ignore
14
- const params = input.params;
15
- for (const key in params) {
16
- url = url.replace(`:${key}`, encodeURIComponent(params[key]));
81
+ for (const key in input.params) {
82
+ url = url.replace(`:${key}`, encodeURIComponent(input.params[key]));
17
83
  }
18
84
  }
19
85
  if (input?.query) {
@@ -22,7 +88,11 @@ class ApiClient {
22
88
  url += `?${queryString}`;
23
89
  }
24
90
  }
25
- const res = await fetch(url, {
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, {
26
96
  method: method,
27
97
  headers: {
28
98
  "Content-Type": "application/json",
@@ -36,14 +106,20 @@ class ApiClient {
36
106
  const data = isJson
37
107
  ? await res.json()
38
108
  : await res.text();
39
- if (!res.ok) {
40
- throw new Error(data?.message ||
41
- data?.error ||
42
- (typeof data === "string"
43
- ? data
44
- : `HTTP ${res.status}`));
45
- }
46
- return data;
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
+ };
47
123
  }
48
124
  async get(path, input) {
49
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":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/lib/core/client/index.ts"],"names":[],"mappings":"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"}
@@ -14,5 +14,5 @@ type Options = {
14
14
  };
15
15
  output?: string;
16
16
  };
17
- export declare function generateRoutes(options: Options): Promise<Route[]>;
17
+ export declare function generateRoutes(options: Options): Promise<Route[] | undefined>;
18
18
  export {};