hapta 1.0.13 → 1.0.15

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.
@@ -94,11 +94,12 @@ type TokenOptions = {
94
94
  iat: number
95
95
  }
96
96
  type VerifyFn = (token: string) => Promise<Principal>;
97
-
97
+ type DecodeFn = (token: string) => Promise<any>;
98
98
  export type ServiceConfigs = {
99
99
  Authenticate: AuthenticateFn;
100
100
  Register: RegisterFn;
101
101
  Verify?: VerifyFn;
102
+ Decode?:DecodeFn
102
103
  };
103
104
 
104
105
  // ---
@@ -113,6 +114,7 @@ export type RequestMetadata = {
113
114
  ipAddress?: string;
114
115
  userAgent?: string;
115
116
  body: any,
117
+ token: string,
116
118
  json: {},
117
119
  headers: Headers | {};
118
120
  query:{},
package/index.ts CHANGED
@@ -39,7 +39,7 @@ if (!config.Database?.url || !config.Database?.Admin_Password || !config.Databas
39
39
  export const pb = new Pocketbase(config.Database?.url || "");
40
40
  pb.autoCancellation(false)
41
41
  try {
42
- await pb.collection("_superusers").authWithPassword(config.Database?.Admin_Email || "", config.Database?.Admin_Password || "");
42
+ await pb.collection("_superusers").authWithPassword(config.Database?.Admin_Email || "", config.Database?.Admin_Password || "");
43
43
  } catch (_) { }
44
44
 
45
45
  const cache = new Cache();
@@ -169,6 +169,43 @@ async function createServeConfig(): Promise<Serve> {
169
169
  const origin = req.headers.get("origin");
170
170
  const corsHeaders = buildCorsHeaders(origin, defaultCorsConfig);
171
171
 
172
+ if (url.pathname.startsWith("/files")) {
173
+ const filePath = url.pathname.replace("/files", "");
174
+
175
+ // 1️⃣ Cache hit
176
+ const cached = cache.get(filePath);
177
+ if (cached) {
178
+ return new Response(cached.body, {
179
+ headers: cached.headers,
180
+ });
181
+ }
182
+
183
+ const res = await fetch(config.Database!.url + "/api/files/" + filePath);
184
+ console.log(res)
185
+
186
+ if (!res.ok) {
187
+ return new Response("File not found", { status: 404 });
188
+ }
189
+
190
+ // 3️⃣ Read once
191
+ const buffer = await res.arrayBuffer();
192
+
193
+ const headers = {
194
+ "Content-Type": res.headers.get("content-type") ?? "application/octet-stream",
195
+ "Cache-Control": "public, max-age=31536000",
196
+ };
197
+
198
+ // 4️⃣ Store bytes, not Response
199
+ cache.set(filePath, {
200
+ body: buffer,
201
+ headers,
202
+ });
203
+
204
+ // 5️⃣ Return fresh Response
205
+ return new Response(buffer, { headers });
206
+ }
207
+
208
+
172
209
  const method = req.method.toUpperCase();
173
210
  // Handle CORS preflight
174
211
  if (req.method === "OPTIONS") {
@@ -244,7 +281,7 @@ async function createServeConfig(): Promise<Serve> {
244
281
  return new Response(
245
282
  JSON.stringify({
246
283
  success: false,
247
- data: {error: validation[key]?.error.flatten()}
284
+ data: { error: validation[key]?.error.flatten() }
248
285
  }),
249
286
  {
250
287
  status: 400,
@@ -409,7 +446,7 @@ async function Register(data: { username: string; email: string; password: strin
409
446
  } catch (err: any) {
410
447
  const fieldErrors: Record<string, { code: string; message: string }> = {};
411
448
 
412
- if (err?.data) {
449
+ if (err?.data) {
413
450
  for (const key in err.data) {
414
451
  let value = err.data[key];
415
452
 
@@ -497,11 +534,27 @@ async function buildRequestContext(req: Request, headers: Headers): Promise<Cont
497
534
  }
498
535
  },
499
536
  Register,
537
+ async Verify(token: string) {
538
+ try {
539
+ // Returns the decoded payload if valid, throws if expired/tampered
540
+ return jwt.verify(token, config.Server.JWT_Secret);
541
+ } catch (error) {
542
+ // Specifically catching JsonWebTokenError or TokenExpiredError
543
+ return false;
544
+ }
545
+ },
546
+
547
+ Decode(token: string) {
548
+ // decode() just reads the data without checking the signature.
549
+ // Useful for checking expiration or UI logic without needing the Secret.
550
+ return jwt.decode(token);
551
+ }
500
552
 
501
553
  },
502
554
  metadata: {
503
555
  requestID: crypto.randomUUID(),
504
556
  timestamp: new Date(),
557
+ token,
505
558
  params: {},
506
559
  query: {},
507
560
  json: reqJSON,
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "bin": {
4
4
  "hapta": "./index.ts"
5
5
  },
6
- "version": "1.0.13",
6
+ "version": "1.0.15",
7
7
  "description": "modular, scalable, and feature-rich backend framework designed to extend Pocketbase with authentication, schema validation, caching, and tenant-based service orchestration.",
8
8
  "dependencies": {
9
9
  "jsonwebtoken": "^9.0.3",
package/bun.lock DELETED
@@ -1,48 +0,0 @@
1
- {
2
- "lockfileVersion": 1,
3
- "configVersion": 1,
4
- "workspaces": {
5
- "": {
6
- "dependencies": {
7
- "jsonwebtoken": "^9.0.3",
8
- "pocketbase": "latest",
9
- "zod": "latest",
10
- },
11
- },
12
- },
13
- "packages": {
14
- "buffer-equal-constant-time": ["buffer-equal-constant-time@1.0.1", "", {}, "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="],
15
-
16
- "ecdsa-sig-formatter": ["ecdsa-sig-formatter@1.0.11", "", { "dependencies": { "safe-buffer": "^5.0.1" } }, "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ=="],
17
-
18
- "jsonwebtoken": ["jsonwebtoken@9.0.3", "", { "dependencies": { "jws": "^4.0.1", "lodash.includes": "^4.3.0", "lodash.isboolean": "^3.0.3", "lodash.isinteger": "^4.0.4", "lodash.isnumber": "^3.0.3", "lodash.isplainobject": "^4.0.6", "lodash.isstring": "^4.0.1", "lodash.once": "^4.0.0", "ms": "^2.1.1", "semver": "^7.5.4" } }, "sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g=="],
19
-
20
- "jwa": ["jwa@2.0.1", "", { "dependencies": { "buffer-equal-constant-time": "^1.0.1", "ecdsa-sig-formatter": "1.0.11", "safe-buffer": "^5.0.1" } }, "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg=="],
21
-
22
- "jws": ["jws@4.0.1", "", { "dependencies": { "jwa": "^2.0.1", "safe-buffer": "^5.0.1" } }, "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA=="],
23
-
24
- "lodash.includes": ["lodash.includes@4.3.0", "", {}, "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w=="],
25
-
26
- "lodash.isboolean": ["lodash.isboolean@3.0.3", "", {}, "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg=="],
27
-
28
- "lodash.isinteger": ["lodash.isinteger@4.0.4", "", {}, "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA=="],
29
-
30
- "lodash.isnumber": ["lodash.isnumber@3.0.3", "", {}, "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw=="],
31
-
32
- "lodash.isplainobject": ["lodash.isplainobject@4.0.6", "", {}, "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA=="],
33
-
34
- "lodash.isstring": ["lodash.isstring@4.0.1", "", {}, "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw=="],
35
-
36
- "lodash.once": ["lodash.once@4.1.1", "", {}, "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg=="],
37
-
38
- "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
39
-
40
- "pocketbase": ["pocketbase@0.26.8", "", {}, "sha512-aQ/ewvS7ncvAE8wxoW10iAZu6ElgbeFpBhKPnCfvRovNzm2gW8u/sQNPGN6vNgVEagz44kK//C61oKjfa+7Low=="],
41
-
42
- "safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
43
-
44
- "semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
45
-
46
- "zod": ["zod@4.3.6", "", {}, "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg=="],
47
- }
48
- }