tspace-spear 1.2.3 → 1.2.5-beta.1

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 (63) hide show
  1. package/README.md +268 -19
  2. package/dist/lib/core/client/index.d.ts +23 -0
  3. package/dist/lib/core/client/index.js +45 -0
  4. package/dist/lib/core/client/index.js.map +1 -0
  5. package/dist/lib/core/compiler/generator.d.ts +18 -0
  6. package/dist/lib/core/compiler/generator.js +142 -0
  7. package/dist/lib/core/compiler/generator.js.map +1 -0
  8. package/dist/lib/core/compiler/index.d.ts +14 -0
  9. package/dist/lib/core/compiler/index.js +11 -0
  10. package/dist/lib/core/compiler/index.js.map +1 -0
  11. package/dist/lib/core/compiler/pre-routes.d.ts +3 -0
  12. package/dist/lib/core/compiler/pre-routes.js +5 -0
  13. package/dist/lib/core/compiler/pre-routes.js.map +1 -0
  14. package/dist/lib/core/compiler/types.d.ts +12 -0
  15. package/dist/lib/core/compiler/types.js +3 -0
  16. package/dist/lib/core/compiler/types.js.map +1 -0
  17. package/dist/lib/core/const/index.d.ts +153 -0
  18. package/dist/lib/core/const/index.js +105 -0
  19. package/dist/lib/core/const/index.js.map +1 -0
  20. package/dist/lib/core/decorators/context.d.ts +16 -9
  21. package/dist/lib/core/decorators/context.js +85 -59
  22. package/dist/lib/core/decorators/context.js.map +1 -1
  23. package/dist/lib/core/decorators/headers.d.ts +2 -2
  24. package/dist/lib/core/decorators/headers.js +1 -1
  25. package/dist/lib/core/decorators/headers.js.map +1 -1
  26. package/dist/lib/core/decorators/methods.d.ts +7 -7
  27. package/dist/lib/core/decorators/methods.js.map +1 -1
  28. package/dist/lib/core/decorators/middleware.d.ts +3 -3
  29. package/dist/lib/core/decorators/middleware.js +2 -2
  30. package/dist/lib/core/decorators/middleware.js.map +1 -1
  31. package/dist/lib/core/decorators/statusCode.d.ts +1 -1
  32. package/dist/lib/core/decorators/statusCode.js.map +1 -1
  33. package/dist/lib/core/decorators/swagger.d.ts +1 -1
  34. package/dist/lib/core/decorators/swagger.js.map +1 -1
  35. package/dist/lib/core/server/fast-router.d.ts +133 -0
  36. package/dist/lib/core/server/fast-router.js +277 -0
  37. package/dist/lib/core/server/fast-router.js.map +1 -0
  38. package/dist/lib/core/server/index.d.ts +39 -37
  39. package/dist/lib/core/server/index.js +201 -501
  40. package/dist/lib/core/server/index.js.map +1 -1
  41. package/dist/lib/core/server/net/index.d.ts +20 -0
  42. package/dist/lib/core/server/net/index.js +393 -0
  43. package/dist/lib/core/server/net/index.js.map +1 -0
  44. package/dist/lib/core/server/parser-factory.d.ts +10 -11
  45. package/dist/lib/core/server/parser-factory.js +259 -437
  46. package/dist/lib/core/server/parser-factory.js.map +1 -1
  47. package/dist/lib/core/server/response.d.ts +6 -0
  48. package/dist/lib/core/server/response.js +168 -0
  49. package/dist/lib/core/server/response.js.map +1 -0
  50. package/dist/lib/core/server/router.d.ts +2 -12
  51. package/dist/lib/core/server/router.js +2 -13
  52. package/dist/lib/core/server/router.js.map +1 -1
  53. package/dist/lib/core/server/uWS/index.d.ts +30 -0
  54. package/dist/lib/core/server/uWS/index.js +357 -0
  55. package/dist/lib/core/server/uWS/index.js.map +1 -0
  56. package/dist/lib/core/types/index.d.ts +150 -48
  57. package/dist/lib/core/utils/index.d.ts +12 -0
  58. package/dist/lib/core/utils/index.js +137 -0
  59. package/dist/lib/core/utils/index.js.map +1 -0
  60. package/dist/lib/index.d.ts +4 -3
  61. package/dist/lib/index.js +4 -2
  62. package/dist/lib/index.js.map +1 -1
  63. package/package.json +20 -14
