princejs 2.0.0 → 2.1.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/README.md CHANGED
@@ -63,6 +63,7 @@ app.listen(3000);
63
63
  | Routing | `princejs` |
64
64
  | Middleware (CORS, Logger, Rate Limit, Auth, JWT) | `princejs/middleware` |
65
65
  | Zod Validation | `princejs/middleware` |
66
+ | **Cookies & IP Detection** | `princejs` |
66
67
  | File Uploads | `princejs/helpers` |
67
68
  | WebSockets | `princejs` |
68
69
  | Server-Sent Events | `princejs/helpers` |
@@ -80,6 +81,91 @@ app.listen(3000);
80
81
 
81
82
  ---
82
83
 
84
+ ## 🍪 Cookies & 🌐 IP Detection
85
+
86
+ ### Reading Cookies
87
+
88
+ Cookies are automatically parsed from the request:
89
+
90
+ ```ts
91
+ app.get("/profile", (req) => ({
92
+ sessionId: req.cookies?.sessionId,
93
+ theme: req.cookies?.theme,
94
+ allCookies: req.cookies // Record<string, string>
95
+ }));
96
+ ```
97
+
98
+ ### Setting Cookies
99
+
100
+ Use the response builder to set cookies with full control:
101
+
102
+ ```ts
103
+ app.get("/login", (req) =>
104
+ app.response()
105
+ .status(200)
106
+ .json({ ok: true })
107
+ .cookie("sessionId", "abc123", {
108
+ maxAge: 3600, // 1 hour
109
+ path: "/",
110
+ httpOnly: true, // not accessible from JS
111
+ secure: true, // HTTPS only
112
+ sameSite: "Strict" // CSRF protection
113
+ })
114
+ );
115
+
116
+ // Chain multiple cookies
117
+ app.response()
118
+ .json({ ok: true })
119
+ .cookie("session", "xyz")
120
+ .cookie("theme", "dark")
121
+ .cookie("lang", "en");
122
+ ```
123
+
124
+ ### Client IP Detection
125
+
126
+ Automatically detect client IP from request headers:
127
+
128
+ ```ts
129
+ app.get("/api/data", (req) => ({
130
+ clientIp: req.ip,
131
+ data: [...]
132
+ }));
133
+ ```
134
+
135
+ **Supported headers** (in priority order):
136
+ - `X-Forwarded-For` — Load balancers, proxies (first IP in list)
137
+ - `X-Real-IP` — Nginx, Apache reverse proxy
138
+ - `CF-Connecting-IP` — Cloudflare
139
+ - `X-Client-IP` — Other proxy services
140
+ - Fallback — `127.0.0.1` (localhost)
141
+
142
+ **Use cases:**
143
+ - 🔒 Rate limiting per IP
144
+ - 📊 Geolocation analytics
145
+ - 🚨 IP-based access control
146
+ - 👥 User tracking & fraud detection
147
+
148
+ ```ts
149
+ // Rate limit by IP
150
+ app.use((req, next) => {
151
+ const ip = req.ip;
152
+ const count = ipTracker.getCount(ip) || 0;
153
+ if (count > 100) return new Response("Too many requests", { status: 429 });
154
+ ipTracker.increment(ip);
155
+ return next();
156
+ });
157
+
158
+ // IP-based security
159
+ app.post("/admin", (req) => {
160
+ if (!ALLOWED_IPS.includes(req.ip!)) {
161
+ return new Response("Forbidden", { status: 403 });
162
+ }
163
+ return { authorized: true };
164
+ });
165
+ ```
166
+
167
+ ---
168
+
83
169
  ## 📖 OpenAPI + Scalar Docs ✨
84
170
 
