princejs 1.9.0 → 1.9.2
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/Readme.md +64 -5
- package/dist/client.d.ts +95 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +99 -0
- package/dist/prince.d.ts +13 -0
- package/dist/prince.d.ts.map +1 -1
- package/dist/prince.js +4 -0
- package/package.json +6 -2
package/Readme.md
CHANGED
|
@@ -53,18 +53,18 @@ app
|
|
|
53
53
|
})));
|
|
54
54
|
```
|
|
55
55
|
|
|
56
|
-
###
|
|
56
|
+
### Middleware
|
|
57
57
|
|
|
58
58
|
* CORS
|
|
59
59
|
* Logger
|
|
60
60
|
* Rate Limiting
|
|
61
61
|
* Static Files
|
|
62
62
|
|
|
63
|
-
###
|
|
63
|
+
### Validation (Zod)
|
|
64
64
|
|
|
65
|
-
###
|
|
65
|
+
### File Uploads
|
|
66
66
|
|
|
67
|
-
###
|
|
67
|
+
### Response Builder
|
|
68
68
|
|
|
69
69
|
### WebSocket Support
|
|
70
70
|
|
|
@@ -78,8 +78,67 @@ app
|
|
|
78
78
|
|
|
79
79
|
### Route-level Middleware
|
|
80
80
|
|
|
81
|
+
### Plugin System
|
|
82
|
+
|
|
83
|
+
You can share bundles of routes and middleware as plugins.
|
|
84
|
+
|
|
85
|
+
```ts
|
|
86
|
+
import { prince, type PrincePlugin } from "princejs";
|
|
87
|
+
|
|
88
|
+
const usersPlugin: PrincePlugin<{ prefix?: string }> = (app, opts) => {
|
|
89
|
+
const base = opts?.prefix ?? "";
|
|
90
|
+
|
|
91
|
+
// plugin-wide middleware
|
|
92
|
+
app.use((req, next) => {
|
|
93
|
+
(req as any).fromPlugin = true;
|
|
94
|
+
return next();
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
// plugin routes
|
|
98
|
+
app.get(`${base}/users`, (req) => ({
|
|
99
|
+
ok: true,
|
|
100
|
+
fromPlugin: (req as any).fromPlugin,
|
|
101
|
+
}));
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
const app = prince();
|
|
105
|
+
app.plugin(usersPlugin, { prefix: "/api" });
|
|
106
|
+
```
|
|
107
|
+
|
|
81
108
|
### Database (SQLite)
|
|
82
109
|
|
|
110
|
+
### End to End Type-Safety
|
|
111
|
+
|
|
112
|
+
PrinceJS supports contract-based type safety to sync your frontend and backend seamlessly. By defining an API contract, your client receives full TypeScript autocompletion and type-checking for routes, parameters, and responses.
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
**Define Your Contract**
|
|
116
|
+
|
|
117
|
+
```ts
|
|
118
|
+
type ApiContract = {
|
|
119
|
+
"GET /users/:id": {
|
|
120
|
+
params: { id: string };
|
|
121
|
+
response: { id: string; name: string };
|
|
122
|
+
};
|
|
123
|
+
"POST /users": {
|
|
124
|
+
body: { name: string };
|
|
125
|
+
response: { id: string; ok: boolean };
|
|
126
|
+
};
|
|
127
|
+
};
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**Initialize The Client**
|
|
131
|
+
|
|
132
|
+
```ts
|
|
133
|
+
import { createClient } from "princejs/client";
|
|
134
|
+
|
|
135
|
+
const client = createClient<ApiContract>("http://localhost:3000");
|
|
136
|
+
|
|
137
|
+
// Fully typed request and response
|
|
138
|
+
const user = await client.get("/users/:id", { params: { id: "42" } });
|
|
139
|
+
console.log(user.name); // Typed as string
|
|
140
|
+
```
|
|
141
|
+
|
|
83
142
|
---
|
|
84
143
|
|
|
85
144
|
## Deploy (Vercel, Workers, Deno)
|
|
@@ -276,4 +335,4 @@ GitHub: [https://github.com/MatthewTheCoder1218/princejs](https://github.com/Mat
|
|
|
276
335
|
|
|
277
336
|
---
|
|
278
337
|
|
|
279
|
-
**PrinceJS: Small in size. Giant in capability. 🚀**
|
|
338
|
+
**PrinceJS: Small in size. Giant in capability. 🚀**
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* princejs/client - End-to-end type-safe API client
|
|
3
|
+
*
|
|
4
|
+
* Define an API contract shared between server and client. The client infers
|
|
5
|
+
* request/response types from the contract—no code generation required.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* // shared/api.ts - Define contract (shared or imported by both server & client)
|
|
9
|
+
* export type ApiContract = {
|
|
10
|
+
* "GET /health": { response: { ok: boolean } };
|
|
11
|
+
* "GET /users/:id": { params: { id: string }; response: { id: string; name: string } };
|
|
12
|
+
* "POST /users": { body: { name: string }; response: { id: string; name: string } };
|
|
13
|
+
* };
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* // client.ts
|
|
17
|
+
* import { createClient } from "princejs/client";
|
|
18
|
+
* import type { ApiContract } from "./shared/api";
|
|
19
|
+
*
|
|
20
|
+
* const client = createClient<ApiContract>("http://localhost:3000");
|
|
21
|
+
*
|
|
22
|
+
* const health = await client.get("/health"); // { ok: boolean }
|
|
23
|
+
* const user = await client.get("/users/:id", { params: { id: "1" } });
|
|
24
|
+
* const created = await client.post("/users", { body: { name: "Alice" } });
|
|
25
|
+
*/
|
|
26
|
+
/** A single route in the API contract. Key format: "METHOD /path/:param" */
|
|
27
|
+
export interface RouteDef {
|
|
28
|
+
/** Path params (e.g. { id: string } for /users/:id) */
|
|
29
|
+
params?: Record<string, string>;
|
|
30
|
+
/** Query params shape (optional, for type hints) */
|
|
31
|
+
query?: Record<string, string>;
|
|
32
|
+
/** Request body for POST/PUT/PATCH */
|
|
33
|
+
body?: unknown;
|
|
34
|
+
/** Response type (default: unknown) */
|
|
35
|
+
response?: unknown;
|
|
36
|
+
}
|
|
37
|
+
/** API contract: maps "METHOD /path" to route definition */
|
|
38
|
+
export type PrinceApiContract = Record<string, RouteDef>;
|
|
39
|
+
type Method = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
40
|
+
/** Extract route keys for a method */
|
|
41
|
+
type KeysForMethod<C extends PrinceApiContract, M extends Method> = Extract<keyof C, `${M} ${string}`>;
|
|
42
|
+
/** Path part from key "GET /users/:id" -> "/users/:id" */
|
|
43
|
+
type PathFromKey<K extends string> = K extends `${Method} ${infer P}` ? P : never;
|
|
44
|
+
/** Route def for a key */
|
|
45
|
+
type DefFor<C extends PrinceApiContract, K extends keyof C> = C[K] extends RouteDef ? C[K] : never;
|
|
46
|
+
/** Response type from route def */
|
|
47
|
+
type ResponseType<D> = D extends {
|
|
48
|
+
response?: infer R;
|
|
49
|
+
} ? R : unknown;
|
|
50
|
+
/** Params type from route def */
|
|
51
|
+
type ParamsType<D> = D extends {
|
|
52
|
+
params?: infer P;
|
|
53
|
+
} ? P : Record<string, never>;
|
|
54
|
+
/** Body type from route def */
|
|
55
|
+
type BodyType<D> = D extends {
|
|
56
|
+
body?: infer B;
|
|
57
|
+
} ? B : undefined;
|
|
58
|
+
/** Options for GET/DELETE (params, query) */
|
|
59
|
+
type GetOpts<D> = ParamsType<D> extends Record<string, never> ? {
|
|
60
|
+
params?: never;
|
|
61
|
+
query?: Record<string, string>;
|
|
62
|
+
} : {
|
|
63
|
+
params: ParamsType<D>;
|
|
64
|
+
query?: Record<string, string>;
|
|
65
|
+
};
|
|
66
|
+
/** Options for POST/PUT/PATCH */
|
|
67
|
+
type MutateOpts<D> = ParamsType<D> extends Record<string, never> ? {
|
|
68
|
+
body: BodyType<D>;
|
|
69
|
+
query?: Record<string, string>;
|
|
70
|
+
} : {
|
|
71
|
+
params: ParamsType<D>;
|
|
72
|
+
body: BodyType<D>;
|
|
73
|
+
query?: Record<string, string>;
|
|
74
|
+
};
|
|
75
|
+
export interface ClientOptions {
|
|
76
|
+
/** Base fetch init (headers, credentials, etc.) */
|
|
77
|
+
init?: RequestInit;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Create an end-to-end type-safe API client from a contract.
|
|
81
|
+
* Share the contract type between server and client for full type safety.
|
|
82
|
+
*/
|
|
83
|
+
export declare function createClient<C extends PrinceApiContract>(baseUrl: string, options?: ClientOptions): PrinceClient<C>;
|
|
84
|
+
/** Typed client interface */
|
|
85
|
+
export interface PrinceClient<C extends PrinceApiContract> {
|
|
86
|
+
get<K extends KeysForMethod<C, "GET">>(path: PathFromKey<K>, opts?: GetOpts<DefFor<C, K>>): Promise<ResponseType<DefFor<C, K>>>;
|
|
87
|
+
post<K extends KeysForMethod<C, "POST">>(path: PathFromKey<K>, opts: MutateOpts<DefFor<C, K>>): Promise<ResponseType<DefFor<C, K>>>;
|
|
88
|
+
put<K extends KeysForMethod<C, "PUT">>(path: PathFromKey<K>, opts: MutateOpts<DefFor<C, K>>): Promise<ResponseType<DefFor<C, K>>>;
|
|
89
|
+
patch<K extends KeysForMethod<C, "PATCH">>(path: PathFromKey<K>, opts: MutateOpts<DefFor<C, K>>): Promise<ResponseType<DefFor<C, K>>>;
|
|
90
|
+
delete<K extends KeysForMethod<C, "DELETE">>(path: PathFromKey<K>, opts?: GetOpts<DefFor<C, K>>): Promise<ResponseType<DefFor<C, K>>>;
|
|
91
|
+
/** Raw fetch (untyped) for custom requests */
|
|
92
|
+
fetch(path: string, init?: RequestInit): Promise<Response>;
|
|
93
|
+
}
|
|
94
|
+
export {};
|
|
95
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
// src/client.ts
|
|
2
|
+
function buildPath(pattern, params) {
|
|
3
|
+
if (!params)
|
|
4
|
+
return pattern;
|
|
5
|
+
let out = pattern;
|
|
6
|
+
for (const [k, v] of Object.entries(params)) {
|
|
7
|
+
out = out.replace(`:${k}`, encodeURIComponent(v));
|
|
8
|
+
}
|
|
9
|
+
return out;
|
|
10
|
+
}
|
|
11
|
+
function buildUrl(base, path, query) {
|
|
12
|
+
const url = new URL(path, base);
|
|
13
|
+
if (query) {
|
|
14
|
+
for (const [k, v] of Object.entries(query)) {
|
|
15
|
+
url.searchParams.set(k, v);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return url.toString();
|
|
19
|
+
}
|
|
20
|
+
async function fetchJson(url, init) {
|
|
21
|
+
const res = await fetch(url, {
|
|
22
|
+
...init,
|
|
23
|
+
headers: {
|
|
24
|
+
"Content-Type": "application/json",
|
|
25
|
+
...init?.headers
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
if (!res.ok) {
|
|
29
|
+
const text = await res.text();
|
|
30
|
+
throw new Error(`API error ${res.status}: ${text}`);
|
|
31
|
+
}
|
|
32
|
+
return res.json();
|
|
33
|
+
}
|
|
34
|
+
function createClient(baseUrl, options) {
|
|
35
|
+
const base = baseUrl.replace(/\/$/, "");
|
|
36
|
+
const init = options?.init ?? {};
|
|
37
|
+
const get = async (path, opts) => {
|
|
38
|
+
const def = {};
|
|
39
|
+
const params = opts && "params" in opts ? opts.params : undefined;
|
|
40
|
+
const query = opts?.query;
|
|
41
|
+
const builtPath = buildPath(path, params);
|
|
42
|
+
const url = buildUrl(base, builtPath, query);
|
|
43
|
+
return fetchJson(url, init);
|
|
44
|
+
};
|
|
45
|
+
const post = async (path, opts) => {
|
|
46
|
+
const params = opts && "params" in opts ? opts.params : undefined;
|
|
47
|
+
const body = opts && "body" in opts ? opts.body : undefined;
|
|
48
|
+
const query = opts?.query;
|
|
49
|
+
const builtPath = buildPath(path, params);
|
|
50
|
+
const url = buildUrl(base, builtPath, query);
|
|
51
|
+
return fetchJson(url, {
|
|
52
|
+
...init,
|
|
53
|
+
method: "POST",
|
|
54
|
+
body: body !== undefined ? JSON.stringify(body) : undefined
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
const put = async (path, opts) => {
|
|
58
|
+
const params = opts && "params" in opts ? opts.params : undefined;
|
|
59
|
+
const body = opts && "body" in opts ? opts.body : undefined;
|
|
60
|
+
const query = opts?.query;
|
|
61
|
+
const builtPath = buildPath(path, params);
|
|
62
|
+
const url = buildUrl(base, builtPath, query);
|
|
63
|
+
return fetchJson(url, {
|
|
64
|
+
...init,
|
|
65
|
+
method: "PUT",
|
|
66
|
+
body: body !== undefined ? JSON.stringify(body) : undefined
|
|
67
|
+
});
|
|
68
|
+
};
|
|
69
|
+
const patch = async (path, opts) => {
|
|
70
|
+
const params = opts && "params" in opts ? opts.params : undefined;
|
|
71
|
+
const body = opts && "body" in opts ? opts.body : undefined;
|
|
72
|
+
const query = opts?.query;
|
|
73
|
+
const builtPath = buildPath(path, params);
|
|
74
|
+
const url = buildUrl(base, builtPath, query);
|
|
75
|
+
return fetchJson(url, {
|
|
76
|
+
...init,
|
|
77
|
+
method: "PATCH",
|
|
78
|
+
body: body !== undefined ? JSON.stringify(body) : undefined
|
|
79
|
+
});
|
|
80
|
+
};
|
|
81
|
+
const del = async (path, opts) => {
|
|
82
|
+
const params = opts && opts.params ? opts.params : undefined;
|
|
83
|
+
const query = opts?.query;
|
|
84
|
+
const builtPath = buildPath(path, params);
|
|
85
|
+
const url = buildUrl(base, builtPath, query);
|
|
86
|
+
return fetchJson(url, { ...init, method: "DELETE" });
|
|
87
|
+
};
|
|
88
|
+
return {
|
|
89
|
+
get,
|
|
90
|
+
post,
|
|
91
|
+
put,
|
|
92
|
+
patch,
|
|
93
|
+
delete: del,
|
|
94
|
+
fetch: (path, reqInit) => globalThis.fetch(`${base}${path}`, { ...init, ...reqInit })
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
export {
|
|
98
|
+
createClient
|
|
99
|
+
};
|
package/dist/prince.d.ts
CHANGED
|
@@ -19,6 +19,7 @@ interface WebSocketHandler {
|
|
|
19
19
|
drain?: (ws: any) => void;
|
|
20
20
|
}
|
|
21
21
|
type RouteHandler = (req: PrinceRequest) => Promise<HandlerResult> | HandlerResult;
|
|
22
|
+
export type PrincePlugin<TOptions = any> = (app: Prince, options?: TOptions) => void | Promise<void>;
|
|
22
23
|
declare class ResponseBuilder {
|
|
23
24
|
private _status;
|
|
24
25
|
private _headers;
|
|
@@ -44,6 +45,18 @@ export declare class Prince {
|
|
|
44
45
|
private routeCache;
|
|
45
46
|
constructor(devMode?: boolean);
|
|
46
47
|
use(mw: Middleware): this;
|
|
48
|
+
/**
|
|
49
|
+
* Lightweight plugin system: allows sharing bundles of routes/middleware.
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* const usersPlugin: PrincePlugin<{ prefix?: string }> = (app, opts) => {
|
|
53
|
+
* const base = opts?.prefix ?? "";
|
|
54
|
+
* app.get(`${base}/users`, () => [{ id: 1 }]);
|
|
55
|
+
* };
|
|
56
|
+
*
|
|
57
|
+
* app.plugin(usersPlugin, { prefix: "/api" });
|
|
58
|
+
*/
|
|
59
|
+
plugin<TOptions = any>(plugin: PrincePlugin<TOptions>, options?: TOptions): this;
|
|
47
60
|
error(fn: (err: any, req: PrinceRequest) => Response): this;
|
|
48
61
|
json(data: any, status?: number): Response;
|
|
49
62
|
response(): ResponseBuilder;
|
package/dist/prince.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prince.d.ts","sourceRoot":"","sources":["../src/prince.ts"],"names":[],"mappings":"AAIA,KAAK,IAAI,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,CAAC;AACpC,KAAK,UAAU,GAAG,CAAC,GAAG,EAAE,aAAa,EAAE,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,GAAG,QAAQ,GAAG,SAAS,CAAC;AAC3G,KAAK,aAAa,GAAG,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,GAAG,UAAU,CAAC;AAE1E,MAAM,WAAW,aAAc,SAAQ,OAAO;IAC5C,UAAU,CAAC,EAAE,GAAG,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC7B,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3D,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,UAAU,gBAAgB;IACxB,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,GAAG,KAAK,IAAI,CAAC;IACzB,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,KAAK,IAAI,CAAC;IAClD,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1D,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,GAAG,KAAK,IAAI,CAAC;CAC3B;AAED,KAAK,YAAY,GAAG,CAAC,GAAG,EAAE,aAAa,KAAK,OAAO,CAAC,aAAa,CAAC,GAAG,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"prince.d.ts","sourceRoot":"","sources":["../src/prince.ts"],"names":[],"mappings":"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"}
|
package/dist/prince.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "princejs",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.2",
|
|
4
4
|
"description": "An easy and fast backend framework that is among the top three — by a 13yo developer, for developers.",
|
|
5
5
|
"main": "dist/prince.js",
|
|
6
6
|
"types": "dist/prince.d.ts",
|
|
@@ -44,6 +44,10 @@
|
|
|
44
44
|
"./deno": {
|
|
45
45
|
"import": "./dist/adapters/deno.js",
|
|
46
46
|
"types": "./dist/adapters/deno.d.ts"
|
|
47
|
+
},
|
|
48
|
+
"./client": {
|
|
49
|
+
"import": "./dist/client.js",
|
|
50
|
+
"types": "./dist/client.d.ts"
|
|
47
51
|
}
|
|
48
52
|
},
|
|
49
53
|
"files": [
|
|
@@ -107,7 +111,7 @@
|
|
|
107
111
|
"jose": "^6.1.2"
|
|
108
112
|
},
|
|
109
113
|
"scripts": {
|
|
110
|
-
"build:js": "bun build src/prince.ts --outdir dist --target bun && bun build src/middleware.ts --outdir dist --target bun && bun build src/helpers.ts --outdir dist --target bun && bun build src/scheduler.ts --outdir dist --target bun && bun build bin/create.ts --outdir dist --target bun && bun build src/jsx.ts --outdir dist --target bun && bun build src/db.ts --outdir dist --target bun --format esm && bun build src/adapters/vercel.ts --outdir dist/adapters --format esm && bun build src/adapters/cloudflare.ts --outdir dist/adapters --format esm && bun build src/adapters/deno.ts --outdir dist/adapters --format esm",
|
|
114
|
+
"build:js": "bun build src/prince.ts --outdir dist --target bun && bun build src/middleware.ts --outdir dist --target bun && bun build src/helpers.ts --outdir dist --target bun && bun build src/scheduler.ts --outdir dist --target bun && bun build bin/create.ts --outdir dist --target bun && bun build src/jsx.ts --outdir dist --target bun && bun build src/db.ts --outdir dist --target bun --format esm && bun build src/client.ts --outdir dist --format esm && bun build src/adapters/vercel.ts --outdir dist/adapters --format esm && bun build src/adapters/cloudflare.ts --outdir dist/adapters --format esm && bun build src/adapters/deno.ts --outdir dist/adapters --format esm",
|
|
111
115
|
"build:types": "tsc --emitDeclarationOnly --skipLibCheck",
|
|
112
116
|
"build": "bun run build:js && bun run build:types",
|
|
113
117
|
"test": "bun test",
|