@@ -1,17 +1,21 @@
1
1
  import http, { IncomingHttpHeaders, IncomingMessage, ServerResponse } from "http";
2
2
  import WebSocket from "ws";
3
- type TContext = {
3
+ import net from 'net';
4
+ type TContextBase = {
4
5
  req: TRequest;
5
6
  res: TResponse;
6
7
  headers: THeaders;
7
- query: TQuery;
8
8
  params: TParams;
9
- body: TBody;
10
- files: TFileUpload;
11
9
  cookies: TCookies;
12
10
  ip: TIp;
11
+ ips: TIps;
12
+ body: TBody;
13
+ query: TQuery;
14
+ files: TFileUpload;
13
15
  };
16
+ type TContext<Override extends Partial<Pick<TContextBase, "body" | "query" | "files" | "params">> = {}> = Omit<TContextBase, keyof Override> & Override;
14
17
  type TIp = string | null;
18
+ type TIps = string[];
15
19
  type THeaders<T = IncomingHttpHeaders> = {
16
20
  [K in keyof T]: T[K];
17
21
  };
@@ -37,37 +41,121 @@ type TFile = {
37
41
  };
38
42
  type TFileUpload = Record<string, TFile[] | undefined>;
39
43
  type TNextFunction<T = any> = (err?: Error) => T | Promise<T>;
40
- type TRequest = IncomingMessage & Partial<any>;
44
+ type TRequest = IncomingMessage & {
45
+ uWs: any;
46
+ query: TQuery;
47
+ files: TFileUpload;
48
+ body: TBody;
49
+ params: TParams;
50
+ } & Partial<any>;
41
51
  type THttpResponder = {
42
- /**200+ */
52
+ /**
53
+ * Raw uWS HttpResponse instance.
54
+ */
55
+ uWS: any;
56
+ /** 200 OK - Standard successful response */
43
57
  ok: (data?: Record<string, any>) => any;
58
+ /** 201 Created - Resource successfully created */
44
59
  created: (data?: Record<string, any>) => any;
60
+ /** 202 Accepted - Request accepted for processing */
45
61
  accepted: (data?: Record<string, any>) => any;
46
- /**400+ */
62
+ /** 204 No Content - Successful request with no response body */
47
63
  noContent: (message?: string) => any;
64
+ /** 400 Bad Request - Invalid request from client */
48
65
  badRequest: (message?: string) => any;
66
+ /** 401 Unauthorized - Authentication required or failed */
49
67
  unauthorized: (message?: string) => any;
68
+ /** 402 Payment Required - Reserved for future/payment flow */
50
69
  paymentRequired: (message?: string) => any;
70
+ /** 403 Forbidden - Client does not have access rights */
51
71
  forbidden: (message?: string) => any;
72
+ /** 422 Unprocessable Entity - Valid request but semantic errors */
52
73
  unprocessable: (message?: string) => any;
74
+ /** 429 Too Many Requests - Rate limit exceeded */
53
75
  tooManyRequests: (message?: string) => any;
76
+ /** 404 Not Found - Resource does not exist */
54
77
  notFound: (message?: string) => any;
55
- /**500+ */
78
+ /** 500 Internal Server Error - Generic server failure */
56
79
  serverError: (message?: string) => any;
80
+ /** 502 Bad Gateway - Invalid response from upstream server */
57
81
  badGateway: (message?: string) => any;
82
+ /** 503 Service Unavailable - Server temporarily unavailable */
58
83
  unavailable: (message?: string) => any;
84
+ /** 504 Gateway Timeout - Upstream server timeout */
59
85
  gatewayTimeout: (message?: string) => any;
60
- /**helper */
86
+ /**
87
+ * Serve a media file (video, image, PDF, etc.) from file system.
88
+ * @param filePath Absolute or relative path to media file
89
+ */
90
+ serveMedia: (filePath: string) => any;
91
+ /**
92
+ * Send JSON response.
93
+ * @param data JSON serializable object
94
+ */
61
95
  json: (data?: Record<string, any>) => any;
96
+ /**
97
+ * Send error response (generic wrapper).
98
+ * @param err Error object or message
99
+ */
62
100
  error: (err: any) => any;
101
+ /**
102
+ * Send plain text response.
103
+ * @param message Text content
104
+ */
63
105
  send: (message: string) => any;
106
+ /**
107
+ * Send HTML response.
108
+ * @param html HTML string
109
+ */
64
110
  html: (html: string) => any;
111
+ /**
112
+ * Set HTTP status code and return chained response helpers.
113
+ *
114
+ * This method does not send a response immediately.
115
+ * Instead, it sets the status code and returns a response builder
116
+ * that allows sending the response in different formats.
117
+ *
118
+ * @param code HTTP status code to set for the response
119
+ * @returns An object containing response methods bound to the given status
120
+ *
121
+ * @example
122
+ * res.status(200).json({ success: true });
123
+ *
124
+ * @example
125
+ * res.status(404).send("Not Found");
126
+ *
127
+ * @example
128
+ * res.status(204).end();
129
+ */
65
130
  status: (code: TStatusCode) => {
131
+ /**
132
+ * Send JSON response with the previously set status code.
133
+ *
134
+ * @param data JSON-serializable object to send as response body
135
+ */
66
136
  json: (data?: Record<string, any>) => any;
137
+ /**
138
+ * Send plain text response with the previously set status code.
139
+ *
140
+ * @param message Text response body
141
+ */
67
142
  send: (message: string) => any;
143
+ /**
144
+ * End the response with optional raw message body.
145
+ *
146
+ * Commonly used for empty responses (e.g. 204 No Content).
147
+ *
148
+ * @param message Optional raw response body
149
+ */
150
+ end: (message?: string) => any;
68
151
  };
152
+ /**
153
+ * Set HTTP cookies.
154
+ * @param cookies Key-value map or detailed cookie objects
155
+ */
69
156
  setCookies: (cookies: Record<string, string | {
70
157
  value: string;
158
+ path?: string;
71
159
  sameSite?: 'Strict' | 'Lax' | 'None';
72
160
  domain?: string;
73
161
  secure?: boolean;
@@ -89,16 +177,16 @@ type TRoute = {
89
177
  };
90
178
  type TMethod = 'get' | 'post' | 'patch' | 'put' | 'delete' | 'all' | 'head' | 'options';
91
179
  type TMethodInput = Uppercase<TMethod>;
92
- type Handler = (res: unknown, req: unknown) => void | Promise<void>;
180
+ type HandlerUWS = (res: unknown, req: unknown) => void | Promise<void>;
93
181
  type UWS = {
94
182
  App: () => {
95
- get: (path: string, handler: Handler) => any;
96
- post: (path: string, handler: Handler) => any;
97
- patch: (path: string, handler: Handler) => any;
98
- put: (path: string, handler: Handler) => any;
99
- del: (path: string, handler: Handler) => any;
100
- any: (path: string, handler: Handler) => any;
101
- options: (path: string, handler: Handler) => any;
183
+ get: (path: string, handler: HandlerUWS) => any;
184
+ post: (path: string, handler: HandlerUWS) => any;
185
+ patch: (path: string, handler: HandlerUWS) => any;
186
+ put: (path: string, handler: HandlerUWS) => any;
187
+ del: (path: string, handler: HandlerUWS) => any;
188
+ any: (path: string, handler: HandlerUWS) => any;
189
+ options: (path: string, handler: HandlerUWS) => any;
102
190
  listen: (...args: any[]) => any;
103
191
  ws: (path: string, options: {
104
192
  open?: (ws: any) => void;
@@ -107,22 +195,33 @@ type UWS = {
107
195
  }) => any;
108
196
  };
109
197
  };
110
- type TAdapter = UWS | typeof http;
198
+ type TAdapter = {
199
+ kind: 'http';
200
+ server: typeof http;
201
+ } | {
202
+ kind: 'net';
203
+ server: typeof net;
204
+ } | {
205
+ kind: 'uWS';
206
+ server: UWS;
207
+ };
208
+ type TAdapterServer = typeof http | typeof net | UWS;
111
209
  type TApplication = {
112
210
  controllers?: (new () => any)[] | {
113
211
  folder: string;
114
212
  name?: RegExp;
115
213
  };
116
- middlewares?: TRequestFunction[] | {
214
+ middlewares?: TContextHandler[] | {
117
215
  folder: string;
118
216
  name?: RegExp;
119
217
  };
120
218
  globalPrefix?: string;
121
219
  logger?: boolean;
122
220
  cluster?: boolean | number;
123
- adapter?: TAdapter;
221
+ adapter?: TAdapterServer;
222
+ express?: boolean;
124
223
  };
125
- type TRequestFunction = (ctx: TContext, next: TNextFunction) => any;
224
+ type TContextHandler = (ctx: TContext, next: TNextFunction) => any;
126
225
  type TErrorFunction = (err: Error, ctx: TContext) => any;
127
226
  type TSwaggerFormat = "string" | "number" | "integer" | "boolean" | "object" | "array" | "date" | "date-time" | "password" | "int32" | "int64" | "float" | "double" | "byte" | "binary" | "base64" | "email" | "uuid" | "uri" | "hostname" | "ipv4" | "ipv6" | "json" | "xml";
128
227
  type TSwaggerType = "string" | "number" | "integer" | "boolean" | "object" | "array" | "date" | "date-time" | "file";
@@ -164,40 +263,40 @@ type TSwaggerDoc = {
164
263
  example?: Record<string, any>;
165
264
  }[];
166
265
  };
266
+ type TSwaggerPropertyOptions = {
267
+ type: "array";
268
+ items: TSwaggerPropertyOptions;
269
+ enum?: never;
270
+ required?: boolean;
271
+ example?: any;
272
+ description?: string;
273
+ format?: TSwaggerFormat;
274
+ } | {
275
+ type?: Exclude<TSwaggerType, "array">;
276
+ enum?: (string | number)[];
277
+ required?: boolean;
278
+ example?: any;
279
+ description?: string;
280
+ format?: TSwaggerFormat;
281
+ items?: never;
282
+ };
167
283
  type TSwagger = {
168
284
  disabled?: boolean;
169
285
  description?: string;
170
286
  summary?: string;
171
287
  bearerToken?: boolean;
172
288
  tags?: string[];
173
- params?: Record<string, {
174
- description?: string;
175
- type?: TSwaggerType;
176
- example?: any;
177
- }>;
178
- query?: Record<string, {
179
- required?: boolean;
180
- description?: string;
181
- type?: TSwaggerType;
182
- example?: any;
183
- }>;
289
+ params?: Record<string, TSwaggerPropertyOptions>;
290
+ query?: Record<string, TSwaggerPropertyOptions>;
184
291
  body?: {
185
292
  required?: boolean;
186
293
  description?: string;
187
- properties: Record<string, {
188
- type: TSwaggerType;
189
- example?: any;
190
- }>;
294
+ properties: Record<string, TSwaggerPropertyOptions>;
191
295
  };
192
296
  files?: {
193
297
  required?: boolean;
194
298
  description?: string;
195
- properties: Record<string, {
196
- type: TSwaggerType;
197
- format?: TSwaggerFormat;
198
- items?: any;
199
- example?: any;
200
- }>;
299
+ properties: Record<string, TSwaggerPropertyOptions>;
201
300
  };
202
301
  cookies?: {
203
302
  names: string[];
@@ -211,23 +310,24 @@ type TSwagger = {
211
310
  }[];
212
311
  };
213
312
  type TWSHandler = {
214
- connection: (ws: WebSocket) => void | string | Buffer;
215
- message: (ws: WebSocket, data: WebSocket.Data) => void | string | Buffer;
216
- close: (ws: WebSocket, code: number, reason: Buffer) => void;
217
- error: (ws: WebSocket, error: Error) => void;
313
+ connection: (ws: WebSocket & Partial<any>) => void | string | Buffer;
314
+ message: (ws: WebSocket & Partial<any>, data: WebSocket.Data) => void | string | Buffer;
315
+ close: (ws: WebSocket & Partial<any>, code: number, reason: Buffer) => void;
316
+ error: (ws: WebSocket & Partial<any>, error: Error) => void;
218
317
  };
219
318
  export declare namespace T {
319
+ type Context<O extends Partial<Pick<TContextBase, "body" | "query" | "files" | "params">> = {}> = TContext<O>;
220
320
  type Adapter = TAdapter;
321
+ type AdapterServer = TAdapterServer;
221
322
  type Application = TApplication;
222
323
  type NextFunction = TNextFunction;
223
324
  type File = TFile;
224
- type Context = TContext;
225
325
  type Router = TRouter;
226
326
  type Route = TRoute;
227
327
  type Method = TMethod;
228
328
  type ErrorFunction = TErrorFunction;
229
329
  type HttpStatus = THttpResponder;
230
- type RequestFunction = TRequestFunction;
330
+ type ContextHandler = TContextHandler;
231
331
  type WebSocketHandler = TWSHandler;
232
332
  type StatusCode = TStatusCode;
233
333
  type MethodInput = TMethodInput;
@@ -239,6 +339,8 @@ export declare namespace T {
239
339
  type Query<T = Record<string, string>> = TQuery<T>;
240
340
  type Body<T = Record<string, any>> = TBody<T>;
241
341
  type Headers<T = IncomingHttpHeaders> = THeaders<T>;
342
+ type Ip = TIp;
343
+ type Ips = TIps;
242
344
  namespace Swagger {
243
345
  type Spec = TSwagger;
244
346
  type Format = TSwaggerFormat;
@@ -0,0 +1,12 @@
1
+ import { IncomingMessage, ServerResponse } from "http";
2
+ import { Stream } from "stream";
3
+ export declare const normalizeRequestBody: ({ contentType, payload, }: {
4
+ contentType: string | null;
5
+ payload: any;
6
+ }) => Promise<any>;
7
+ export declare const pipeStream: ({ req, res, filePath, isUwebSocket, }: {
8
+ req: IncomingMessage;
9
+ res: ServerResponse;
10
+ filePath: string;
11
+ isUwebSocket?: boolean;
12
+ }) => Promise<Stream>;
@@ -0,0 +1,137 @@
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.pipeStream = exports.normalizeRequestBody = void 0;
7
+ const const_1 = require("../const");
8
+ const uWS_1 = require("../server/uWS");
9
+ const querystring_1 = __importDefault(require("querystring"));
10
+ const fs_1 = __importDefault(require("fs"));
11
+ const path_1 = __importDefault(require("path"));
12
+ const mime_types_1 = __importDefault(require("mime-types"));
13
+ const xml2js_1 = __importDefault(require("xml2js"));
14
+ const crypto_1 = __importDefault(require("crypto"));
15
+ const normalizeRequestBody = async ({ contentType, payload, }) => {
16
+ if (contentType == null || payload == null || payload === "") {
17
+ return {};
18
+ }
19
+ if (contentType.includes("x-www-form-urlencoded")) {
20
+ return querystring_1.default.parse(payload);
21
+ }
22
+ if (contentType.includes("application/json")) {
23
+ try {
24
+ return JSON.parse(payload);
25
+ }
26
+ catch (err) {
27
+ throw new Error("Invalid JSON format in request body.");
28
+ }
29
+ }
30
+ if (contentType.includes("application/xml") ||
31
+ contentType.includes("text/xml")) {
32
+ try {
33
+ const result = await xml2js_1.default.parseStringPromise(payload, {
34
+ explicitArray: false,
35
+ });
36
+ return result;
37
+ }
38
+ catch (err) {
39
+ throw new Error("Invalid XML format in request body.");
40
+ }
41
+ }
42
+ if (contentType.includes("text/plain") ||
43
+ contentType.includes("text/javascript") ||
44
+ contentType.includes("application/javascript") ||
45
+ contentType.includes("application/x-javascript")) {
46
+ return { contentType, text: payload };
47
+ }
48
+ return {};
49
+ };
50
+ exports.normalizeRequestBody = normalizeRequestBody;
51
+ const pipeStream = async ({ req, res, filePath, isUwebSocket, }) => {
52
+ if (!fs_1.default.existsSync(filePath)) {
53
+ return res
54
+ .writeHead(404, const_1.HEADER_CONTENT_TYPES["text"])
55
+ .end(`File not found: ${path_1.default.basename(filePath)}`);
56
+ }
57
+ if (isUwebSocket) {
58
+ return (0, uWS_1.uWSPipeStream)({ req, res, filePath });
59
+ }
60
+ const stat = fs_1.default.statSync(filePath);
61
+ const fileSize = stat.size;
62
+ const range = req.headers["range"] ?? null;
63
+ const contentType = mime_types_1.default.lookup(filePath) || "application/octet-stream";
64
+ const isVideo = contentType.startsWith("video/");
65
+ const writeHead = (header, code = 200) => {
66
+ const extension = filePath.split(".").pop();
67
+ const previews = Object.values({
68
+ video: [
69
+ "mp4",
70
+ "webm",
71
+ "ogg",
72
+ "ogv",
73
+ "avi",
74
+ "mov",
75
+ "mkv",
76
+ "flv",
77
+ "f4v",
78
+ "wmv",
79
+ "ts",
80
+ "mpeg",
81
+ ],
82
+ audio: ["wav", "mp3"],
83
+ document: ["pdf"],
84
+ image: ["png", "jpeg", "jpg", "gif", "webp", "svg", "ico"],
85
+ }).flat();
86
+ if (previews.some((p) => extension?.toLocaleLowerCase().includes(p))) {
87
+ res.writeHead(code, header);
88
+ return;
89
+ }
90
+ res.setHeader("Content-Disposition", `attachment; filename=${+new Date()}.${extension}`);
91
+ res.setHeader("Content-Type", "application/octet-stream");
92
+ };
93
+ const maxAge = 1000 * 60 * 60 * 24 * 7;
94
+ const etag = crypto_1.default.createHash("md5").update(`${stat.size}-${stat.mtimeMs}`).digest("hex");
95
+ const baseHeader = {
96
+ "Connection": "keep-alive",
97
+ "Keep-Alive": "timeout=60, max=1000",
98
+ "Cache-Control": `public, max-age=${maxAge}, immutable`,
99
+ "Strict-transport-security": `max-age=${maxAge}; includeSubDomains`,
100
+ "ETag": `"${etag}"`,
101
+ "Date": new Date(stat.birthtimeMs).toUTCString(),
102
+ "Last-modified": new Date(stat.birthtimeMs).toUTCString(),
103
+ "Vary": "Origin, Accept-Encoding",
104
+ "Accept-Ranges": "bytes",
105
+ "Content-Length": fileSize,
106
+ "Content-Type": contentType,
107
+ "X-Content-type-options": "nosniff",
108
+ "X-Xss-protection": "1; mode=block",
109
+ };
110
+ if (!isVideo || range == null) {
111
+ const header = {
112
+ ...baseHeader,
113
+ "Content-Length": fileSize,
114
+ "Content-Type": contentType,
115
+ };
116
+ const stream = fs_1.default.createReadStream(filePath);
117
+ writeHead(header);
118
+ stream.on("error", () => res.end());
119
+ return stream.pipe(res);
120
+ }
121
+ const parts = range.replace(/bytes=/, "").split("-");
122
+ const start = parseInt(parts[0], 10);
123
+ const end = parts[1] ? parseInt(parts[1], 10) : fileSize - 1;
124
+ const chunksize = end - start + 1;
125
+ const stream = fs_1.default.createReadStream(filePath, { start, end });
126
+ const header = {
127
+ ...baseHeader,
128
+ "Content-Range": `bytes ${start}-${end}/${fileSize}`,
129
+ "Content-Length": chunksize,
130
+ "Accept-Ranges": "bytes"
131
+ };
132
+ writeHead(header, 206);
133
+ stream.on("error", () => res.end());
134
+ return stream.pipe(res);
135
+ };
136
+ exports.pipeStream = pipeStream;
137
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/lib/core/utils/index.ts"],"names":[],"mappings":"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"}
@@ -3,9 +3,10 @@
3
3
  *
4
4
  * @module tspace-spear
5
5
  */
6
+ import Spear from './core/server';
6
7
  export * from './core/decorators';
7
- export * from './core/server/router';
8
+ export * from './core/types';
8
9
  export * from './core/server';
9
- export { T } from './core/types';
10
- import Spear from './core/server';
10
+ export * from './core/server/router';
11
+ export * from './core/client';
11
12
  export default Spear;
package/dist/lib/index.js CHANGED
@@ -22,9 +22,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
22
22
  *
23
23
  * @module tspace-spear
24
24
  */
25
+ const server_1 = __importDefault(require("./core/server"));
25
26
  __exportStar(require("./core/decorators"), exports);
26
- __exportStar(require("./core/server/router"), exports);
27
+ __exportStar(require("./core/types"), exports);
27
28
  __exportStar(require("./core/server"), exports);
28
- const server_1 = __importDefault(require("./core/server"));
29
+ __exportStar(require("./core/server/router"), exports);
30
+ __exportStar(require("./core/client"), exports);
29
31
  exports.default = server_1.default;
30
32
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/lib/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;;;;IAII;AACJ,oDAAiC;AACjC,uDAAoC;AACpC,gDAA6B;AAG7B,2DAAkC;AAElC,kBAAe,gBAAK,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/lib/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;;;;IAII;AACJ,2DAAkC;AAElC,oDAAkC;AAClC,+CAA6B;AAC7B,gDAA8B;AAC9B,uDAAqC;AACrC,gDAA6B;AAE7B,kBAAe,gBAAK,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tspace-spear",
3
- "version": "1.2.3",
3
+ "version": "1.2.5-beta.1",
4
4
  "description": "tspace-spear is a lightweight, high-performance API framework for Node.js that leverages the native HTTP server and supports uWebSockets.js (C++) for maximum speed and efficiency.",
5
5
  "main": "./dist/lib/index.js",
6
6
  "types": "./dist/lib/index.d.ts",
@@ -18,6 +18,8 @@
18
18
  "api",
19
19
  "rest api",
20
20
  "fast",
21
+ "fast-api",
22
+ "fast api",
21
23
  "low overhead",
22
24
  "http",
23
25
  "uWS",
@@ -35,9 +37,12 @@
35
37
  "prepare": "npm run build",
36
38
  "release": "npm run build && npm publish",
37
39
  "beta": "npm run build && npm publish --tag beta",
38
- "benchmark": "npm run build && ts-node __tests__/benchmark.test.ts",
40
+ "bm:node": "npm run benchmark:node",
41
+ "bm:bun": "npm run benchmark:bun",
42
+ "benchmark:node": "npm run build && node benchmarks/tests/benchmark.node.js",
43
+ "benchmark:bun": "npm run build && bun run benchmarks/tests/benchmark.bun.js",
39
44
  "test": "mocha dist/tests/**/0*.test.js",
40
- "load": "autocannon -c 100 -d 30 -p 10 localhost:3000",
45
+ "load": "autocannon -c 100 -d 30 -p 10 localhost:5000",
41
46
  "docs": "npx docsify-cli serve docs"
42
47
  },
43
48
  "engines": {
@@ -45,36 +50,37 @@
45
50
  },
46
51
  "dependencies": {
47
52
  "busboy": "1.6.0",
48
- "find-my-way": "8.2.2",
53
+ "fast-querystring": "1.1.2",
49
54
  "mime-types": "2.1.35",
50
55
  "on-finished": "2.4.1",
51
56
  "reflect-metadata": "0.2.2",
52
57
  "swagger-ui-dist": "5.32.0",
53
- "ws": "8.19.0"
58
+ "ws": "8.19.0",
59
+ "xml2js": "0.6.2",
60
+ "ts-morph": "28.0.0"
54
61
  },
55
62
  "devDependencies": {
63
+ "@elysiajs/node": "1.4.5",
64
+ "@hono/node-server": "1.19.11",
56
65
  "@types/autocannon": "7.12.5",
57
66
  "@types/busboy": "1.5.4",
58
- "@types/chai": "5.2.3",
59
- "@types/chai-http": "4.2.4",
60
67
  "@types/express": "4.17.21",
61
- "@types/jest": "30.0.0",
62
68
  "@types/mime-types": "2.1.4",
63
- "@types/mocha": "10.0.10",
64
- "@types/node": "16.4.0",
69
+ "@types/node": "16.18.126",
65
70
  "@types/on-finished": "2.3.4",
66
71
  "@types/swagger-ui-dist": "3.30.4",
67
72
  "@types/ws": "8.18.1",
68
- "@types/yargs": "17.0.32",
73
+ "@types/xml2js": "0.4.14",
74
+ "0http": "4.4.0",
69
75
  "autocannon": "7.15.0",
70
- "chai": "4.5.0",
71
- "chai-http": "5.1.2",
72
76
  "docsify-cli": "4.4.4",
77
+ "elysia": "1.4.28",
73
78
  "express": "4.19.2",
74
79
  "fastify": "4.28.1",
80
+ "hono": "4.12.9",
75
81
  "ts-node": "10.9.2",
76
82
  "typescript": "5.9.3",
77
- "yargs": "17.7.2",
83
+ "uWebSockets.js": "github:uNetworking/uWebSockets.js#v20.63.0",
78
84
  "zod": "4.3.6"
79
85
  }
80
86
  }