85
171
  Auto-generate an OpenAPI 3.0 spec and serve a beautiful [Scalar](https://scalar.com) UI — all from a single `app.openapi()` call. Routes, validation, and docs stay in sync automatically.
@@ -330,6 +416,23 @@ app.use(compress());
330
416
  const Page = () => Html(Head("Test Page"), Body(H1("Hello World"), P("This is a test")));
331
417
  app.get("/jsx", () => render(Page()));
332
418
 
419
+ // Cookies & IP Detection
420
+ app.post("/login", (req) =>
421
+ app.response()
422
+ .json({ ok: true, ip: req.ip })
423
+ .cookie("sessionId", "user_123", {
424
+ httpOnly: true,
425
+ secure: true,
426
+ sameSite: "Strict",
427
+ maxAge: 86400 // 24 hours
428
+ })
429
+ );
430
+
431
+ app.get("/profile", (req) => ({
432
+ sessionId: req.cookies?.sessionId,
433
+ clientIp: req.ip,
434
+ }));
435
+
333
436
  // Database
334
437
  const users = db.sqlite("./db.sqlite", "CREATE TABLE users...");
335
438
  app.get("/users", () => users.query("SELECT * FROM users"));
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- // node_modules/jose/dist/webapi/lib/buffer_utils.js
2
+ // node_modules/.pnpm/jose@6.2.1/node_modules/jose/dist/webapi/lib/buffer_utils.js
3
3
  var encoder = new TextEncoder;
4
4
  var decoder = new TextDecoder;
5
5
  var MAX_INT32 = 2 ** 32;
@@ -25,7 +25,7 @@ function encode(string) {
25
25
  return bytes;
26
26
  }
27
27
 
28
- // node_modules/jose/dist/webapi/lib/base64.js
28
+ // node_modules/.pnpm/jose@6.2.1/node_modules/jose/dist/webapi/lib/base64.js
29
29
  function encodeBase64(input) {
30
30
  if (Uint8Array.prototype.toBase64) {
31
31
  return input.toBase64();
@@ -49,7 +49,7 @@ function decodeBase64(encoded) {
49
49
  return bytes;
50
50
  }
51
51
 
52
- // node_modules/jose/dist/webapi/util/base64url.js
52
+ // node_modules/.pnpm/jose@6.2.1/node_modules/jose/dist/webapi/util/base64url.js
53
53
  function decode(input) {
54
54
  if (Uint8Array.fromBase64) {
55
55
  return Uint8Array.fromBase64(typeof input === "string" ? input : decoder.decode(input), {
@@ -78,77 +78,17 @@ function encode2(input) {
78
78
  return encodeBase64(unencoded).replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
79
79
  }
80
80
 
81
- // node_modules/jose/dist/webapi/util/errors.js
82
- class JOSEError extends Error {
83
- static code = "ERR_JOSE_GENERIC";
84
- code = "ERR_JOSE_GENERIC";
85
- constructor(message, options) {
86
- super(message, options);
87
- this.name = this.constructor.name;
88
- Error.captureStackTrace?.(this, this.constructor);
89
- }
90
- }
91
-
92
- class JWTClaimValidationFailed extends JOSEError {
93
- static code = "ERR_JWT_CLAIM_VALIDATION_FAILED";
94
- code = "ERR_JWT_CLAIM_VALIDATION_FAILED";
95
- claim;
96
- reason;
97
- payload;
98
- constructor(message, payload, claim = "unspecified", reason = "unspecified") {
99
- super(message, { cause: { claim, reason, payload } });
100
- this.claim = claim;
101
- this.reason = reason;
102
- this.payload = payload;
103
- }
104
- }
105
-
106
- class JWTExpired extends JOSEError {
107
- static code = "ERR_JWT_EXPIRED";
108
- code = "ERR_JWT_EXPIRED";
109
- claim;
110
- reason;
111
- payload;
112
- constructor(message, payload, claim = "unspecified", reason = "unspecified") {
113
- super(message, { cause: { claim, reason, payload } });
114
- this.claim = claim;
115
- this.reason = reason;
116
- this.payload = payload;
117
- }
118
- }
119
-
120
- class JOSEAlgNotAllowed extends JOSEError {
121
- static code = "ERR_JOSE_ALG_NOT_ALLOWED";
122
- code = "ERR_JOSE_ALG_NOT_ALLOWED";
123
- }
124
-
125
- class JOSENotSupported extends JOSEError {
126
- static code = "ERR_JOSE_NOT_SUPPORTED";
127
- code = "ERR_JOSE_NOT_SUPPORTED";
128
- }
129
- class JWSInvalid extends JOSEError {
130
- static code = "ERR_JWS_INVALID";
131
- code = "ERR_JWS_INVALID";
132
- }
133
-
134
- class JWTInvalid extends JOSEError {
135
- static code = "ERR_JWT_INVALID";
136
- code = "ERR_JWT_INVALID";
137
- }
138
- class JWSSignatureVerificationFailed extends JOSEError {
139
- static code = "ERR_JWS_SIGNATURE_VERIFICATION_FAILED";
140
- code = "ERR_JWS_SIGNATURE_VERIFICATION_FAILED";
141
- constructor(message = "signature verification failed", options) {
142
- super(message, options);
143
- }
144
- }
145
-
146
- // node_modules/jose/dist/webapi/lib/crypto_key.js
81
+ // node_modules/.pnpm/jose@6.2.1/node_modules/jose/dist/webapi/lib/crypto_key.js
147
82
  var unusable = (name, prop = "algorithm.name") => new TypeError(`CryptoKey does not support this operation, its ${prop} must be ${name}`);
148
83
  var isAlgorithm = (algorithm, name) => algorithm.name === name;
149
84
  function getHashLength(hash) {
150
85
  return parseInt(hash.name.slice(4), 10);
151
86
  }
87
+ function checkHashLength(algorithm, expected) {
88
+ const actual = getHashLength(algorithm.hash);
89
+ if (actual !== expected)
90
+ throw unusable(`SHA-${expected}`, "algorithm.hash");
91
+ }
152
92
  function getNamedCurve(alg) {
153
93
  switch (alg) {
154
94
  case "ES256":
@@ -173,10 +113,7 @@ function checkSigCryptoKey(key, alg, usage) {
173
113
  case "HS512": {
174
114
  if (!isAlgorithm(key.algorithm, "HMAC"))
175
115
  throw unusable("HMAC");
176
- const expected = parseInt(alg.slice(2), 10);
177
- const actual = getHashLength(key.algorithm.hash);
178
- if (actual !== expected)
179
- throw unusable(`SHA-${expected}`, "algorithm.hash");
116
+ checkHashLength(key.algorithm, parseInt(alg.slice(2), 10));
180
117
  break;
181
118
  }
182
119
  case "RS256":
@@ -184,10 +121,7 @@ function checkSigCryptoKey(key, alg, usage) {
184
121
  case "RS512": {
185
122
  if (!isAlgorithm(key.algorithm, "RSASSA-PKCS1-v1_5"))
186
123
  throw unusable("RSASSA-PKCS1-v1_5");
187
- const expected = parseInt(alg.slice(2), 10);
188
- const actual = getHashLength(key.algorithm.hash);
189
- if (actual !== expected)
190
- throw unusable(`SHA-${expected}`, "algorithm.hash");
124
+ checkHashLength(key.algorithm, parseInt(alg.slice(2), 10));
191
125
  break;
192
126
  }
193
127
  case "PS256":
@@ -195,10 +129,7 @@ function checkSigCryptoKey(key, alg, usage) {
195
129
  case "PS512": {
196
130
  if (!isAlgorithm(key.algorithm, "RSA-PSS"))
197
131
  throw unusable("RSA-PSS");
198
- const expected = parseInt(alg.slice(2), 10);
199
- const actual = getHashLength(key.algorithm.hash);
200
- if (actual !== expected)
201
- throw unusable(`SHA-${expected}`, "algorithm.hash");
132
+ checkHashLength(key.algorithm, parseInt(alg.slice(2), 10));
202
133
  break;
203
134
  }
204
135
  case "Ed25519":
@@ -231,7 +162,7 @@ function checkSigCryptoKey(key, alg, usage) {
231
162
  checkUsage(key, usage);
232
163
  }
233
164
 
234
- // node_modules/jose/dist/webapi/lib/invalid_key_input.js
165
+ // node_modules/.pnpm/jose@6.2.1/node_modules/jose/dist/webapi/lib/invalid_key_input.js
235
166
  function message(msg, actual, ...types) {
236
167
  types = types.filter(Boolean);
237
168
  if (types.length > 2) {
@@ -256,7 +187,72 @@ function message(msg, actual, ...types) {
256
187
  var invalidKeyInput = (actual, ...types) => message("Key must be ", actual, ...types);
257
188
  var withAlg = (alg, actual, ...types) => message(`Key for the ${alg} algorithm must be `, actual, ...types);
258
189
 
259
- // node_modules/jose/dist/webapi/lib/is_key_like.js
190
+ // node_modules/.pnpm/jose@6.2.1/node_modules/jose/dist/webapi/util/errors.js
191
+ class JOSEError extends Error {
192
+ static code = "ERR_JOSE_GENERIC";
193
+ code = "ERR_JOSE_GENERIC";
194
+ constructor(message2, options) {
195
+ super(message2, options);
196
+ this.name = this.constructor.name;
197
+ Error.captureStackTrace?.(this, this.constructor);
198
+ }
199
+ }
200
+
201
+ class JWTClaimValidationFailed extends JOSEError {
202
+ static code = "ERR_JWT_CLAIM_VALIDATION_FAILED";
203
+ code = "ERR_JWT_CLAIM_VALIDATION_FAILED";
204
+ claim;
205
+ reason;
206
+ payload;
207
+ constructor(message2, payload, claim = "unspecified", reason = "unspecified") {
208
+ super(message2, { cause: { claim, reason, payload } });
209
+ this.claim = claim;
210
+ this.reason = reason;
211
+ this.payload = payload;
212
+ }
213
+ }
214
+
215
+ class JWTExpired extends JOSEError {
216
+ static code = "ERR_JWT_EXPIRED";
217
+ code = "ERR_JWT_EXPIRED";
218
+ claim;
219
+ reason;
220
+ payload;
221
+ constructor(message2, payload, claim = "unspecified", reason = "unspecified") {
222
+ super(message2, { cause: { claim, reason, payload } });
223
+ this.claim = claim;
224
+ this.reason = reason;
225
+ this.payload = payload;
226
+ }
227
+ }
228
+
229
+ class JOSEAlgNotAllowed extends JOSEError {
230
+ static code = "ERR_JOSE_ALG_NOT_ALLOWED";
231
+ code = "ERR_JOSE_ALG_NOT_ALLOWED";
232
+ }
233
+
234
+ class JOSENotSupported extends JOSEError {
235
+ static code = "ERR_JOSE_NOT_SUPPORTED";
236
+ code = "ERR_JOSE_NOT_SUPPORTED";
237
+ }
238
+ class JWSInvalid extends JOSEError {
239
+ static code = "ERR_JWS_INVALID";
240
+ code = "ERR_JWS_INVALID";
241
+ }
242
+
243
+ class JWTInvalid extends JOSEError {
244
+ static code = "ERR_JWT_INVALID";
245
+ code = "ERR_JWT_INVALID";
246
+ }
247
+ class JWSSignatureVerificationFailed extends JOSEError {
248
+ static code = "ERR_JWS_SIGNATURE_VERIFICATION_FAILED";
249
+ code = "ERR_JWS_SIGNATURE_VERIFICATION_FAILED";
250
+ constructor(message2 = "signature verification failed", options) {
251
+ super(message2, options);
252
+ }
253
+ }
254
+
255
+ // node_modules/.pnpm/jose@6.2.1/node_modules/jose/dist/webapi/lib/is_key_like.js
260
256
  var isCryptoKey = (key) => {
261
257
  if (key?.[Symbol.toStringTag] === "CryptoKey")
262
258
  return true;
@@ -269,7 +265,36 @@ var isCryptoKey = (key) => {
269
265
  var isKeyObject = (key) => key?.[Symbol.toStringTag] === "KeyObject";
270
266
  var isKeyLike = (key) => isCryptoKey(key) || isKeyObject(key);
271
267
 
272
- // node_modules/jose/dist/webapi/lib/is_disjoint.js
268
+ // node_modules/.pnpm/jose@6.2.1/node_modules/jose/dist/webapi/lib/helpers.js
269
+ var unprotected = Symbol();
270
+ function assertNotSet(value, name) {
271
+ if (value) {
272
+ throw new TypeError(`${name} can only be called once`);
273
+ }
274
+ }
275
+ function decodeBase64url(value, label, ErrorClass) {
276
+ try {
277
+ return decode(value);
278
+ } catch {
279
+ throw new ErrorClass(`Failed to base64url decode the ${label}`);
280
+ }
281
+ }
282
+
283
+ // node_modules/.pnpm/jose@6.2.1/node_modules/jose/dist/webapi/lib/type_checks.js
284
+ var isObjectLike = (value) => typeof value === "object" && value !== null;
285
+ function isObject(input) {
286
+ if (!isObjectLike(input) || Object.prototype.toString.call(input) !== "[object Object]") {
287
+ return false;
288
+ }
289
+ if (Object.getPrototypeOf(input) === null) {
290
+ return true;
291
+ }
292
+ let proto = input;
293
+ while (Object.getPrototypeOf(proto) !== null) {
294
+ proto = Object.getPrototypeOf(proto);
295
+ }
296
+ return Object.getPrototypeOf(input) === proto;
297
+ }
273
298
  function isDisjoint(...headers) {
274
299
  const sources = headers.filter(Boolean);
275
300
  if (sources.length === 0 || sources.length === 1) {
@@ -291,24 +316,12 @@ function isDisjoint(...headers) {
291
316
  }
292
317
  return true;
293
318
  }
319
+ var isJWK = (key) => isObject(key) && typeof key.kty === "string";
320
+ var isPrivateJWK = (key) => key.kty !== "oct" && (key.kty === "AKP" && typeof key.priv === "string" || typeof key.d === "string");
321
+ var isPublicJWK = (key) => key.kty !== "oct" && key.d === undefined && key.priv === undefined;
322
+ var isSecretJWK = (key) => key.kty === "oct" && typeof key.k === "string";
294
323
 
295
- // node_modules/jose/dist/webapi/lib/is_object.js
296
- var isObjectLike = (value) => typeof value === "object" && value !== null;
297
- function isObject(input) {
298
- if (!isObjectLike(input) || Object.prototype.toString.call(input) !== "[object Object]") {
299
- return false;
300
- }
301
- if (Object.getPrototypeOf(input) === null) {
302
- return true;
303
- }
304
- let proto = input;
305
- while (Object.getPrototypeOf(proto) !== null) {
306
- proto = Object.getPrototypeOf(proto);
307
- }
308
- return Object.getPrototypeOf(input) === proto;
309
- }
310
-
311
- // node_modules/jose/dist/webapi/lib/check_key_length.js
324
+ // node_modules/.pnpm/jose@6.2.1/node_modules/jose/dist/webapi/lib/signing.js
312
325
  function checkKeyLength(alg, key) {
313
326
  if (alg.startsWith("RS") || alg.startsWith("PS")) {
314
327
  const { modulusLength } = key.algorithm;
@@ -317,8 +330,65 @@ function checkKeyLength(alg, key) {
317
330
  }
318
331
  }
319
332
  }
333
+ function subtleAlgorithm(alg, algorithm) {
334
+ const hash = `SHA-${alg.slice(-3)}`;
335
+ switch (alg) {
336
+ case "HS256":
337
+ case "HS384":
338
+ case "HS512":
339
+ return { hash, name: "HMAC" };
340
+ case "PS256":
341
+ case "PS384":
342
+ case "PS512":
343
+ return { hash, name: "RSA-PSS", saltLength: parseInt(alg.slice(-3), 10) >> 3 };
344
+ case "RS256":
345
+ case "RS384":
346
+ case "RS512":
347
+ return { hash, name: "RSASSA-PKCS1-v1_5" };
348
+ case "ES256":
349
+ case "ES384":
350
+ case "ES512":
351
+ return { hash, name: "ECDSA", namedCurve: algorithm.namedCurve };
352
+ case "Ed25519":
353
+ case "EdDSA":
354
+ return { name: "Ed25519" };
355
+ case "ML-DSA-44":
356
+ case "ML-DSA-65":
357
+ case "ML-DSA-87":
358
+ return { name: alg };
359
+ default:
360
+ throw new JOSENotSupported(`alg ${alg} is not supported either by JOSE or your javascript runtime`);
361
+ }
362
+ }
363
+ async function getSigKey(alg, key, usage) {
364
+ if (key instanceof Uint8Array) {
365
+ if (!alg.startsWith("HS")) {
366
+ throw new TypeError(invalidKeyInput(key, "CryptoKey", "KeyObject", "JSON Web Key"));
367
+ }
368
+ return crypto.subtle.importKey("raw", key, { hash: `SHA-${alg.slice(-3)}`, name: "HMAC" }, false, [usage]);
369
+ }
370
+ checkSigCryptoKey(key, alg, usage);
371
+ return key;
372
+ }
373
+ async function sign(alg, key, data) {
374
+ const cryptoKey = await getSigKey(alg, key, "sign");
375
+ checkKeyLength(alg, cryptoKey);
376
+ const signature = await crypto.subtle.sign(subtleAlgorithm(alg, cryptoKey.algorithm), cryptoKey, data);
377
+ return new Uint8Array(signature);
378
+ }
379
+ async function verify(alg, key, signature, data) {
380
+ const cryptoKey = await getSigKey(alg, key, "verify");
381
+ checkKeyLength(alg, cryptoKey);
382
+ const algorithm = subtleAlgorithm(alg, cryptoKey.algorithm);
383
+ try {
384
+ return await crypto.subtle.verify(algorithm, cryptoKey, signature, data);
385
+ } catch {
386
+ return false;
387
+ }
388
+ }
320
389
 
321
- // node_modules/jose/dist/webapi/lib/jwk_to_key.js
390
+ // node_modules/.pnpm/jose@6.2.1/node_modules/jose/dist/webapi/lib/jwk_to_key.js
391
+ var unsupportedAlg = 'Invalid or unsupported JWK "alg" (Algorithm) Parameter value';
322
392
  function subtleMapping(jwk) {
323
393
  let algorithm;
324
394
  let keyUsages;
@@ -332,7 +402,7 @@ function subtleMapping(jwk) {
332
402
  keyUsages = jwk.priv ? ["sign"] : ["verify"];
333
403
  break;
334
404
  default:
335
- throw new JOSENotSupported('Invalid or unsupported JWK "alg" (Algorithm) Parameter value');
405
+ throw new JOSENotSupported(unsupportedAlg);
336
406
  }
337
407
  break;
338
408
  }
@@ -361,22 +431,19 @@ function subtleMapping(jwk) {
361
431
  keyUsages = jwk.d ? ["decrypt", "unwrapKey"] : ["encrypt", "wrapKey"];
362
432
  break;
363
433
  default:
364
- throw new JOSENotSupported('Invalid or unsupported JWK "alg" (Algorithm) Parameter value');
434
+ throw new JOSENotSupported(unsupportedAlg);
365
435
  }
366
436
  break;
367
437
  }
368
438
  case "EC": {
369
439
  switch (jwk.alg) {
370
440
  case "ES256":
371
- algorithm = { name: "ECDSA", namedCurve: "P-256" };
372
- keyUsages = jwk.d ? ["sign"] : ["verify"];
373
- break;
374
441
  case "ES384":
375
- algorithm = { name: "ECDSA", namedCurve: "P-384" };
376
- keyUsages = jwk.d ? ["sign"] : ["verify"];
377
- break;
378
442
  case "ES512":
379
- algorithm = { name: "ECDSA", namedCurve: "P-521" };
443
+ algorithm = {
444
+ name: "ECDSA",
445
+ namedCurve: { ES256: "P-256", ES384: "P-384", ES512: "P-521" }[jwk.alg]
446
+ };
380
447
  keyUsages = jwk.d ? ["sign"] : ["verify"];
381
448
  break;
382
449
  case "ECDH-ES":
@@ -387,7 +454,7 @@ function subtleMapping(jwk) {
387
454
  keyUsages = jwk.d ? ["deriveBits"] : [];
388
455
  break;
389
456
  default:
390
- throw new JOSENotSupported('Invalid or unsupported JWK "alg" (Algorithm) Parameter value');
457
+ throw new JOSENotSupported(unsupportedAlg);
391
458
  }
392
459
  break;
393
460
  }
@@ -406,7 +473,7 @@ function subtleMapping(jwk) {
406
473
  keyUsages = jwk.d ? ["deriveBits"] : [];
407
474
  break;
408
475
  default:
409
- throw new JOSENotSupported('Invalid or unsupported JWK "alg" (Algorithm) Parameter value');
476
+ throw new JOSENotSupported(unsupportedAlg);
410
477
  }
411
478
  break;
412
479
  }
@@ -428,55 +495,8 @@ async function jwkToKey(jwk) {
428
495
  return crypto.subtle.importKey("jwk", keyData, algorithm, jwk.ext ?? (jwk.d || jwk.priv ? false : true), jwk.key_ops ?? keyUsages);
429
496
  }
430
497
 
431
- // node_modules/jose/dist/webapi/lib/validate_crit.js
432
- function validateCrit(Err, recognizedDefault, recognizedOption, protectedHeader, joseHeader) {
433
- if (joseHeader.crit !== undefined && protectedHeader?.crit === undefined) {
434
- throw new Err('"crit" (Critical) Header Parameter MUST be integrity protected');
435
- }
436
- if (!protectedHeader || protectedHeader.crit === undefined) {
437
- return new Set;
438
- }
439
- if (!Array.isArray(protectedHeader.crit) || protectedHeader.crit.length === 0 || protectedHeader.crit.some((input) => typeof input !== "string" || input.length === 0)) {
440
- throw new Err('"crit" (Critical) Header Parameter MUST be an array of non-empty strings when present');
441
- }
442
- let recognized;
443
- if (recognizedOption !== undefined) {
444
- recognized = new Map([...Object.entries(recognizedOption), ...recognizedDefault.entries()]);
445
- } else {
446
- recognized = recognizedDefault;
447
- }
448
- for (const parameter of protectedHeader.crit) {
449
- if (!recognized.has(parameter)) {
450
- throw new JOSENotSupported(`Extension Header Parameter "${parameter}" is not recognized`);
451
- }
452
- if (joseHeader[parameter] === undefined) {
453
- throw new Err(`Extension Header Parameter "${parameter}" is missing`);
454
- }
455
- if (recognized.get(parameter) && protectedHeader[parameter] === undefined) {
456
- throw new Err(`Extension Header Parameter "${parameter}" MUST be integrity protected`);
457
- }
458
- }
459
- return new Set(protectedHeader.crit);
460
- }
461
-
462
- // node_modules/jose/dist/webapi/lib/validate_algorithms.js
463
- function validateAlgorithms(option, algorithms) {
464
- if (algorithms !== undefined && (!Array.isArray(algorithms) || algorithms.some((s) => typeof s !== "string"))) {
465
- throw new TypeError(`"${option}" option must be an array of strings`);
466
- }
467
- if (!algorithms) {
468
- return;
469
- }
470
- return new Set(algorithms);
471
- }
472
-
473
- // node_modules/jose/dist/webapi/lib/is_jwk.js
474
- var isJWK = (key) => isObject(key) && typeof key.kty === "string";
475
- var isPrivateJWK = (key) => key.kty !== "oct" && (key.kty === "AKP" && typeof key.priv === "string" || typeof key.d === "string");
476
- var isPublicJWK = (key) => key.kty !== "oct" && key.d === undefined && key.priv === undefined;
477
- var isSecretJWK = (key) => key.kty === "oct" && typeof key.k === "string";
478
-
479
- // node_modules/jose/dist/webapi/lib/normalize_key.js
498
+ // node_modules/.pnpm/jose@6.2.1/node_modules/jose/dist/webapi/lib/normalize_key.js
499
+ var unusableForAlg = "given KeyObject instance cannot be used for this algorithm";
480
500
  var cache;
481
501
  var handleJWK = async (key, jwk, alg, freeze = false) => {
482
502
  cache ||= new WeakMap;
@@ -511,13 +531,13 @@ var handleKeyObject = (keyObject, alg) => {
511
531
  case "ECDH-ES+A256KW":
512
532
  break;
513
533
  default:
514
- throw new TypeError("given KeyObject instance cannot be used for this algorithm");
534
+ throw new TypeError(unusableForAlg);
515
535
  }
516
536
  cryptoKey = keyObject.toCryptoKey(keyObject.asymmetricKeyType, extractable, isPublic ? [] : ["deriveBits"]);
517
537
  }
518
538
  if (keyObject.asymmetricKeyType === "ed25519") {
519
539
  if (alg !== "EdDSA" && alg !== "Ed25519") {
520
- throw new TypeError("given KeyObject instance cannot be used for this algorithm");
540
+ throw new TypeError(unusableForAlg);
521
541
  }
522
542
  cryptoKey = keyObject.toCryptoKey(keyObject.asymmetricKeyType, extractable, [
523
543
  isPublic ? "verify" : "sign"
@@ -528,7 +548,7 @@ var handleKeyObject = (keyObject, alg) => {
528
548
  case "ml-dsa-65":
529
549
  case "ml-dsa-87": {
530
550
  if (alg !== keyObject.asymmetricKeyType.toUpperCase()) {
531
- throw new TypeError("given KeyObject instance cannot be used for this algorithm");
551
+ throw new TypeError(unusableForAlg);
532
552
  }
533
553
  cryptoKey = keyObject.toCryptoKey(keyObject.asymmetricKeyType, extractable, [
534
554
  isPublic ? "verify" : "sign"
@@ -557,7 +577,7 @@ var handleKeyObject = (keyObject, alg) => {
557
577
  hash = "SHA-512";
558
578
  break;
559
579
  default:
560
- throw new TypeError("given KeyObject instance cannot be used for this algorithm");
580
+ throw new TypeError(unusableForAlg);
561
581
  }
562
582
  if (alg.startsWith("RSA-OAEP")) {
563
583
  return keyObject.toCryptoKey({
@@ -578,21 +598,10 @@ var handleKeyObject = (keyObject, alg) => {
578
598
  ]);
579
599
  const namedCurve = nist.get(keyObject.asymmetricKeyDetails?.namedCurve);
580
600
  if (!namedCurve) {
581
- throw new TypeError("given KeyObject instance cannot be used for this algorithm");
582
- }
583
- if (alg === "ES256" && namedCurve === "P-256") {
584
- cryptoKey = keyObject.toCryptoKey({
585
- name: "ECDSA",
586
- namedCurve
587
- }, extractable, [isPublic ? "verify" : "sign"]);
588
- }
589
- if (alg === "ES384" && namedCurve === "P-384") {
590
- cryptoKey = keyObject.toCryptoKey({
591
- name: "ECDSA",
592
- namedCurve
593
- }, extractable, [isPublic ? "verify" : "sign"]);
601
+ throw new TypeError(unusableForAlg);
594
602
  }
595
- if (alg === "ES512" && namedCurve === "P-521") {
603
+ const expectedCurve = { ES256: "P-256", ES384: "P-384", ES512: "P-521" };
604
+ if (expectedCurve[alg] && namedCurve === expectedCurve[alg]) {
596
605
  cryptoKey = keyObject.toCryptoKey({
597
606
  name: "ECDSA",
598
607
  namedCurve
@@ -606,7 +615,7 @@ var handleKeyObject = (keyObject, alg) => {
606
615
  }
607
616
  }
608
617
  if (!cryptoKey) {
609
- throw new TypeError("given KeyObject instance cannot be used for this algorithm");
618
+ throw new TypeError(unusableForAlg);
610
619
  }
611
620
  if (!cached) {
612
621
  cache.set(keyObject, { [alg]: cryptoKey });
@@ -647,7 +656,49 @@ async function normalizeKey(key, alg) {
647
656
  throw new Error("unreachable");
648
657
  }
649
658
 
650
- // node_modules/jose/dist/webapi/lib/check_key_type.js
659
+ // node_modules/.pnpm/jose@6.2.1/node_modules/jose/dist/webapi/lib/validate_crit.js
660
+ function validateCrit(Err, recognizedDefault, recognizedOption, protectedHeader, joseHeader) {
661
+ if (joseHeader.crit !== undefined && protectedHeader?.crit === undefined) {
662
+ throw new Err('"crit" (Critical) Header Parameter MUST be integrity protected');
663
+ }
664
+ if (!protectedHeader || protectedHeader.crit === undefined) {
665
+ return new Set;
666
+ }
667
+ if (!Array.isArray(protectedHeader.crit) || protectedHeader.crit.length === 0 || protectedHeader.crit.some((input) => typeof input !== "string" || input.length === 0)) {
668
+ throw new Err('"crit" (Critical) Header Parameter MUST be an array of non-empty strings when present');
669
+ }
670
+ let recognized;
671
+ if (recognizedOption !== undefined) {
672
+ recognized = new Map([...Object.entries(recognizedOption), ...recognizedDefault.entries()]);
673
+ } else {
674
+ recognized = recognizedDefault;
675
+ }
676
+ for (const parameter of protectedHeader.crit) {
677
+ if (!recognized.has(parameter)) {
678
+ throw new JOSENotSupported(`Extension Header Parameter "${parameter}" is not recognized`);
679
+ }
680
+ if (joseHeader[parameter] === undefined) {
681
+ throw new Err(`Extension Header Parameter "${parameter}" is missing`);
682
+ }
683
+ if (recognized.get(parameter) && protectedHeader[parameter] === undefined) {
684
+ throw new Err(`Extension Header Parameter "${parameter}" MUST be integrity protected`);
685
+ }
686
+ }
687
+ return new Set(protectedHeader.crit);
688
+ }
689
+
690
+ // node_modules/.pnpm/jose@6.2.1/node_modules/jose/dist/webapi/lib/validate_algorithms.js
691
+ function validateAlgorithms(option, algorithms) {
692
+ if (algorithms !== undefined && (!Array.isArray(algorithms) || algorithms.some((s) => typeof s !== "string"))) {
693
+ throw new TypeError(`"${option}" option must be an array of strings`);
694
+ }
695
+ if (!algorithms) {
696
+ return;
697
+ }
698
+ return new Set(algorithms);
699
+ }
700
+
701
+ // node_modules/.pnpm/jose@6.2.1/node_modules/jose/dist/webapi/lib/check_key_type.js
651
702
  var tag = (key) => key?.[Symbol.toStringTag];
652
703
  var jwkMatchesOp = (alg, key, usage) => {
653
704
  if (key.use !== undefined) {
@@ -722,12 +773,12 @@ var asymmetricTypeCheck = (alg, key, usage) => {
722
773
  case "sign":
723
774
  if (isPrivateJWK(key) && jwkMatchesOp(alg, key, usage))
724
775
  return;
725
- throw new TypeError(`JSON Web Key for this operation be a private JWK`);
776
+ throw new TypeError(`JSON Web Key for this operation must be a private JWK`);
726
777
  case "encrypt":
727
778
  case "verify":
728
779
  if (isPublicJWK(key) && jwkMatchesOp(alg, key, usage))
729
780
  return;
730
- throw new TypeError(`JSON Web Key for this operation be a public JWK`);
781
+ throw new TypeError(`JSON Web Key for this operation must be a public JWK`);
731
782
  }
732
783
  }
733
784
  if (!isKeyLike(key)) {
@@ -767,63 +818,7 @@ function checkKeyType(alg, key, usage) {
767
818
  }
768
819
  }
769
820
 
770
- // node_modules/jose/dist/webapi/lib/subtle_dsa.js
771
- function subtleAlgorithm(alg, algorithm) {
772
- const hash = `SHA-${alg.slice(-3)}`;
773
- switch (alg) {
774
- case "HS256":
775
- case "HS384":
776
- case "HS512":
777
- return { hash, name: "HMAC" };
778
- case "PS256":
779
- case "PS384":
780
- case "PS512":
781
- return { hash, name: "RSA-PSS", saltLength: parseInt(alg.slice(-3), 10) >> 3 };
782
- case "RS256":
783
- case "RS384":
784
- case "RS512":
785
- return { hash, name: "RSASSA-PKCS1-v1_5" };
786
- case "ES256":
787
- case "ES384":
788
- case "ES512":
789
- return { hash, name: "ECDSA", namedCurve: algorithm.namedCurve };
790
- case "Ed25519":
791
- case "EdDSA":
792
- return { name: "Ed25519" };
793
- case "ML-DSA-44":
794
- case "ML-DSA-65":
795
- case "ML-DSA-87":
796
- return { name: alg };
797
- default:
798
- throw new JOSENotSupported(`alg ${alg} is not supported either by JOSE or your javascript runtime`);
799
- }
800
- }
801
-
802
- // node_modules/jose/dist/webapi/lib/get_sign_verify_key.js
803
- async function getSigKey(alg, key, usage) {
804
- if (key instanceof Uint8Array) {
805
- if (!alg.startsWith("HS")) {
806
- throw new TypeError(invalidKeyInput(key, "CryptoKey", "KeyObject", "JSON Web Key"));
807
- }
808
- return crypto.subtle.importKey("raw", key, { hash: `SHA-${alg.slice(-3)}`, name: "HMAC" }, false, [usage]);
809
- }
810
- checkSigCryptoKey(key, alg, usage);
811
- return key;
812
- }
813
-
814
- // node_modules/jose/dist/webapi/lib/verify.js
815
- async function verify(alg, key, signature, data) {
816
- const cryptoKey = await getSigKey(alg, key, "verify");
817
- checkKeyLength(alg, cryptoKey);
818
- const algorithm = subtleAlgorithm(alg, cryptoKey.algorithm);
819
- try {
820
- return await crypto.subtle.verify(algorithm, cryptoKey, signature, data);
821
- } catch {
822
- return false;
823
- }
824
- }
825
-
826
- // node_modules/jose/dist/webapi/jws/flattened/verify.js
821
+ // node_modules/.pnpm/jose@6.2.1/node_modules/jose/dist/webapi/jws/flattened/verify.js
827
822
  async function flattenedVerify(jws, key, options) {
828
823
  if (!isObject(jws)) {
829
824
  throw new JWSInvalid("Flattened JWS must be an object");
@@ -889,12 +884,7 @@ async function flattenedVerify(jws, key, options) {
889
884
  }
890
885
  checkKeyType(alg, key, "verify");
891
886
  const data = concat(jws.protected !== undefined ? encode(jws.protected) : new Uint8Array, encode("."), typeof jws.payload === "string" ? b64 ? encode(jws.payload) : encoder.encode(jws.payload) : jws.payload);
892
- let signature;
893
- try {
894
- signature = decode(jws.signature);
895
- } catch {
896
- throw new JWSInvalid("Failed to base64url decode the signature");
897
- }
887
+ const signature = decodeBase64url(jws.signature, "signature", JWSInvalid);
898
888
  const k = await normalizeKey(key, alg);
899
889
  const verified = await verify(alg, k, signature, data);
900
890
  if (!verified) {
@@ -902,11 +892,7 @@ async function flattenedVerify(jws, key, options) {
902
892
  }
903
893
  let payload;
904
894
  if (b64) {
905
- try {
906
- payload = decode(jws.payload);
907
- } catch {
908
- throw new JWSInvalid("Failed to base64url decode the payload");
909
- }
895
+ payload = decodeBase64url(jws.payload, "payload", JWSInvalid);
910
896
  } else if (typeof jws.payload === "string") {
911
897
  payload = encoder.encode(jws.payload);
912
898
  } else {
@@ -925,7 +911,7 @@ async function flattenedVerify(jws, key, options) {
925
911
  return result;
926
912
  }
927
913
 
928
- // node_modules/jose/dist/webapi/jws/compact/verify.js
914
+ // node_modules/.pnpm/jose@6.2.1/node_modules/jose/dist/webapi/jws/compact/verify.js
929
915
  async function compactVerify(jws, key, options) {
930
916
  if (jws instanceof Uint8Array) {
931
917
  jws = decoder.decode(jws);
@@ -945,7 +931,7 @@ async function compactVerify(jws, key, options) {
945
931
  return result;
946
932
  }
947
933
 
948
- // node_modules/jose/dist/webapi/lib/jwt_claims_set.js
934
+ // node_modules/.pnpm/jose@6.2.1/node_modules/jose/dist/webapi/lib/jwt_claims_set.js
949
935
  var epoch = (date) => Math.floor(date.getTime() / 1000);
950
936
  var minute = 60;
951
937
  var hour = minute * 60;
@@ -1170,7 +1156,7 @@ class JWTClaimsBuilder {
1170
1156
  }
1171
1157
  }
1172
1158
 
1173
- // node_modules/jose/dist/webapi/jwt/verify.js
1159
+ // node_modules/.pnpm/jose@6.2.1/node_modules/jose/dist/webapi/jwt/verify.js
1174
1160
  async function jwtVerify(jwt, key, options) {
1175
1161
  const verified = await compactVerify(jwt, key, options);
1176
1162
  if (verified.protectedHeader.crit?.includes("b64") && verified.protectedHeader.b64 === false) {
@@ -1183,15 +1169,7 @@ async function jwtVerify(jwt, key, options) {
1183
1169
  }
1184
1170
  return result;
1185
1171
  }
1186
- // node_modules/jose/dist/webapi/lib/sign.js
1187
- async function sign(alg, key, data) {
1188
- const cryptoKey = await getSigKey(alg, key, "sign");
1189
- checkKeyLength(alg, cryptoKey);
1190
- const signature = await crypto.subtle.sign(subtleAlgorithm(alg, cryptoKey.algorithm), cryptoKey, data);
1191
- return new Uint8Array(signature);
1192
- }
1193
-
1194
- // node_modules/jose/dist/webapi/jws/flattened/sign.js
1172
+ // node_modules/.pnpm/jose@6.2.1/node_modules/jose/dist/webapi/jws/flattened/sign.js
1195
1173
  class FlattenedSign {
1196
1174
  #payload;
1197
1175
  #protectedHeader;
@@ -1203,16 +1181,12 @@ class FlattenedSign {
1203
1181
  this.#payload = payload;
1204
1182
  }
1205
1183
  setProtectedHeader(protectedHeader) {
1206
- if (this.#protectedHeader) {
1207
- throw new TypeError("setProtectedHeader can only be called once");
1208
- }
1184
+ assertNotSet(this.#protectedHeader, "setProtectedHeader");
1209
1185
  this.#protectedHeader = protectedHeader;
1210
1186
  return this;
1211
1187
  }
1212
1188
  setUnprotectedHeader(unprotectedHeader) {
1213
- if (this.#unprotectedHeader) {
1214
- throw new TypeError("setUnprotectedHeader can only be called once");
1215
- }
1189
+ assertNotSet(this.#unprotectedHeader, "setUnprotectedHeader");
1216
1190
  this.#unprotectedHeader = unprotectedHeader;
1217
1191
  return this;
1218
1192
  }
@@ -1275,7 +1249,7 @@ class FlattenedSign {
1275
1249
  }
1276
1250
  }
1277
1251
 
1278
- // node_modules/jose/dist/webapi/jws/compact/sign.js
1252
+ // node_modules/.pnpm/jose@6.2.1/node_modules/jose/dist/webapi/jws/compact/sign.js
1279
1253
  class CompactSign {
1280
1254
  #flattened;
1281
1255
  constructor(payload) {
@@ -1294,7 +1268,7 @@ class CompactSign {
1294
1268
  }
1295
1269
  }
1296
1270
 
1297
- // node_modules/jose/dist/webapi/jwt/sign.js
1271
+ // node_modules/.pnpm/jose@6.2.1/node_modules/jose/dist/webapi/jwt/sign.js
1298
1272
  class SignJWT {
1299
1273
  #protectedHeader;
1300
1274
  #jwt;
package/dist/prince.d.ts CHANGED
@@ -12,6 +12,8 @@ export interface PrinceRequest extends Request {
12
12
  session?: any;
13
13
  apiKey?: string;
14
14
  sseSend?: (data: any, event?: string, id?: string) => void;
15
+ cookies?: Record<string, string>;
16
+ ip?: string;
15
17
  [key: string]: any;
16
18
  }
17
19
  export type OnRequest = (req: PrinceRequest) => void | Promise<void>;
@@ -32,10 +34,18 @@ declare class ResponseBuilder {
32
34
  private _body;
33
35
  status(code: number): this;
34
36
  header(key: string, value: string): this;
35
- json(data: any): Response;
36
- text(data: string): Response;
37
- html(data: string): Response;
38
- redirect(url: string, status?: number): Response;
37
+ json(data: any): this;
38
+ text(data: string): this;
39
+ html(data: string): this;
40
+ redirect(url: string, status?: number): this;
41
+ cookie(name: string, value: string, options?: {
42
+ maxAge?: number;
43
+ path?: string;
44
+ domain?: string;
45
+ secure?: boolean;
46
+ httpOnly?: boolean;
47
+ sameSite?: "Strict" | "Lax" | "None";
48
+ }): this;
39
49
  build(): Response;
40
50
  }
41
51
  export interface RouteSchema {
@@ -1 +1 @@
1
- {"version":3,"file":"prince.d.ts","sourceRoot":"","sources":["../src/prince.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"prince.d.ts","sourceRoot":"","sources":["../src/prince.ts"],"names":[],"mappings":"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"}
package/dist/prince.js CHANGED
@@ -134,27 +134,71 @@ class ResponseBuilder {
134
134
  json(data) {
135
135
  this._headers["Content-Type"] = "application/json";
136
136
  this._body = JSON.stringify(data);
137
- return this.build();
137
+ return this;
138
138
  }
139
139
  text(data) {
140
140
  this._headers["Content-Type"] = "text/plain";
141
141
  this._body = data;
142
- return this.build();
142
+ return this;
143
143
  }
144
144
  html(data) {
145
145
  this._headers["Content-Type"] = "text/html";
146
146
  this._body = data;
147
- return this.build();
147
+ return this;
148
148
  }
149
149
  redirect(url, status = 302) {
150
150
  this._status = status;
151
151
  this._headers["Location"] = url;
152
- return this.build();
152
+ return this;
153
+ }
154
+ cookie(name, value, options) {
155
+ let cookieStr = `${encodeURIComponent(name)}=${encodeURIComponent(value)}`;
156
+ if (options?.maxAge)
157
+ cookieStr += `; Max-Age=${options.maxAge}`;
158
+ if (options?.path)
159
+ cookieStr += `; Path=${options.path}`;
160
+ if (options?.domain)
161
+ cookieStr += `; Domain=${options.domain}`;
162
+ if (options?.secure)
163
+ cookieStr += "; Secure";
164
+ if (options?.httpOnly)
165
+ cookieStr += "; HttpOnly";
166
+ if (options?.sameSite)
167
+ cookieStr += `; SameSite=${options.sameSite}`;
168
+ const existing = this._headers["Set-Cookie"];
169
+ this._headers["Set-Cookie"] = existing ? `${existing}, ${cookieStr}` : cookieStr;
170
+ return this;
153
171
  }
154
172
  build() {
155
173
  return new Response(this._body, { status: this._status, headers: this._headers });
156
174
  }
157
175
  }
176
+ function parseCookies(cookieHeader) {
177
+ const cookies = {};
178
+ if (!cookieHeader)
179
+ return cookies;
180
+ cookieHeader.split(";").forEach((pair) => {
181
+ const [name, ...value] = pair.split("=");
182
+ if (name)
183
+ cookies[decodeURIComponent(name.trim())] = decodeURIComponent((value.join("=") || "").trim());
184
+ });
185
+ return cookies;
186
+ }
187
+ function detectIP(req) {
188
+ const forwarded = req.headers.get("x-forwarded-for");
189
+ if (forwarded)
190
+ return forwarded.split(",")[0].trim();
191
+ const realIp = req.headers.get("x-real-ip");
192
+ if (realIp)
193
+ return realIp;
194
+ const cfIp = req.headers.get("cf-connecting-ip");
195
+ if (cfIp)
196
+ return cfIp;
197
+ const clientIp = req.headers.get("x-client-ip");
198
+ if (clientIp)
199
+ return clientIp;
200
+ return "127.0.0.1";
201
+ }
158
202
  function zodToJsonSchema(schema) {
159
203
  const d = schema._def;
160
204
  const typeName = d?.typeName ?? d?.type ?? "";
@@ -595,6 +639,9 @@ class Prince {
595
639
  async executeHandler(req, handler, params, query, routeMiddlewares, method, pathname) {
596
640
  Object.defineProperty(req, "params", { value: params, writable: true, configurable: true });
597
641
  Object.defineProperty(req, "query", { value: query, writable: true, configurable: true });
642
+ const cookieHeader = req.headers.get("cookie") || "";
643
+ Object.defineProperty(req, "cookies", { value: parseCookies(cookieHeader), writable: true, configurable: true });
644
+ Object.defineProperty(req, "ip", { value: detectIP(req), writable: true, configurable: true });
598
645
  if (["POST", "PUT", "PATCH"].includes(req.method) && !req.parsedBody) {
599
646
  const parsed = await this.parseBody(req);
600
647
  if (parsed) {
@@ -627,6 +674,8 @@ class Prince {
627
674
  const res = await handler(req);
628
675
  if (res instanceof Response)
629
676
  return res;
677
+ if (res instanceof ResponseBuilder)
678
+ return res.build();
630
679
  if (typeof res === "string")
631
680
  return new Response(res);
632
681
  if (res instanceof Uint8Array)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "princejs",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
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",
@@ -96,24 +96,23 @@
96
96
  },
97
97
  "devDependencies": {
98
98
  "@types/bun": "^1.3.2",
99
- "@types/jsonwebtoken": "^9.0.10",
100
99
  "bun-types": "latest",
101
- "fast-jwt": "^5.0.0",
102
- "jsonwebtoken": "^9.0.2",
103
100
  "typescript": "^5.9.3",
104
101
  "zod": "^4.1.12"
105
102
  },
106
103
  "peerDependencies": {
107
- "zod": "^4.1.12"
104
+ "zod": "^4.1.12",
105
+ "jose": "^6.1.2"
108
106
  },
109
107
  "peerDependenciesMeta": {
110
108
  "zod": {
111
109
  "optional": true
110
+ },
111
+ "jose": {
112
+ "optional": true
112
113
  }
113
114
  },
114
- "dependencies": {
115
- "jose": "^6.1.2"
116
- },
115
+ "dependencies": {},
117
116
  "scripts": {
118
117
  "build:js": "bun build src/prince.ts --outdir dist --target bun --external zod --external jose && 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",
119
118
  "build:types": "tsc --emitDeclarationOnly --skipLibCheck",