princejs 1.3.5 → 1.4.0
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/index.js +346 -0
- package/dist/prince.js +140 -0
- package/package.json +22 -6
package/dist/index.js
ADDED
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// src/prince.ts
|
|
3
|
+
class TrieNode {
|
|
4
|
+
children = Object.create(null);
|
|
5
|
+
paramChild;
|
|
6
|
+
wildcardChild;
|
|
7
|
+
catchAllChild;
|
|
8
|
+
handlers = null;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
class ResponseBuilder {
|
|
12
|
+
_status = 200;
|
|
13
|
+
_headers = {};
|
|
14
|
+
_body = null;
|
|
15
|
+
status(code) {
|
|
16
|
+
this._status = code;
|
|
17
|
+
return this;
|
|
18
|
+
}
|
|
19
|
+
header(key, value) {
|
|
20
|
+
this._headers[key] = value;
|
|
21
|
+
return this;
|
|
22
|
+
}
|
|
23
|
+
json(data) {
|
|
24
|
+
this._headers["Content-Type"] = "application/json";
|
|
25
|
+
this._body = JSON.stringify(data);
|
|
26
|
+
return this.build();
|
|
27
|
+
}
|
|
28
|
+
text(data) {
|
|
29
|
+
this._headers["Content-Type"] = "text/plain";
|
|
30
|
+
this._body = data;
|
|
31
|
+
return this.build();
|
|
32
|
+
}
|
|
33
|
+
html(data) {
|
|
34
|
+
this._headers["Content-Type"] = "text/html";
|
|
35
|
+
this._body = data;
|
|
36
|
+
return this.build();
|
|
37
|
+
}
|
|
38
|
+
redirect(url, status = 302) {
|
|
39
|
+
this._status = status;
|
|
40
|
+
this._headers["Location"] = url;
|
|
41
|
+
return this.build();
|
|
42
|
+
}
|
|
43
|
+
build() {
|
|
44
|
+
return new Response(this._body, {
|
|
45
|
+
status: this._status,
|
|
46
|
+
headers: this._headers
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
class Prince {
|
|
52
|
+
devMode;
|
|
53
|
+
rawRoutes = [];
|
|
54
|
+
middlewares = [];
|
|
55
|
+
errorHandler;
|
|
56
|
+
prefix = "";
|
|
57
|
+
constructor(devMode = false) {
|
|
58
|
+
this.devMode = devMode;
|
|
59
|
+
}
|
|
60
|
+
use(mw) {
|
|
61
|
+
this.middlewares.push(mw);
|
|
62
|
+
return this;
|
|
63
|
+
}
|
|
64
|
+
error(fn) {
|
|
65
|
+
this.errorHandler = fn;
|
|
66
|
+
return this;
|
|
67
|
+
}
|
|
68
|
+
json(data, status = 200) {
|
|
69
|
+
return new Response(JSON.stringify(data), {
|
|
70
|
+
status,
|
|
71
|
+
headers: { "Content-Type": "application/json" }
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
response() {
|
|
75
|
+
return new ResponseBuilder;
|
|
76
|
+
}
|
|
77
|
+
route(path) {
|
|
78
|
+
const group = new Prince(this.devMode);
|
|
79
|
+
group.prefix = path;
|
|
80
|
+
group.middlewares = [...this.middlewares];
|
|
81
|
+
return {
|
|
82
|
+
get: (subpath, handler) => {
|
|
83
|
+
this.get(path + subpath, handler);
|
|
84
|
+
return group;
|
|
85
|
+
},
|
|
86
|
+
post: (subpath, handler) => {
|
|
87
|
+
this.post(path + subpath, handler);
|
|
88
|
+
return group;
|
|
89
|
+
},
|
|
90
|
+
put: (subpath, handler) => {
|
|
91
|
+
this.put(path + subpath, handler);
|
|
92
|
+
return group;
|
|
93
|
+
},
|
|
94
|
+
delete: (subpath, handler) => {
|
|
95
|
+
this.delete(path + subpath, handler);
|
|
96
|
+
return group;
|
|
97
|
+
},
|
|
98
|
+
patch: (subpath, handler) => {
|
|
99
|
+
this.patch(path + subpath, handler);
|
|
100
|
+
return group;
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
get(path, handler) {
|
|
105
|
+
return this.add("GET", path, handler);
|
|
106
|
+
}
|
|
107
|
+
post(path, handler) {
|
|
108
|
+
return this.add("POST", path, handler);
|
|
109
|
+
}
|
|
110
|
+
put(path, handler) {
|
|
111
|
+
return this.add("PUT", path, handler);
|
|
112
|
+
}
|
|
113
|
+
delete(path, handler) {
|
|
114
|
+
return this.add("DELETE", path, handler);
|
|
115
|
+
}
|
|
116
|
+
patch(path, handler) {
|
|
117
|
+
return this.add("PATCH", path, handler);
|
|
118
|
+
}
|
|
119
|
+
options(path, handler) {
|
|
120
|
+
return this.add("OPTIONS", path, handler);
|
|
121
|
+
}
|
|
122
|
+
head(path, handler) {
|
|
123
|
+
return this.add("HEAD", path, handler);
|
|
124
|
+
}
|
|
125
|
+
add(method, path, handler) {
|
|
126
|
+
if (!path.startsWith("/"))
|
|
127
|
+
path = "/" + path;
|
|
128
|
+
if (path.length > 1 && path.endsWith("/"))
|
|
129
|
+
path = path.slice(0, -1);
|
|
130
|
+
const parts = path === "/" ? [""] : path.split("/").slice(1);
|
|
131
|
+
this.rawRoutes.push({ method: method.toUpperCase(), path, parts, handler });
|
|
132
|
+
return this;
|
|
133
|
+
}
|
|
134
|
+
parseUrl(req) {
|
|
135
|
+
const url = new URL(req.url);
|
|
136
|
+
const query = {};
|
|
137
|
+
for (const [key, value] of url.searchParams.entries()) {
|
|
138
|
+
query[key] = value;
|
|
139
|
+
}
|
|
140
|
+
return {
|
|
141
|
+
pathname: url.pathname,
|
|
142
|
+
query
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
async parseBody(req) {
|
|
146
|
+
const ct = req.headers.get("content-type") || "";
|
|
147
|
+
if (ct.includes("application/json")) {
|
|
148
|
+
return await req.json();
|
|
149
|
+
}
|
|
150
|
+
if (ct.includes("application/x-www-form-urlencoded")) {
|
|
151
|
+
const text = await req.text();
|
|
152
|
+
const params = {};
|
|
153
|
+
const pairs = text.split("&");
|
|
154
|
+
for (const pair of pairs) {
|
|
155
|
+
const [key, val] = pair.split("=");
|
|
156
|
+
params[decodeURIComponent(key)] = decodeURIComponent(val || "");
|
|
157
|
+
}
|
|
158
|
+
return params;
|
|
159
|
+
}
|
|
160
|
+
if (ct.includes("text/")) {
|
|
161
|
+
return await req.text();
|
|
162
|
+
}
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
buildRouter() {
|
|
166
|
+
const root = new TrieNode;
|
|
167
|
+
for (const route of this.rawRoutes) {
|
|
168
|
+
let node = root;
|
|
169
|
+
const parts = route.parts;
|
|
170
|
+
if (parts.length === 1 && parts[0] === "") {
|
|
171
|
+
if (!node.handlers)
|
|
172
|
+
node.handlers = Object.create(null);
|
|
173
|
+
node.handlers[route.method] = route.handler;
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
for (let i = 0;i < parts.length; i++) {
|
|
177
|
+
const part = parts[i];
|
|
178
|
+
if (part === "**") {
|
|
179
|
+
if (!node.catchAllChild) {
|
|
180
|
+
node.catchAllChild = { name: "**", node: new TrieNode };
|
|
181
|
+
}
|
|
182
|
+
node = node.catchAllChild.node;
|
|
183
|
+
break;
|
|
184
|
+
} else if (part === "*") {
|
|
185
|
+
if (!node.wildcardChild)
|
|
186
|
+
node.wildcardChild = new TrieNode;
|
|
187
|
+
node = node.wildcardChild;
|
|
188
|
+
} else if (part.startsWith(":")) {
|
|
189
|
+
const name = part.slice(1);
|
|
190
|
+
if (!node.paramChild)
|
|
191
|
+
node.paramChild = { name, node: new TrieNode };
|
|
192
|
+
node = node.paramChild.node;
|
|
193
|
+
} else {
|
|
194
|
+
if (!node.children[part])
|
|
195
|
+
node.children[part] = new TrieNode;
|
|
196
|
+
node = node.children[part];
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
if (!node.handlers)
|
|
200
|
+
node.handlers = Object.create(null);
|
|
201
|
+
node.handlers[route.method] = route.handler;
|
|
202
|
+
}
|
|
203
|
+
return root;
|
|
204
|
+
}
|
|
205
|
+
compilePipeline(handler, paramsGetter) {
|
|
206
|
+
const mws = this.middlewares.slice();
|
|
207
|
+
const hasMiddleware = mws.length > 0;
|
|
208
|
+
if (!hasMiddleware) {
|
|
209
|
+
return async (req, params, query) => {
|
|
210
|
+
const princeReq = req;
|
|
211
|
+
princeReq.params = params;
|
|
212
|
+
princeReq.query = query;
|
|
213
|
+
if (req.method === "POST" || req.method === "PUT" || req.method === "PATCH") {
|
|
214
|
+
princeReq.body = await this.parseBody(req);
|
|
215
|
+
}
|
|
216
|
+
const res = await handler(princeReq);
|
|
217
|
+
if (res instanceof Response)
|
|
218
|
+
return res;
|
|
219
|
+
if (typeof res === "string")
|
|
220
|
+
return new Response(res, { status: 200 });
|
|
221
|
+
if (res instanceof Uint8Array || res instanceof ArrayBuffer)
|
|
222
|
+
return new Response(res, { status: 200 });
|
|
223
|
+
return this.json(res);
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
return async (req, params, query) => {
|
|
227
|
+
const princeReq = req;
|
|
228
|
+
princeReq.params = params;
|
|
229
|
+
princeReq.query = query;
|
|
230
|
+
let idx = 0;
|
|
231
|
+
const runNext = async () => {
|
|
232
|
+
if (idx >= mws.length) {
|
|
233
|
+
if (req.method === "POST" || req.method === "PUT" || req.method === "PATCH") {
|
|
234
|
+
princeReq.body = await this.parseBody(req);
|
|
235
|
+
}
|
|
236
|
+
const res = await handler(princeReq);
|
|
237
|
+
if (res instanceof Response)
|
|
238
|
+
return res;
|
|
239
|
+
if (typeof res === "string")
|
|
240
|
+
return new Response(res, { status: 200 });
|
|
241
|
+
if (res instanceof Uint8Array || res instanceof ArrayBuffer)
|
|
242
|
+
return new Response(res, { status: 200 });
|
|
243
|
+
return this.json(res);
|
|
244
|
+
}
|
|
245
|
+
const mw = mws[idx++];
|
|
246
|
+
return await mw(req, runNext);
|
|
247
|
+
};
|
|
248
|
+
const out = await runNext();
|
|
249
|
+
if (out instanceof Response)
|
|
250
|
+
return out;
|
|
251
|
+
if (out !== undefined) {
|
|
252
|
+
if (typeof out === "string")
|
|
253
|
+
return new Response(out, { status: 200 });
|
|
254
|
+
if (out instanceof Uint8Array || out instanceof ArrayBuffer)
|
|
255
|
+
return new Response(out, { status: 200 });
|
|
256
|
+
return this.json(out);
|
|
257
|
+
}
|
|
258
|
+
return new Response(null, { status: 204 });
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
listen(port = 3000) {
|
|
262
|
+
const root = this.buildRouter();
|
|
263
|
+
const handlerMap = new Map;
|
|
264
|
+
Bun.serve({
|
|
265
|
+
port,
|
|
266
|
+
fetch: async (req) => {
|
|
267
|
+
try {
|
|
268
|
+
const { pathname, query } = this.parseUrl(req);
|
|
269
|
+
const segments = pathname === "/" ? [] : pathname.slice(1).split("/");
|
|
270
|
+
let node = root;
|
|
271
|
+
const params = {};
|
|
272
|
+
let matched = true;
|
|
273
|
+
if (segments.length === 0) {
|
|
274
|
+
if (!node.handlers)
|
|
275
|
+
return this.json({ error: "Route not found" }, 404);
|
|
276
|
+
const handler2 = node.handlers[req.method];
|
|
277
|
+
if (!handler2)
|
|
278
|
+
return this.json({ error: "Method not allowed" }, 405);
|
|
279
|
+
let methodMap2 = handlerMap.get(node);
|
|
280
|
+
if (!methodMap2) {
|
|
281
|
+
methodMap2 = {};
|
|
282
|
+
handlerMap.set(node, methodMap2);
|
|
283
|
+
}
|
|
284
|
+
if (!methodMap2[req.method]) {
|
|
285
|
+
methodMap2[req.method] = this.compilePipeline(handler2, (_) => params);
|
|
286
|
+
}
|
|
287
|
+
return await methodMap2[req.method](req, params, query);
|
|
288
|
+
}
|
|
289
|
+
for (let i = 0;i < segments.length; i++) {
|
|
290
|
+
const seg = segments[i];
|
|
291
|
+
if (node.children[seg]) {
|
|
292
|
+
node = node.children[seg];
|
|
293
|
+
continue;
|
|
294
|
+
}
|
|
295
|
+
if (node.paramChild) {
|
|
296
|
+
params[node.paramChild.name] = seg;
|
|
297
|
+
node = node.paramChild.node;
|
|
298
|
+
continue;
|
|
299
|
+
}
|
|
300
|
+
if (node.wildcardChild) {
|
|
301
|
+
node = node.wildcardChild;
|
|
302
|
+
continue;
|
|
303
|
+
}
|
|
304
|
+
if (node.catchAllChild) {
|
|
305
|
+
const remaining = segments.slice(i).join("/");
|
|
306
|
+
if (node.catchAllChild.name)
|
|
307
|
+
params[node.catchAllChild.name] = remaining;
|
|
308
|
+
node = node.catchAllChild.node;
|
|
309
|
+
break;
|
|
310
|
+
}
|
|
311
|
+
matched = false;
|
|
312
|
+
break;
|
|
313
|
+
}
|
|
314
|
+
if (!matched || !node || !node.handlers) {
|
|
315
|
+
return this.json({ error: "Route not found" }, 404);
|
|
316
|
+
}
|
|
317
|
+
const handler = node.handlers[req.method];
|
|
318
|
+
if (!handler)
|
|
319
|
+
return this.json({ error: "Method not allowed" }, 405);
|
|
320
|
+
let methodMap = handlerMap.get(node);
|
|
321
|
+
if (!methodMap) {
|
|
322
|
+
methodMap = {};
|
|
323
|
+
handlerMap.set(node, methodMap);
|
|
324
|
+
}
|
|
325
|
+
if (!methodMap[req.method]) {
|
|
326
|
+
methodMap[req.method] = this.compilePipeline(handler, (_) => params);
|
|
327
|
+
}
|
|
328
|
+
return await methodMap[req.method](req, params, query);
|
|
329
|
+
} catch (err) {
|
|
330
|
+
if (this.errorHandler) {
|
|
331
|
+
try {
|
|
332
|
+
return this.errorHandler(err, req);
|
|
333
|
+
} catch {}
|
|
334
|
+
}
|
|
335
|
+
return this.json({ error: String(err) }, 500);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
});
|
|
339
|
+
console.log(`\uD83D\uDE80 PrinceJS running at http://localhost:${port}`);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
var prince = (dev = false) => new Prince(dev);
|
|
343
|
+
export {
|
|
344
|
+
prince,
|
|
345
|
+
Prince
|
|
346
|
+
};
|
package/dist/prince.js
CHANGED
|
@@ -1,4 +1,129 @@
|
|
|
1
1
|
// @bun
|
|
2
|
+
// src/middleware.ts
|
|
3
|
+
var MIDDLEWARE_EXECUTED = Symbol("middlewareExecuted");
|
|
4
|
+
var cors = (options) => {
|
|
5
|
+
const origin = options?.origin || "*";
|
|
6
|
+
const methods = options?.methods || "GET,POST,PUT,DELETE,PATCH,OPTIONS";
|
|
7
|
+
const headers = options?.headers || "Content-Type,Authorization";
|
|
8
|
+
const credentials = options?.credentials || false;
|
|
9
|
+
return async (req, next) => {
|
|
10
|
+
if (req[MIDDLEWARE_EXECUTED]?.cors) {
|
|
11
|
+
return await next();
|
|
12
|
+
}
|
|
13
|
+
if (!req[MIDDLEWARE_EXECUTED]) {
|
|
14
|
+
req[MIDDLEWARE_EXECUTED] = {};
|
|
15
|
+
}
|
|
16
|
+
req[MIDDLEWARE_EXECUTED].cors = true;
|
|
17
|
+
if (req.method === "OPTIONS") {
|
|
18
|
+
return new Response(null, {
|
|
19
|
+
status: 204,
|
|
20
|
+
headers: {
|
|
21
|
+
"Access-Control-Allow-Origin": origin,
|
|
22
|
+
"Access-Control-Allow-Methods": methods,
|
|
23
|
+
"Access-Control-Allow-Headers": headers,
|
|
24
|
+
...credentials ? { "Access-Control-Allow-Credentials": "true" } : {}
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
const res = await next();
|
|
29
|
+
if (!res)
|
|
30
|
+
return res;
|
|
31
|
+
const newHeaders = new Headers(res.headers);
|
|
32
|
+
newHeaders.set("Access-Control-Allow-Origin", origin);
|
|
33
|
+
if (credentials)
|
|
34
|
+
newHeaders.set("Access-Control-Allow-Credentials", "true");
|
|
35
|
+
return new Response(res.body, {
|
|
36
|
+
status: res.status,
|
|
37
|
+
statusText: res.statusText,
|
|
38
|
+
headers: newHeaders
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
var logger = (options) => {
|
|
43
|
+
const format = options?.format || "dev";
|
|
44
|
+
const colors = options?.colors !== false;
|
|
45
|
+
const colorize = (code, text) => {
|
|
46
|
+
if (!colors)
|
|
47
|
+
return text;
|
|
48
|
+
if (code >= 500)
|
|
49
|
+
return `\x1B[31m${text}\x1B[0m`;
|
|
50
|
+
if (code >= 400)
|
|
51
|
+
return `\x1B[33m${text}\x1B[0m`;
|
|
52
|
+
if (code >= 300)
|
|
53
|
+
return `\x1B[36m${text}\x1B[0m`;
|
|
54
|
+
if (code >= 200)
|
|
55
|
+
return `\x1B[32m${text}\x1B[0m`;
|
|
56
|
+
return text;
|
|
57
|
+
};
|
|
58
|
+
return async (req, next) => {
|
|
59
|
+
if (req[MIDDLEWARE_EXECUTED]?.logger) {
|
|
60
|
+
return await next();
|
|
61
|
+
}
|
|
62
|
+
if (!req[MIDDLEWARE_EXECUTED]) {
|
|
63
|
+
req[MIDDLEWARE_EXECUTED] = {};
|
|
64
|
+
}
|
|
65
|
+
req[MIDDLEWARE_EXECUTED].logger = true;
|
|
66
|
+
const start = Date.now();
|
|
67
|
+
const pathname = new URL(req.url).pathname;
|
|
68
|
+
const res = await next();
|
|
69
|
+
if (!res)
|
|
70
|
+
return res;
|
|
71
|
+
const duration = Date.now() - start;
|
|
72
|
+
const status = res.status;
|
|
73
|
+
if (format === "dev") {
|
|
74
|
+
console.log(`${colorize(status, req.method)} ${pathname} ${colorize(status, String(status))} ${duration}ms`);
|
|
75
|
+
} else if (format === "tiny") {
|
|
76
|
+
console.log(`${req.method} ${pathname} ${status} - ${duration}ms`);
|
|
77
|
+
} else {
|
|
78
|
+
const date = new Date().toISOString();
|
|
79
|
+
console.log(`[${date}] ${req.method} ${pathname} ${status} ${duration}ms`);
|
|
80
|
+
}
|
|
81
|
+
return res;
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
var rateLimit = (options) => {
|
|
85
|
+
const store = new Map;
|
|
86
|
+
return async (req, next) => {
|
|
87
|
+
const ip = req.headers.get("x-forwarded-for") || "unknown";
|
|
88
|
+
const now = Date.now();
|
|
89
|
+
const windowMs = options.window * 1000;
|
|
90
|
+
let record = store.get(ip);
|
|
91
|
+
if (!record || now > record.resetAt) {
|
|
92
|
+
record = { count: 1, resetAt: now + windowMs };
|
|
93
|
+
store.set(ip, record);
|
|
94
|
+
return await next();
|
|
95
|
+
}
|
|
96
|
+
if (record.count >= options.max) {
|
|
97
|
+
return new Response(JSON.stringify({ error: options.message || "Too many requests" }), {
|
|
98
|
+
status: 429,
|
|
99
|
+
headers: { "Content-Type": "application/json" }
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
record.count++;
|
|
103
|
+
return await next();
|
|
104
|
+
};
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
// src/validation.ts
|
|
108
|
+
var validate = (schema, source = "body") => {
|
|
109
|
+
return async (req, next) => {
|
|
110
|
+
try {
|
|
111
|
+
const data = source === "body" ? req.body : source === "query" ? req.query : req.params;
|
|
112
|
+
const validated = schema.parse(data);
|
|
113
|
+
req[`validated${source.charAt(0).toUpperCase() + source.slice(1)}`] = validated;
|
|
114
|
+
return await next();
|
|
115
|
+
} catch (err) {
|
|
116
|
+
return new Response(JSON.stringify({
|
|
117
|
+
error: "Validation failed",
|
|
118
|
+
details: err.errors || err.message
|
|
119
|
+
}), {
|
|
120
|
+
status: 400,
|
|
121
|
+
headers: { "Content-Type": "application/json" }
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
};
|
|
126
|
+
|
|
2
127
|
// src/prince.ts
|
|
3
128
|
class TrieNode {
|
|
4
129
|
children = Object.create(null);
|
|
@@ -57,6 +182,21 @@ class Prince {
|
|
|
57
182
|
constructor(devMode = false) {
|
|
58
183
|
this.devMode = devMode;
|
|
59
184
|
}
|
|
185
|
+
useCors(options) {
|
|
186
|
+
this.use(cors(options));
|
|
187
|
+
return this;
|
|
188
|
+
}
|
|
189
|
+
useLogger(options) {
|
|
190
|
+
this.use(logger(options));
|
|
191
|
+
return this;
|
|
192
|
+
}
|
|
193
|
+
useRateLimit(options) {
|
|
194
|
+
this.use(rateLimit(options));
|
|
195
|
+
return this;
|
|
196
|
+
}
|
|
197
|
+
validate(schema, source = "body") {
|
|
198
|
+
return validate(schema, source);
|
|
199
|
+
}
|
|
60
200
|
use(mw) {
|
|
61
201
|
this.middlewares.push(mw);
|
|
62
202
|
return this;
|
package/package.json
CHANGED
|
@@ -1,9 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "princejs",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "An easy and fast backend framework — by a 13yo developer, for developers.",
|
|
5
5
|
"main": "dist/prince.js",
|
|
6
6
|
"types": "dist/prince.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"import": "./dist/prince.js",
|
|
10
|
+
"types": "./dist/prince.d.ts"
|
|
11
|
+
},
|
|
12
|
+
"./middleware": {
|
|
13
|
+
"import": "./dist/middleware.js",
|
|
14
|
+
"types": "./dist/middleware.d.ts"
|
|
15
|
+
},
|
|
16
|
+
"./validation": {
|
|
17
|
+
"import": "./dist/validation.js",
|
|
18
|
+
"types": "./dist/validation.d.ts"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
7
21
|
"files": [
|
|
8
22
|
"dist"
|
|
9
23
|
],
|
|
@@ -13,7 +27,10 @@
|
|
|
13
27
|
"framework",
|
|
14
28
|
"bun",
|
|
15
29
|
"easy",
|
|
16
|
-
"princejs"
|
|
30
|
+
"princejs",
|
|
31
|
+
"rest",
|
|
32
|
+
"server",
|
|
33
|
+
"typescript"
|
|
17
34
|
],
|
|
18
35
|
"author": "Matthew Michael (MatthewTheCoder1218)",
|
|
19
36
|
"license": "MIT",
|
|
@@ -23,12 +40,11 @@
|
|
|
23
40
|
},
|
|
24
41
|
"devDependencies": {
|
|
25
42
|
"@types/bun": "^1.3.2",
|
|
26
|
-
"bun-types": "latest"
|
|
27
|
-
|
|
28
|
-
"dependencies": {
|
|
43
|
+
"bun-types": "latest",
|
|
44
|
+
"typescript": "^5.9.3",
|
|
29
45
|
"zod": "^4.1.12"
|
|
30
46
|
},
|
|
31
47
|
"scripts": {
|
|
32
|
-
"build": "bun build
|
|
48
|
+
"build": "bun build src/index.ts --outdir dist --target bun && bun build src/middleware.ts --outdir dist --target bun && bun build src/validation.ts --outdir dist --target bun"
|
|
33
49
|
}
|
|
34
50
|
}
|