@spfn/auth 0.1.0-alpha.1 → 0.1.0-alpha.86

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 (124) hide show
  1. package/README.md +250 -0
  2. package/dist/adapters/nextjs/api.d.ts +446 -0
  3. package/dist/adapters/nextjs/api.js +3279 -0
  4. package/dist/adapters/nextjs/api.js.map +1 -0
  5. package/dist/adapters/nextjs/server.d.ts +246 -0
  6. package/dist/adapters/nextjs/server.js +3645 -0
  7. package/dist/adapters/nextjs/server.js.map +1 -0
  8. package/dist/index.d.ts +3 -46
  9. package/dist/index.js +777 -645
  10. package/dist/index.js.map +1 -1
  11. package/dist/lib/api/auth-codes-verify.d.ts +37 -0
  12. package/dist/lib/api/auth-codes-verify.js +2949 -0
  13. package/dist/lib/api/auth-codes-verify.js.map +1 -0
  14. package/dist/lib/api/auth-codes.d.ts +37 -0
  15. package/dist/lib/api/auth-codes.js +2949 -0
  16. package/dist/lib/api/auth-codes.js.map +1 -0
  17. package/dist/lib/api/auth-exists.d.ts +38 -0
  18. package/dist/lib/api/auth-exists.js +2949 -0
  19. package/dist/lib/api/auth-exists.js.map +1 -0
  20. package/dist/lib/api/auth-invitations-accept.d.ts +38 -0
  21. package/dist/lib/api/auth-invitations-accept.js +2883 -0
  22. package/dist/lib/api/auth-invitations-accept.js.map +1 -0
  23. package/dist/lib/api/auth-invitations-cancel.d.ts +37 -0
  24. package/dist/lib/api/auth-invitations-cancel.js +2883 -0
  25. package/dist/lib/api/auth-invitations-cancel.js.map +1 -0
  26. package/dist/lib/api/auth-invitations-delete.d.ts +36 -0
  27. package/dist/lib/api/auth-invitations-delete.js +2883 -0
  28. package/dist/lib/api/auth-invitations-delete.js.map +1 -0
  29. package/dist/lib/api/auth-invitations-resend.d.ts +37 -0
  30. package/dist/lib/api/auth-invitations-resend.js +2883 -0
  31. package/dist/lib/api/auth-invitations-resend.js.map +1 -0
  32. package/dist/lib/api/auth-invitations.d.ts +109 -0
  33. package/dist/lib/api/auth-invitations.js +2887 -0
  34. package/dist/lib/api/auth-invitations.js.map +1 -0
  35. package/dist/lib/api/auth-keys-rotate.d.ts +37 -0
  36. package/dist/lib/api/auth-keys-rotate.js +2949 -0
  37. package/dist/lib/api/auth-keys-rotate.js.map +1 -0
  38. package/dist/lib/api/auth-login.d.ts +39 -0
  39. package/dist/lib/api/auth-login.js +2949 -0
  40. package/dist/lib/api/auth-login.js.map +1 -0
  41. package/dist/lib/api/auth-logout.d.ts +36 -0
  42. package/dist/lib/api/auth-logout.js +2949 -0
  43. package/dist/lib/api/auth-logout.js.map +1 -0
  44. package/dist/lib/api/auth-me.d.ts +50 -0
  45. package/dist/lib/api/auth-me.js +2949 -0
  46. package/dist/lib/api/auth-me.js.map +1 -0
  47. package/dist/lib/api/auth-password.d.ts +36 -0
  48. package/dist/lib/api/auth-password.js +2949 -0
  49. package/dist/lib/api/auth-password.js.map +1 -0
  50. package/dist/lib/api/auth-register.d.ts +38 -0
  51. package/dist/lib/api/auth-register.js +2949 -0
  52. package/dist/lib/api/auth-register.js.map +1 -0
  53. package/dist/lib/api/index.d.ts +356 -0
  54. package/dist/lib/api/index.js +3261 -0
  55. package/dist/lib/api/index.js.map +1 -0
  56. package/dist/lib/config.d.ts +70 -0
  57. package/dist/lib/config.js +64 -0
  58. package/dist/lib/config.js.map +1 -0
  59. package/dist/lib/contracts/auth.d.ts +41 -1
  60. package/dist/lib/contracts/auth.js +28 -0
  61. package/dist/lib/contracts/auth.js.map +1 -1
  62. package/dist/lib/contracts/index.d.ts +1 -1
  63. package/dist/lib/contracts/index.js +28 -0
  64. package/dist/lib/contracts/index.js.map +1 -1
  65. package/dist/lib/crypto.d.ts +76 -0
  66. package/dist/lib/crypto.js +127 -0
  67. package/dist/lib/crypto.js.map +1 -0
  68. package/dist/lib/index.d.ts +4 -0
  69. package/dist/lib/index.js +313 -0
  70. package/dist/lib/index.js.map +1 -0
  71. package/dist/lib/session.d.ts +68 -0
  72. package/dist/lib/session.js +126 -0
  73. package/dist/lib/session.js.map +1 -0
  74. package/dist/{api-BcQM4WKb.d.ts → lib/types/api.d.ts} +2 -2
  75. package/dist/lib/types/api.js +1 -0
  76. package/dist/lib/types/api.js.map +1 -0
  77. package/dist/lib/types/index.d.ts +3 -0
  78. package/dist/lib/types/index.js +2647 -0
  79. package/dist/lib/types/index.js.map +1 -0
  80. package/dist/lib/types/schemas.d.ts +45 -0
  81. package/dist/lib/types/schemas.js +2647 -0
  82. package/dist/lib/types/schemas.js.map +1 -0
  83. package/dist/lib.d.ts +2 -0
  84. package/dist/lib.js +1 -0
  85. package/dist/lib.js.map +1 -0
  86. package/dist/plugin.js +777 -645
  87. package/dist/plugin.js.map +1 -1
  88. package/dist/server/entities/index.d.ts +1 -0
  89. package/dist/server/entities/index.js +23 -27
  90. package/dist/server/entities/index.js.map +1 -1
  91. package/dist/server/entities/invitations.js +12 -9
  92. package/dist/server/entities/invitations.js.map +1 -1
  93. package/dist/server/entities/permissions.js +8 -3
  94. package/dist/server/entities/permissions.js.map +1 -1
  95. package/dist/server/entities/role-permissions.js +12 -9
  96. package/dist/server/entities/role-permissions.js.map +1 -1
  97. package/dist/server/entities/roles.js +8 -3
  98. package/dist/server/entities/roles.js.map +1 -1
  99. package/dist/server/entities/schema.d.ts +14 -0
  100. package/dist/server/entities/schema.js +7 -0
  101. package/dist/server/entities/schema.js.map +1 -0
  102. package/dist/server/entities/user-permissions.js +14 -12
  103. package/dist/server/entities/user-permissions.js.map +1 -1
  104. package/dist/server/entities/user-public-keys.js +12 -9
  105. package/dist/server/entities/user-public-keys.js.map +1 -1
  106. package/dist/server/entities/user-social-accounts.js +12 -9
  107. package/dist/server/entities/user-social-accounts.js.map +1 -1
  108. package/dist/server/entities/users.js +10 -6
  109. package/dist/server/entities/users.js.map +1 -1
  110. package/dist/server/entities/verification-codes.js +8 -3
  111. package/dist/server/entities/verification-codes.js.map +1 -1
  112. package/dist/server/routes/auth/index.js +495 -512
  113. package/dist/server/routes/auth/index.js.map +1 -1
  114. package/dist/server/routes/index.js +775 -545
  115. package/dist/server/routes/index.js.map +1 -1
  116. package/dist/server/routes/invitations/index.js +416 -230
  117. package/dist/server/routes/invitations/index.js.map +1 -1
  118. package/dist/server.d.ts +91 -62
  119. package/dist/server.js +320 -327
  120. package/dist/server.js.map +1 -1
  121. package/migrations/{0000_tired_gambit.sql → 0000_complex_swordsman.sql} +2 -0
  122. package/migrations/meta/0000_snapshot.json +4 -2
  123. package/migrations/meta/_journal.json +2 -2
  124. package/package.json +30 -3
@@ -8,15 +8,102 @@ var __export = (target, all) => {
8
8
  __defProp(target, name, { get: all[name], enumerable: true });
9
9
  };
10
10
 
11
+ // src/server/helpers/jwt.ts
12
+ var jwt_exports = {};
13
+ __export(jwt_exports, {
14
+ decodeToken: () => decodeToken,
15
+ generateToken: () => generateToken,
16
+ verifyClientToken: () => verifyClientToken,
17
+ verifyKeyFingerprint: () => verifyKeyFingerprint,
18
+ verifyToken: () => verifyToken
19
+ });
20
+ import jwt from "jsonwebtoken";
21
+ import crypto from "crypto";
22
+ function generateToken(payload) {
23
+ return jwt.sign(payload, JWT_SECRET, {
24
+ expiresIn: JWT_EXPIRES_IN
25
+ });
26
+ }
27
+ function verifyToken(token) {
28
+ return jwt.verify(token, JWT_SECRET);
29
+ }
30
+ function verifyClientToken(token, publicKeyB64, algorithm) {
31
+ try {
32
+ const publicKeyDER = Buffer.from(publicKeyB64, "base64");
33
+ const publicKeyObject = crypto.createPublicKey({
34
+ key: publicKeyDER,
35
+ format: "der",
36
+ type: "spki"
37
+ });
38
+ const decoded = jwt.verify(token, publicKeyObject, {
39
+ algorithms: [algorithm],
40
+ // Prevent algorithm confusion attacks
41
+ issuer: "spfn-client"
42
+ // Validate token issuer
43
+ });
44
+ if (typeof decoded === "string") {
45
+ throw new Error("Invalid token format: expected object payload");
46
+ }
47
+ return decoded;
48
+ } catch (error) {
49
+ if (error instanceof jwt.TokenExpiredError) {
50
+ throw new Error("Token has expired");
51
+ }
52
+ if (error instanceof jwt.JsonWebTokenError) {
53
+ throw new Error("Invalid token signature");
54
+ }
55
+ throw new Error(`Token verification failed: ${error instanceof Error ? error.message : "Unknown error"}`);
56
+ }
57
+ }
58
+ function decodeToken(token) {
59
+ try {
60
+ return jwt.decode(token);
61
+ } catch {
62
+ return null;
63
+ }
64
+ }
65
+ function verifyKeyFingerprint(publicKeyB64, expectedFingerprint) {
66
+ try {
67
+ const publicKeyDER = Buffer.from(publicKeyB64, "base64");
68
+ const fingerprint = crypto.createHash("sha256").update(publicKeyDER).digest("hex");
69
+ return fingerprint === expectedFingerprint;
70
+ } catch (error) {
71
+ console.error("Failed to verify key fingerprint:", error);
72
+ return false;
73
+ }
74
+ }
75
+ var JWT_SECRET, JWT_EXPIRES_IN;
76
+ var init_jwt = __esm({
77
+ "src/server/helpers/jwt.ts"() {
78
+ "use strict";
79
+ JWT_SECRET = process.env.SPFN_AUTH_JWT_SECRET || // New prefixed version (recommended)
80
+ process.env.JWT_SECRET || // Legacy fallback
81
+ "dev-secret-key-change-in-production";
82
+ JWT_EXPIRES_IN = process.env.SPFN_AUTH_JWT_EXPIRES_IN || // New prefixed version (recommended)
83
+ process.env.JWT_EXPIRES_IN || // Legacy fallback
84
+ "7d";
85
+ }
86
+ });
87
+
88
+ // src/server/entities/schema.ts
89
+ import { createFunctionSchema } from "@spfn/core/db";
90
+ var authSchema;
91
+ var init_schema = __esm({
92
+ "src/server/entities/schema.ts"() {
93
+ "use strict";
94
+ authSchema = createFunctionSchema("@spfn/auth");
95
+ }
96
+ });
97
+
11
98
  // src/server/entities/roles.ts
12
99
  import { text, boolean, integer, index } from "drizzle-orm/pg-core";
13
- import { id, timestamps, createFunctionSchema } from "@spfn/core/db";
14
- var schema, roles;
100
+ import { id, timestamps } from "@spfn/core/db";
101
+ var roles;
15
102
  var init_roles = __esm({
16
103
  "src/server/entities/roles.ts"() {
17
104
  "use strict";
18
- schema = createFunctionSchema("@spfn/auth");
19
- roles = schema.table(
105
+ init_schema();
106
+ roles = authSchema.table(
20
107
  "roles",
21
108
  {
22
109
  // Primary key
@@ -58,15 +145,15 @@ var init_roles = __esm({
58
145
 
59
146
  // src/server/entities/users.ts
60
147
  import { text as text2, timestamp, check, boolean as boolean2, bigint, index as index2 } from "drizzle-orm/pg-core";
61
- import { id as id2, timestamps as timestamps2, createFunctionSchema as createFunctionSchema2 } from "@spfn/core/db";
148
+ import { id as id2, timestamps as timestamps2 } from "@spfn/core/db";
62
149
  import { sql } from "drizzle-orm";
63
- var schema2, users;
150
+ var users;
64
151
  var init_users = __esm({
65
152
  "src/server/entities/users.ts"() {
66
153
  "use strict";
67
154
  init_roles();
68
- schema2 = createFunctionSchema2("@spfn/auth");
69
- users = schema2.table(
155
+ init_schema();
156
+ users = authSchema.table(
70
157
  "users",
71
158
  {
72
159
  // Identity
@@ -131,14 +218,14 @@ var init_users = __esm({
131
218
 
132
219
  // src/server/entities/user-social-accounts.ts
133
220
  import { text as text3, timestamp as timestamp2, uniqueIndex } from "drizzle-orm/pg-core";
134
- import { id as id3, timestamps as timestamps3, foreignKey, createFunctionSchema as createFunctionSchema3 } from "@spfn/core/db";
135
- var schema3, userSocialAccounts;
221
+ import { id as id3, timestamps as timestamps3, foreignKey } from "@spfn/core/db";
222
+ var userSocialAccounts;
136
223
  var init_user_social_accounts = __esm({
137
224
  "src/server/entities/user-social-accounts.ts"() {
138
225
  "use strict";
139
226
  init_users();
140
- schema3 = createFunctionSchema3("@spfn/auth");
141
- userSocialAccounts = schema3.table(
227
+ init_schema();
228
+ userSocialAccounts = authSchema.table(
142
229
  "user_social_accounts",
143
230
  {
144
231
  id: id3(),
@@ -169,14 +256,14 @@ var init_user_social_accounts = __esm({
169
256
 
170
257
  // src/server/entities/user-public-keys.ts
171
258
  import { text as text4, timestamp as timestamp3, boolean as boolean3, index as index3 } from "drizzle-orm/pg-core";
172
- import { id as id4, foreignKey as foreignKey2, createFunctionSchema as createFunctionSchema4 } from "@spfn/core/db";
173
- var schema4, userPublicKeys;
259
+ import { id as id4, foreignKey as foreignKey2 } from "@spfn/core/db";
260
+ var userPublicKeys;
174
261
  var init_user_public_keys = __esm({
175
262
  "src/server/entities/user-public-keys.ts"() {
176
263
  "use strict";
177
264
  init_users();
178
- schema4 = createFunctionSchema4("@spfn/auth");
179
- userPublicKeys = schema4.table(
265
+ init_schema();
266
+ userPublicKeys = authSchema.table(
180
267
  "user_public_keys",
181
268
  {
182
269
  id: id4(),
@@ -214,13 +301,13 @@ var init_user_public_keys = __esm({
214
301
 
215
302
  // src/server/entities/verification-codes.ts
216
303
  import { text as text5, timestamp as timestamp4, index as index4 } from "drizzle-orm/pg-core";
217
- import { id as id5, timestamps as timestamps4, createFunctionSchema as createFunctionSchema5 } from "@spfn/core/db";
218
- var schema5, verificationCodes;
304
+ import { id as id5, timestamps as timestamps4 } from "@spfn/core/db";
305
+ var verificationCodes;
219
306
  var init_verification_codes = __esm({
220
307
  "src/server/entities/verification-codes.ts"() {
221
308
  "use strict";
222
- schema5 = createFunctionSchema5("@spfn/auth");
223
- verificationCodes = schema5.table(
309
+ init_schema();
310
+ verificationCodes = authSchema.table(
224
311
  "verification_codes",
225
312
  {
226
313
  id: id5(),
@@ -261,15 +348,15 @@ var init_verification_codes = __esm({
261
348
 
262
349
  // src/server/entities/invitations.ts
263
350
  import { text as text6, timestamp as timestamp5, bigint as bigint2, index as index5, jsonb } from "drizzle-orm/pg-core";
264
- import { id as id6, timestamps as timestamps5, createFunctionSchema as createFunctionSchema6 } from "@spfn/core/db";
265
- var schema6, invitations;
351
+ import { id as id6, timestamps as timestamps5 } from "@spfn/core/db";
352
+ var invitations;
266
353
  var init_invitations = __esm({
267
354
  "src/server/entities/invitations.ts"() {
268
355
  "use strict";
269
356
  init_roles();
270
357
  init_users();
271
- schema6 = createFunctionSchema6("@spfn/auth");
272
- invitations = schema6.table(
358
+ init_schema();
359
+ invitations = authSchema.table(
273
360
  "user_invitations",
274
361
  {
275
362
  // Primary key
@@ -337,13 +424,13 @@ var init_invitations = __esm({
337
424
 
338
425
  // src/server/entities/permissions.ts
339
426
  import { text as text7, boolean as boolean4, index as index6 } from "drizzle-orm/pg-core";
340
- import { id as id7, timestamps as timestamps6, createFunctionSchema as createFunctionSchema7 } from "@spfn/core/db";
341
- var schema7, permissions;
427
+ import { id as id7, timestamps as timestamps6 } from "@spfn/core/db";
428
+ var permissions;
342
429
  var init_permissions = __esm({
343
430
  "src/server/entities/permissions.ts"() {
344
431
  "use strict";
345
- schema7 = createFunctionSchema7("@spfn/auth");
346
- permissions = schema7.table(
432
+ init_schema();
433
+ permissions = authSchema.table(
347
434
  "permissions",
348
435
  {
349
436
  // Primary key
@@ -384,15 +471,15 @@ var init_permissions = __esm({
384
471
 
385
472
  // src/server/entities/role-permissions.ts
386
473
  import { bigint as bigint3, index as index7, unique } from "drizzle-orm/pg-core";
387
- import { id as id8, timestamps as timestamps7, createFunctionSchema as createFunctionSchema8 } from "@spfn/core/db";
388
- var schema8, rolePermissions;
474
+ import { id as id8, timestamps as timestamps7 } from "@spfn/core/db";
475
+ var rolePermissions;
389
476
  var init_role_permissions = __esm({
390
477
  "src/server/entities/role-permissions.ts"() {
391
478
  "use strict";
392
479
  init_roles();
393
480
  init_permissions();
394
- schema8 = createFunctionSchema8("@spfn/auth");
395
- rolePermissions = schema8.table(
481
+ init_schema();
482
+ rolePermissions = authSchema.table(
396
483
  "role_permissions",
397
484
  {
398
485
  // Primary key
@@ -416,15 +503,15 @@ var init_role_permissions = __esm({
416
503
 
417
504
  // src/server/entities/user-permissions.ts
418
505
  import { bigint as bigint4, boolean as boolean5, text as text8, timestamp as timestamp6, index as index8, unique as unique2 } from "drizzle-orm/pg-core";
419
- import { id as id9, timestamps as timestamps8, createFunctionSchema as createFunctionSchema9 } from "@spfn/core/db";
420
- var schema9, userPermissions;
506
+ import { id as id9, timestamps as timestamps8 } from "@spfn/core/db";
507
+ var userPermissions;
421
508
  var init_user_permissions = __esm({
422
509
  "src/server/entities/user-permissions.ts"() {
423
510
  "use strict";
424
511
  init_users();
425
512
  init_permissions();
426
- schema9 = createFunctionSchema9("@spfn/auth");
427
- userPermissions = schema9.table(
513
+ init_schema();
514
+ userPermissions = authSchema.table(
428
515
  "user_permissions",
429
516
  {
430
517
  // Primary key
@@ -460,6 +547,7 @@ var init_user_permissions = __esm({
460
547
  // src/server/entities/index.ts
461
548
  var entities_exports = {};
462
549
  __export(entities_exports, {
550
+ authSchema: () => authSchema,
463
551
  invitations: () => invitations,
464
552
  permissions: () => permissions,
465
553
  rolePermissions: () => rolePermissions,
@@ -473,6 +561,7 @@ __export(entities_exports, {
473
561
  var init_entities = __esm({
474
562
  "src/server/entities/index.ts"() {
475
563
  "use strict";
564
+ init_schema();
476
565
  init_users();
477
566
  init_user_social_accounts();
478
567
  init_user_public_keys();
@@ -486,8 +575,8 @@ var init_entities = __esm({
486
575
  });
487
576
 
488
577
  // src/server/services/role.service.ts
489
- import { getDatabase as getDatabase6 } from "@spfn/core/db";
490
- import { eq as eq6, and as and6 } from "drizzle-orm";
578
+ import { getDatabase as getDatabase7 } from "@spfn/core/db";
579
+ import { eq as eq7, and as and7 } from "drizzle-orm";
491
580
  var init_role_service = __esm({
492
581
  "src/server/services/role.service.ts"() {
493
582
  "use strict";
@@ -598,8 +687,8 @@ function Clone(value) {
598
687
  }
599
688
 
600
689
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/clone/type.mjs
601
- function CloneType(schema10, options) {
602
- return options === void 0 ? Clone(schema10) : Clone({ ...options, ...schema10 });
690
+ function CloneType(schema, options) {
691
+ return options === void 0 ? Clone(schema) : Clone({ ...options, ...schema });
603
692
  }
604
693
 
605
694
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/value/guard/guard.mjs
@@ -676,8 +765,8 @@ function Immutable(value) {
676
765
  }
677
766
 
678
767
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/create/type.mjs
679
- function CreateType(schema10, options) {
680
- const result = options !== void 0 ? { ...options, ...schema10 } : schema10;
768
+ function CreateType(schema, options) {
769
+ const result = options !== void 0 ? { ...options, ...schema } : schema;
681
770
  switch (TypeSystemPolicy.InstanceMode) {
682
771
  case "freeze":
683
772
  return Immutable(result);
@@ -995,16 +1084,16 @@ function IsBoolean3(value) {
995
1084
  return IsKindOf2(value, "Boolean") && value.type === "boolean" && IsOptionalString(value.$id);
996
1085
  }
997
1086
  function IsComputed2(value) {
998
- return IsKindOf2(value, "Computed") && IsString(value.target) && IsArray(value.parameters) && value.parameters.every((schema10) => IsSchema2(schema10));
1087
+ return IsKindOf2(value, "Computed") && IsString(value.target) && IsArray(value.parameters) && value.parameters.every((schema) => IsSchema2(schema));
999
1088
  }
1000
1089
  function IsConstructor2(value) {
1001
- return IsKindOf2(value, "Constructor") && value.type === "Constructor" && IsOptionalString(value.$id) && IsArray(value.parameters) && value.parameters.every((schema10) => IsSchema2(schema10)) && IsSchema2(value.returns);
1090
+ return IsKindOf2(value, "Constructor") && value.type === "Constructor" && IsOptionalString(value.$id) && IsArray(value.parameters) && value.parameters.every((schema) => IsSchema2(schema)) && IsSchema2(value.returns);
1002
1091
  }
1003
1092
  function IsDate3(value) {
1004
1093
  return IsKindOf2(value, "Date") && value.type === "Date" && IsOptionalString(value.$id) && IsOptionalNumber(value.exclusiveMaximumTimestamp) && IsOptionalNumber(value.exclusiveMinimumTimestamp) && IsOptionalNumber(value.maximumTimestamp) && IsOptionalNumber(value.minimumTimestamp) && IsOptionalNumber(value.multipleOfTimestamp);
1005
1094
  }
1006
1095
  function IsFunction3(value) {
1007
- return IsKindOf2(value, "Function") && value.type === "Function" && IsOptionalString(value.$id) && IsArray(value.parameters) && value.parameters.every((schema10) => IsSchema2(schema10)) && IsSchema2(value.returns);
1096
+ return IsKindOf2(value, "Function") && value.type === "Function" && IsOptionalString(value.$id) && IsArray(value.parameters) && value.parameters.every((schema) => IsSchema2(schema)) && IsSchema2(value.returns);
1008
1097
  }
1009
1098
  function IsImport(value) {
1010
1099
  return IsKindOf2(value, "Import") && HasPropertyKey(value, "$defs") && IsObject(value.$defs) && IsProperties(value.$defs) && HasPropertyKey(value, "$ref") && IsString(value.$ref) && value.$ref in value.$defs;
@@ -1013,10 +1102,10 @@ function IsInteger2(value) {
1013
1102
  return IsKindOf2(value, "Integer") && value.type === "integer" && IsOptionalString(value.$id) && IsOptionalNumber(value.exclusiveMaximum) && IsOptionalNumber(value.exclusiveMinimum) && IsOptionalNumber(value.maximum) && IsOptionalNumber(value.minimum) && IsOptionalNumber(value.multipleOf);
1014
1103
  }
1015
1104
  function IsProperties(value) {
1016
- return IsObject(value) && Object.entries(value).every(([key, schema10]) => IsControlCharacterFree(key) && IsSchema2(schema10));
1105
+ return IsObject(value) && Object.entries(value).every(([key, schema]) => IsControlCharacterFree(key) && IsSchema2(schema));
1017
1106
  }
1018
1107
  function IsIntersect2(value) {
1019
- return IsKindOf2(value, "Intersect") && (IsString(value.type) && value.type !== "object" ? false : true) && IsArray(value.allOf) && value.allOf.every((schema10) => IsSchema2(schema10) && !IsTransform2(schema10)) && IsOptionalString(value.type) && (IsOptionalBoolean(value.unevaluatedProperties) || IsOptionalSchema(value.unevaluatedProperties)) && IsOptionalString(value.$id);
1108
+ return IsKindOf2(value, "Intersect") && (IsString(value.type) && value.type !== "object" ? false : true) && IsArray(value.allOf) && value.allOf.every((schema) => IsSchema2(schema) && !IsTransform2(schema)) && IsOptionalString(value.type) && (IsOptionalBoolean(value.unevaluatedProperties) || IsOptionalSchema(value.unevaluatedProperties)) && IsOptionalString(value.$id);
1020
1109
  }
1021
1110
  function IsIterator3(value) {
1022
1111
  return IsKindOf2(value, "Iterator") && value.type === "Iterator" && IsOptionalString(value.$id) && IsSchema2(value.items);
@@ -1064,9 +1153,9 @@ function IsPromise2(value) {
1064
1153
  return IsKindOf2(value, "Promise") && value.type === "Promise" && IsOptionalString(value.$id) && IsSchema2(value.item);
1065
1154
  }
1066
1155
  function IsRecord2(value) {
1067
- return IsKindOf2(value, "Record") && value.type === "object" && IsOptionalString(value.$id) && IsAdditionalProperties(value.additionalProperties) && IsObject(value.patternProperties) && ((schema10) => {
1068
- const keys = Object.getOwnPropertyNames(schema10.patternProperties);
1069
- return keys.length === 1 && IsPattern(keys[0]) && IsObject(schema10.patternProperties) && IsSchema2(schema10.patternProperties[keys[0]]);
1156
+ return IsKindOf2(value, "Record") && value.type === "object" && IsOptionalString(value.$id) && IsAdditionalProperties(value.additionalProperties) && IsObject(value.patternProperties) && ((schema) => {
1157
+ const keys = Object.getOwnPropertyNames(schema.patternProperties);
1158
+ return keys.length === 1 && IsPattern(keys[0]) && IsObject(schema.patternProperties) && IsSchema2(schema.patternProperties[keys[0]]);
1070
1159
  })(value);
1071
1160
  }
1072
1161
  function IsRecursive(value) {
@@ -1095,16 +1184,16 @@ function IsTransform2(value) {
1095
1184
  }
1096
1185
  function IsTuple2(value) {
1097
1186
  return IsKindOf2(value, "Tuple") && value.type === "array" && IsOptionalString(value.$id) && IsNumber(value.minItems) && IsNumber(value.maxItems) && value.minItems === value.maxItems && // empty
1098
- (IsUndefined(value.items) && IsUndefined(value.additionalItems) && value.minItems === 0 || IsArray(value.items) && value.items.every((schema10) => IsSchema2(schema10)));
1187
+ (IsUndefined(value.items) && IsUndefined(value.additionalItems) && value.minItems === 0 || IsArray(value.items) && value.items.every((schema) => IsSchema2(schema)));
1099
1188
  }
1100
1189
  function IsUndefined4(value) {
1101
1190
  return IsKindOf2(value, "Undefined") && value.type === "undefined" && IsOptionalString(value.$id);
1102
1191
  }
1103
1192
  function IsUnionLiteral(value) {
1104
- return IsUnion2(value) && value.anyOf.every((schema10) => IsLiteralString(schema10) || IsLiteralNumber(schema10));
1193
+ return IsUnion2(value) && value.anyOf.every((schema) => IsLiteralString(schema) || IsLiteralNumber(schema));
1105
1194
  }
1106
1195
  function IsUnion2(value) {
1107
- return IsKindOf2(value, "Union") && IsOptionalString(value.$id) && IsObject(value) && IsArray(value.anyOf) && value.anyOf.every((schema10) => IsSchema2(schema10));
1196
+ return IsKindOf2(value, "Union") && IsOptionalString(value.$id) && IsObject(value) && IsArray(value.anyOf) && value.anyOf.every((schema) => IsSchema2(schema));
1108
1197
  }
1109
1198
  function IsUint8Array3(value) {
1110
1199
  return IsKindOf2(value, "Uint8Array") && value.type === "Uint8Array" && IsOptionalString(value.$id) && IsOptionalNumber(value.minByteLength) && IsOptionalNumber(value.maxByteLength);
@@ -1386,8 +1475,8 @@ function IsTemplateLiteralExpressionFinite(expression) {
1386
1475
  throw new TemplateLiteralFiniteError(`Unknown expression type`);
1387
1476
  })();
1388
1477
  }
1389
- function IsTemplateLiteralFinite(schema10) {
1390
- const expression = TemplateLiteralParseExact(schema10.pattern);
1478
+ function IsTemplateLiteralFinite(schema) {
1479
+ const expression = TemplateLiteralParseExact(schema.pattern);
1391
1480
  return IsTemplateLiteralExpressionFinite(expression);
1392
1481
  }
1393
1482
 
@@ -1418,8 +1507,8 @@ function* TemplateLiteralExpressionGenerate(expression) {
1418
1507
  throw new TemplateLiteralGenerateError("Unknown expression");
1419
1508
  })();
1420
1509
  }
1421
- function TemplateLiteralGenerate(schema10) {
1422
- const expression = TemplateLiteralParseExact(schema10.pattern);
1510
+ function TemplateLiteralGenerate(schema) {
1511
+ const expression = TemplateLiteralParseExact(schema.pattern);
1423
1512
  return IsTemplateLiteralExpressionFinite(expression) ? [...TemplateLiteralExpressionGenerate(expression)] : [];
1424
1513
  }
1425
1514
 
@@ -1495,18 +1584,18 @@ var TemplateLiteralPatternError = class extends TypeBoxError {
1495
1584
  function Escape(value) {
1496
1585
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1497
1586
  }
1498
- function Visit2(schema10, acc) {
1499
- return IsTemplateLiteral(schema10) ? schema10.pattern.slice(1, schema10.pattern.length - 1) : IsUnion(schema10) ? `(${schema10.anyOf.map((schema11) => Visit2(schema11, acc)).join("|")})` : IsNumber3(schema10) ? `${acc}${PatternNumber}` : IsInteger(schema10) ? `${acc}${PatternNumber}` : IsBigInt2(schema10) ? `${acc}${PatternNumber}` : IsString2(schema10) ? `${acc}${PatternString}` : IsLiteral(schema10) ? `${acc}${Escape(schema10.const.toString())}` : IsBoolean2(schema10) ? `${acc}${PatternBoolean}` : (() => {
1500
- throw new TemplateLiteralPatternError(`Unexpected Kind '${schema10[Kind]}'`);
1587
+ function Visit2(schema, acc) {
1588
+ return IsTemplateLiteral(schema) ? schema.pattern.slice(1, schema.pattern.length - 1) : IsUnion(schema) ? `(${schema.anyOf.map((schema2) => Visit2(schema2, acc)).join("|")})` : IsNumber3(schema) ? `${acc}${PatternNumber}` : IsInteger(schema) ? `${acc}${PatternNumber}` : IsBigInt2(schema) ? `${acc}${PatternNumber}` : IsString2(schema) ? `${acc}${PatternString}` : IsLiteral(schema) ? `${acc}${Escape(schema.const.toString())}` : IsBoolean2(schema) ? `${acc}${PatternBoolean}` : (() => {
1589
+ throw new TemplateLiteralPatternError(`Unexpected Kind '${schema[Kind]}'`);
1501
1590
  })();
1502
1591
  }
1503
1592
  function TemplateLiteralPattern(kinds) {
1504
- return `^${kinds.map((schema10) => Visit2(schema10, "")).join("")}$`;
1593
+ return `^${kinds.map((schema) => Visit2(schema, "")).join("")}$`;
1505
1594
  }
1506
1595
 
1507
1596
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/template-literal/union.mjs
1508
- function TemplateLiteralToUnion(schema10) {
1509
- const R = TemplateLiteralGenerate(schema10);
1597
+ function TemplateLiteralToUnion(schema) {
1598
+ const R = TemplateLiteralGenerate(schema);
1510
1599
  const L = R.map((S) => Literal(S));
1511
1600
  return UnionEvaluated(L);
1512
1601
  }
@@ -1643,18 +1732,18 @@ function Promise2(item, options) {
1643
1732
  }
1644
1733
 
1645
1734
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/readonly/readonly.mjs
1646
- function RemoveReadonly(schema10) {
1647
- return CreateType(Discard(schema10, [ReadonlyKind]));
1735
+ function RemoveReadonly(schema) {
1736
+ return CreateType(Discard(schema, [ReadonlyKind]));
1648
1737
  }
1649
- function AddReadonly(schema10) {
1650
- return CreateType({ ...schema10, [ReadonlyKind]: "Readonly" });
1738
+ function AddReadonly(schema) {
1739
+ return CreateType({ ...schema, [ReadonlyKind]: "Readonly" });
1651
1740
  }
1652
- function ReadonlyWithFlag(schema10, F) {
1653
- return F === false ? RemoveReadonly(schema10) : AddReadonly(schema10);
1741
+ function ReadonlyWithFlag(schema, F) {
1742
+ return F === false ? RemoveReadonly(schema) : AddReadonly(schema);
1654
1743
  }
1655
- function Readonly(schema10, enable) {
1744
+ function Readonly(schema, enable) {
1656
1745
  const F = enable ?? true;
1657
- return IsMappedResult(schema10) ? ReadonlyFromMappedResult(schema10, F) : ReadonlyWithFlag(schema10, F);
1746
+ return IsMappedResult(schema) ? ReadonlyFromMappedResult(schema, F) : ReadonlyWithFlag(schema, F);
1658
1747
  }
1659
1748
 
1660
1749
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/readonly/readonly-from-mapped-result.mjs
@@ -1733,18 +1822,18 @@ function Mapped(key, map, options) {
1733
1822
  }
1734
1823
 
1735
1824
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/optional/optional.mjs
1736
- function RemoveOptional(schema10) {
1737
- return CreateType(Discard(schema10, [OptionalKind]));
1825
+ function RemoveOptional(schema) {
1826
+ return CreateType(Discard(schema, [OptionalKind]));
1738
1827
  }
1739
- function AddOptional(schema10) {
1740
- return CreateType({ ...schema10, [OptionalKind]: "Optional" });
1828
+ function AddOptional(schema) {
1829
+ return CreateType({ ...schema, [OptionalKind]: "Optional" });
1741
1830
  }
1742
- function OptionalWithFlag(schema10, F) {
1743
- return F === false ? RemoveOptional(schema10) : AddOptional(schema10);
1831
+ function OptionalWithFlag(schema, F) {
1832
+ return F === false ? RemoveOptional(schema) : AddOptional(schema);
1744
1833
  }
1745
- function Optional(schema10, enable) {
1834
+ function Optional(schema, enable) {
1746
1835
  const F = enable ?? true;
1747
- return IsMappedResult(schema10) ? OptionalFromMappedResult(schema10, F) : OptionalWithFlag(schema10, F);
1836
+ return IsMappedResult(schema) ? OptionalFromMappedResult(schema, F) : OptionalWithFlag(schema, F);
1748
1837
  }
1749
1838
 
1750
1839
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/optional/optional-from-mapped-result.mjs
@@ -1764,7 +1853,7 @@ function OptionalFromMappedResult(R, F) {
1764
1853
 
1765
1854
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/intersect/intersect-create.mjs
1766
1855
  function IntersectCreate(T, options = {}) {
1767
- const allObjects = T.every((schema10) => IsObject3(schema10));
1856
+ const allObjects = T.every((schema) => IsObject3(schema));
1768
1857
  const clonedUnevaluatedProperties = IsSchema(options.unevaluatedProperties) ? { unevaluatedProperties: options.unevaluatedProperties } : {};
1769
1858
  return CreateType(options.unevaluatedProperties === false || IsSchema(options.unevaluatedProperties) || allObjects ? { ...clonedUnevaluatedProperties, [Kind]: "Intersect", type: "object", allOf: T } : { ...clonedUnevaluatedProperties, [Kind]: "Intersect", allOf: T }, options);
1770
1859
  }
@@ -1787,7 +1876,7 @@ function IntersectEvaluated(types, options = {}) {
1787
1876
  return CreateType(types[0], options);
1788
1877
  if (types.length === 0)
1789
1878
  return Never(options);
1790
- if (types.some((schema10) => IsTransform(schema10)))
1879
+ if (types.some((schema) => IsTransform(schema)))
1791
1880
  throw new Error("Cannot intersect transform types");
1792
1881
  return ResolveIntersect(types, options);
1793
1882
  }
@@ -1798,7 +1887,7 @@ function Intersect(types, options) {
1798
1887
  return CreateType(types[0], options);
1799
1888
  if (types.length === 0)
1800
1889
  return Never(options);
1801
- if (types.some((schema10) => IsTransform(schema10)))
1890
+ if (types.some((schema) => IsTransform(schema)))
1802
1891
  throw new Error("Cannot intersect transform types");
1803
1892
  return IntersectCreate(types, options);
1804
1893
  }
@@ -1989,8 +2078,8 @@ function Const(T, options) {
1989
2078
  }
1990
2079
 
1991
2080
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/constructor-parameters/constructor-parameters.mjs
1992
- function ConstructorParameters(schema10, options) {
1993
- return IsConstructor(schema10) ? Tuple(schema10.parameters, options) : Never(options);
2081
+ function ConstructorParameters(schema, options) {
2082
+ return IsConstructor(schema) ? Tuple(schema.parameters, options) : Never(options);
1994
2083
  }
1995
2084
 
1996
2085
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/enum/enum.mjs
@@ -2028,7 +2117,7 @@ function FromAnyRight(left, right) {
2028
2117
  return ExtendsResult.True;
2029
2118
  }
2030
2119
  function FromAny(left, right) {
2031
- return type_exports.IsIntersect(right) ? FromIntersectRight(left, right) : type_exports.IsUnion(right) && right.anyOf.some((schema10) => type_exports.IsAny(schema10) || type_exports.IsUnknown(schema10)) ? ExtendsResult.True : type_exports.IsUnion(right) ? ExtendsResult.Union : type_exports.IsUnknown(right) ? ExtendsResult.True : type_exports.IsAny(right) ? ExtendsResult.True : ExtendsResult.Union;
2120
+ return type_exports.IsIntersect(right) ? FromIntersectRight(left, right) : type_exports.IsUnion(right) && right.anyOf.some((schema) => type_exports.IsAny(schema) || type_exports.IsUnknown(schema)) ? ExtendsResult.True : type_exports.IsUnion(right) ? ExtendsResult.Union : type_exports.IsUnknown(right) ? ExtendsResult.True : type_exports.IsAny(right) ? ExtendsResult.True : ExtendsResult.Union;
2032
2121
  }
2033
2122
  function FromArrayRight(left, right) {
2034
2123
  return type_exports.IsUnknown(left) ? ExtendsResult.False : type_exports.IsAny(left) ? ExtendsResult.Union : type_exports.IsNever(left) ? ExtendsResult.True : ExtendsResult.False;
@@ -2049,13 +2138,13 @@ function FromBoolean(left, right) {
2049
2138
  return IsStructuralRight(right) ? StructuralRight(left, right) : type_exports.IsObject(right) ? FromObjectRight(left, right) : type_exports.IsRecord(right) ? FromRecordRight(left, right) : type_exports.IsBoolean(right) ? ExtendsResult.True : ExtendsResult.False;
2050
2139
  }
2051
2140
  function FromConstructor(left, right) {
2052
- return IsStructuralRight(right) ? StructuralRight(left, right) : type_exports.IsObject(right) ? FromObjectRight(left, right) : !type_exports.IsConstructor(right) ? ExtendsResult.False : left.parameters.length > right.parameters.length ? ExtendsResult.False : !left.parameters.every((schema10, index9) => IntoBooleanResult(Visit3(right.parameters[index9], schema10)) === ExtendsResult.True) ? ExtendsResult.False : IntoBooleanResult(Visit3(left.returns, right.returns));
2141
+ return IsStructuralRight(right) ? StructuralRight(left, right) : type_exports.IsObject(right) ? FromObjectRight(left, right) : !type_exports.IsConstructor(right) ? ExtendsResult.False : left.parameters.length > right.parameters.length ? ExtendsResult.False : !left.parameters.every((schema, index9) => IntoBooleanResult(Visit3(right.parameters[index9], schema)) === ExtendsResult.True) ? ExtendsResult.False : IntoBooleanResult(Visit3(left.returns, right.returns));
2053
2142
  }
2054
2143
  function FromDate(left, right) {
2055
2144
  return IsStructuralRight(right) ? StructuralRight(left, right) : type_exports.IsObject(right) ? FromObjectRight(left, right) : type_exports.IsRecord(right) ? FromRecordRight(left, right) : type_exports.IsDate(right) ? ExtendsResult.True : ExtendsResult.False;
2056
2145
  }
2057
2146
  function FromFunction(left, right) {
2058
- return IsStructuralRight(right) ? StructuralRight(left, right) : type_exports.IsObject(right) ? FromObjectRight(left, right) : !type_exports.IsFunction(right) ? ExtendsResult.False : left.parameters.length > right.parameters.length ? ExtendsResult.False : !left.parameters.every((schema10, index9) => IntoBooleanResult(Visit3(right.parameters[index9], schema10)) === ExtendsResult.True) ? ExtendsResult.False : IntoBooleanResult(Visit3(left.returns, right.returns));
2147
+ return IsStructuralRight(right) ? StructuralRight(left, right) : type_exports.IsObject(right) ? FromObjectRight(left, right) : !type_exports.IsFunction(right) ? ExtendsResult.False : left.parameters.length > right.parameters.length ? ExtendsResult.False : !left.parameters.every((schema, index9) => IntoBooleanResult(Visit3(right.parameters[index9], schema)) === ExtendsResult.True) ? ExtendsResult.False : IntoBooleanResult(Visit3(left.returns, right.returns));
2059
2148
  }
2060
2149
  function FromIntegerRight(left, right) {
2061
2150
  return type_exports.IsLiteral(left) && value_exports.IsNumber(left.const) ? ExtendsResult.True : type_exports.IsNumber(left) || type_exports.IsInteger(left) ? ExtendsResult.True : ExtendsResult.False;
@@ -2064,10 +2153,10 @@ function FromInteger(left, right) {
2064
2153
  return type_exports.IsInteger(right) || type_exports.IsNumber(right) ? ExtendsResult.True : IsStructuralRight(right) ? StructuralRight(left, right) : type_exports.IsObject(right) ? FromObjectRight(left, right) : type_exports.IsRecord(right) ? FromRecordRight(left, right) : ExtendsResult.False;
2065
2154
  }
2066
2155
  function FromIntersectRight(left, right) {
2067
- return right.allOf.every((schema10) => Visit3(left, schema10) === ExtendsResult.True) ? ExtendsResult.True : ExtendsResult.False;
2156
+ return right.allOf.every((schema) => Visit3(left, schema) === ExtendsResult.True) ? ExtendsResult.True : ExtendsResult.False;
2068
2157
  }
2069
2158
  function FromIntersect4(left, right) {
2070
- return left.allOf.some((schema10) => Visit3(schema10, right) === ExtendsResult.True) ? ExtendsResult.True : ExtendsResult.False;
2159
+ return left.allOf.some((schema) => Visit3(schema, right) === ExtendsResult.True) ? ExtendsResult.True : ExtendsResult.False;
2071
2160
  }
2072
2161
  function FromIterator(left, right) {
2073
2162
  return IsStructuralRight(right) ? StructuralRight(left, right) : !type_exports.IsIterator(right) ? ExtendsResult.False : IntoBooleanResult(Visit3(left.items, right.items));
@@ -2081,8 +2170,8 @@ function FromNeverRight(left, right) {
2081
2170
  function FromNever(left, right) {
2082
2171
  return ExtendsResult.True;
2083
2172
  }
2084
- function UnwrapTNot(schema10) {
2085
- let [current, depth] = [schema10, 0];
2173
+ function UnwrapTNot(schema) {
2174
+ let [current, depth] = [schema, 0];
2086
2175
  while (true) {
2087
2176
  if (!type_exports.IsNot(current))
2088
2177
  break;
@@ -2103,44 +2192,44 @@ function FromNumberRight(left, right) {
2103
2192
  function FromNumber(left, right) {
2104
2193
  return IsStructuralRight(right) ? StructuralRight(left, right) : type_exports.IsObject(right) ? FromObjectRight(left, right) : type_exports.IsRecord(right) ? FromRecordRight(left, right) : type_exports.IsInteger(right) || type_exports.IsNumber(right) ? ExtendsResult.True : ExtendsResult.False;
2105
2194
  }
2106
- function IsObjectPropertyCount(schema10, count) {
2107
- return Object.getOwnPropertyNames(schema10.properties).length === count;
2195
+ function IsObjectPropertyCount(schema, count) {
2196
+ return Object.getOwnPropertyNames(schema.properties).length === count;
2108
2197
  }
2109
- function IsObjectStringLike(schema10) {
2110
- return IsObjectArrayLike(schema10);
2198
+ function IsObjectStringLike(schema) {
2199
+ return IsObjectArrayLike(schema);
2111
2200
  }
2112
- function IsObjectSymbolLike(schema10) {
2113
- return IsObjectPropertyCount(schema10, 0) || IsObjectPropertyCount(schema10, 1) && "description" in schema10.properties && type_exports.IsUnion(schema10.properties.description) && schema10.properties.description.anyOf.length === 2 && (type_exports.IsString(schema10.properties.description.anyOf[0]) && type_exports.IsUndefined(schema10.properties.description.anyOf[1]) || type_exports.IsString(schema10.properties.description.anyOf[1]) && type_exports.IsUndefined(schema10.properties.description.anyOf[0]));
2201
+ function IsObjectSymbolLike(schema) {
2202
+ return IsObjectPropertyCount(schema, 0) || IsObjectPropertyCount(schema, 1) && "description" in schema.properties && type_exports.IsUnion(schema.properties.description) && schema.properties.description.anyOf.length === 2 && (type_exports.IsString(schema.properties.description.anyOf[0]) && type_exports.IsUndefined(schema.properties.description.anyOf[1]) || type_exports.IsString(schema.properties.description.anyOf[1]) && type_exports.IsUndefined(schema.properties.description.anyOf[0]));
2114
2203
  }
2115
- function IsObjectNumberLike(schema10) {
2116
- return IsObjectPropertyCount(schema10, 0);
2204
+ function IsObjectNumberLike(schema) {
2205
+ return IsObjectPropertyCount(schema, 0);
2117
2206
  }
2118
- function IsObjectBooleanLike(schema10) {
2119
- return IsObjectPropertyCount(schema10, 0);
2207
+ function IsObjectBooleanLike(schema) {
2208
+ return IsObjectPropertyCount(schema, 0);
2120
2209
  }
2121
- function IsObjectBigIntLike(schema10) {
2122
- return IsObjectPropertyCount(schema10, 0);
2210
+ function IsObjectBigIntLike(schema) {
2211
+ return IsObjectPropertyCount(schema, 0);
2123
2212
  }
2124
- function IsObjectDateLike(schema10) {
2125
- return IsObjectPropertyCount(schema10, 0);
2213
+ function IsObjectDateLike(schema) {
2214
+ return IsObjectPropertyCount(schema, 0);
2126
2215
  }
2127
- function IsObjectUint8ArrayLike(schema10) {
2128
- return IsObjectArrayLike(schema10);
2216
+ function IsObjectUint8ArrayLike(schema) {
2217
+ return IsObjectArrayLike(schema);
2129
2218
  }
2130
- function IsObjectFunctionLike(schema10) {
2219
+ function IsObjectFunctionLike(schema) {
2131
2220
  const length = Number2();
2132
- return IsObjectPropertyCount(schema10, 0) || IsObjectPropertyCount(schema10, 1) && "length" in schema10.properties && IntoBooleanResult(Visit3(schema10.properties["length"], length)) === ExtendsResult.True;
2221
+ return IsObjectPropertyCount(schema, 0) || IsObjectPropertyCount(schema, 1) && "length" in schema.properties && IntoBooleanResult(Visit3(schema.properties["length"], length)) === ExtendsResult.True;
2133
2222
  }
2134
- function IsObjectConstructorLike(schema10) {
2135
- return IsObjectPropertyCount(schema10, 0);
2223
+ function IsObjectConstructorLike(schema) {
2224
+ return IsObjectPropertyCount(schema, 0);
2136
2225
  }
2137
- function IsObjectArrayLike(schema10) {
2226
+ function IsObjectArrayLike(schema) {
2138
2227
  const length = Number2();
2139
- return IsObjectPropertyCount(schema10, 0) || IsObjectPropertyCount(schema10, 1) && "length" in schema10.properties && IntoBooleanResult(Visit3(schema10.properties["length"], length)) === ExtendsResult.True;
2228
+ return IsObjectPropertyCount(schema, 0) || IsObjectPropertyCount(schema, 1) && "length" in schema.properties && IntoBooleanResult(Visit3(schema.properties["length"], length)) === ExtendsResult.True;
2140
2229
  }
2141
- function IsObjectPromiseLike(schema10) {
2230
+ function IsObjectPromiseLike(schema) {
2142
2231
  const then = Function([Any()], Any());
2143
- return IsObjectPropertyCount(schema10, 0) || IsObjectPropertyCount(schema10, 1) && "then" in schema10.properties && IntoBooleanResult(Visit3(schema10.properties["then"], then)) === ExtendsResult.True;
2232
+ return IsObjectPropertyCount(schema, 0) || IsObjectPropertyCount(schema, 1) && "then" in schema.properties && IntoBooleanResult(Visit3(schema.properties["then"], then)) === ExtendsResult.True;
2144
2233
  }
2145
2234
  function Property(left, right) {
2146
2235
  return Visit3(left, right) === ExtendsResult.False ? ExtendsResult.False : type_exports.IsOptional(left) && !type_exports.IsOptional(right) ? ExtendsResult.False : ExtendsResult.True;
@@ -2171,11 +2260,11 @@ function FromObject(left, right) {
2171
2260
  function FromPromise2(left, right) {
2172
2261
  return IsStructuralRight(right) ? StructuralRight(left, right) : type_exports.IsObject(right) && IsObjectPromiseLike(right) ? ExtendsResult.True : !type_exports.IsPromise(right) ? ExtendsResult.False : IntoBooleanResult(Visit3(left.item, right.item));
2173
2262
  }
2174
- function RecordKey(schema10) {
2175
- return PatternNumberExact in schema10.patternProperties ? Number2() : PatternStringExact in schema10.patternProperties ? String2() : Throw("Unknown record key pattern");
2263
+ function RecordKey(schema) {
2264
+ return PatternNumberExact in schema.patternProperties ? Number2() : PatternStringExact in schema.patternProperties ? String2() : Throw("Unknown record key pattern");
2176
2265
  }
2177
- function RecordValue(schema10) {
2178
- return PatternNumberExact in schema10.patternProperties ? schema10.patternProperties[PatternNumberExact] : PatternStringExact in schema10.patternProperties ? schema10.patternProperties[PatternStringExact] : Throw("Unable to get record value schema");
2266
+ function RecordValue(schema) {
2267
+ return PatternNumberExact in schema.patternProperties ? schema.patternProperties[PatternNumberExact] : PatternStringExact in schema.patternProperties ? schema.patternProperties[PatternStringExact] : Throw("Unable to get record value schema");
2179
2268
  }
2180
2269
  function FromRecordRight(left, right) {
2181
2270
  const [Key, Value] = [RecordKey(right), RecordValue(right)];
@@ -2209,13 +2298,13 @@ function FromTemplateLiteral2(left, right) {
2209
2298
  return type_exports.IsTemplateLiteral(left) ? Visit3(TemplateLiteralToUnion(left), right) : type_exports.IsTemplateLiteral(right) ? Visit3(left, TemplateLiteralToUnion(right)) : Throw("Invalid fallthrough for TemplateLiteral");
2210
2299
  }
2211
2300
  function IsArrayOfTuple(left, right) {
2212
- return type_exports.IsArray(right) && left.items !== void 0 && left.items.every((schema10) => Visit3(schema10, right.items) === ExtendsResult.True);
2301
+ return type_exports.IsArray(right) && left.items !== void 0 && left.items.every((schema) => Visit3(schema, right.items) === ExtendsResult.True);
2213
2302
  }
2214
2303
  function FromTupleRight(left, right) {
2215
2304
  return type_exports.IsNever(left) ? ExtendsResult.True : type_exports.IsUnknown(left) ? ExtendsResult.False : type_exports.IsAny(left) ? ExtendsResult.Union : ExtendsResult.False;
2216
2305
  }
2217
2306
  function FromTuple3(left, right) {
2218
- return IsStructuralRight(right) ? StructuralRight(left, right) : type_exports.IsObject(right) && IsObjectArrayLike(right) ? ExtendsResult.True : type_exports.IsArray(right) && IsArrayOfTuple(left, right) ? ExtendsResult.True : !type_exports.IsTuple(right) ? ExtendsResult.False : value_exports.IsUndefined(left.items) && !value_exports.IsUndefined(right.items) || !value_exports.IsUndefined(left.items) && value_exports.IsUndefined(right.items) ? ExtendsResult.False : value_exports.IsUndefined(left.items) && !value_exports.IsUndefined(right.items) ? ExtendsResult.True : left.items.every((schema10, index9) => Visit3(schema10, right.items[index9]) === ExtendsResult.True) ? ExtendsResult.True : ExtendsResult.False;
2307
+ return IsStructuralRight(right) ? StructuralRight(left, right) : type_exports.IsObject(right) && IsObjectArrayLike(right) ? ExtendsResult.True : type_exports.IsArray(right) && IsArrayOfTuple(left, right) ? ExtendsResult.True : !type_exports.IsTuple(right) ? ExtendsResult.False : value_exports.IsUndefined(left.items) && !value_exports.IsUndefined(right.items) || !value_exports.IsUndefined(left.items) && value_exports.IsUndefined(right.items) ? ExtendsResult.False : value_exports.IsUndefined(left.items) && !value_exports.IsUndefined(right.items) ? ExtendsResult.True : left.items.every((schema, index9) => Visit3(schema, right.items[index9]) === ExtendsResult.True) ? ExtendsResult.True : ExtendsResult.False;
2219
2308
  }
2220
2309
  function FromUint8Array(left, right) {
2221
2310
  return IsStructuralRight(right) ? StructuralRight(left, right) : type_exports.IsObject(right) ? FromObjectRight(left, right) : type_exports.IsRecord(right) ? FromRecordRight(left, right) : type_exports.IsUint8Array(right) ? ExtendsResult.True : ExtendsResult.False;
@@ -2224,10 +2313,10 @@ function FromUndefined(left, right) {
2224
2313
  return IsStructuralRight(right) ? StructuralRight(left, right) : type_exports.IsObject(right) ? FromObjectRight(left, right) : type_exports.IsRecord(right) ? FromRecordRight(left, right) : type_exports.IsVoid(right) ? FromVoidRight(left, right) : type_exports.IsUndefined(right) ? ExtendsResult.True : ExtendsResult.False;
2225
2314
  }
2226
2315
  function FromUnionRight(left, right) {
2227
- return right.anyOf.some((schema10) => Visit3(left, schema10) === ExtendsResult.True) ? ExtendsResult.True : ExtendsResult.False;
2316
+ return right.anyOf.some((schema) => Visit3(left, schema) === ExtendsResult.True) ? ExtendsResult.True : ExtendsResult.False;
2228
2317
  }
2229
2318
  function FromUnion6(left, right) {
2230
- return left.anyOf.every((schema10) => Visit3(schema10, right) === ExtendsResult.True) ? ExtendsResult.True : ExtendsResult.False;
2319
+ return left.anyOf.every((schema) => Visit3(schema, right) === ExtendsResult.True) ? ExtendsResult.True : ExtendsResult.False;
2231
2320
  }
2232
2321
  function FromUnknownRight(left, right) {
2233
2322
  return ExtendsResult.True;
@@ -2364,13 +2453,13 @@ function ExtractFromMappedResult(R, T) {
2364
2453
  }
2365
2454
 
2366
2455
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/instance-type/instance-type.mjs
2367
- function InstanceType(schema10, options) {
2368
- return IsConstructor(schema10) ? CreateType(schema10.returns, options) : Never(options);
2456
+ function InstanceType(schema, options) {
2457
+ return IsConstructor(schema) ? CreateType(schema.returns, options) : Never(options);
2369
2458
  }
2370
2459
 
2371
2460
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/readonly-optional/readonly-optional.mjs
2372
- function ReadonlyOptional(schema10) {
2373
- return Readonly(Optional(schema10));
2461
+ function ReadonlyOptional(schema) {
2462
+ return Readonly(Optional(schema));
2374
2463
  }
2375
2464
 
2376
2465
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/record/record.mjs
@@ -2543,11 +2632,11 @@ function ApplyUppercase(value) {
2543
2632
  function ApplyLowercase(value) {
2544
2633
  return value.toLowerCase();
2545
2634
  }
2546
- function FromTemplateLiteral3(schema10, mode, options) {
2547
- const expression = TemplateLiteralParseExact(schema10.pattern);
2635
+ function FromTemplateLiteral3(schema, mode, options) {
2636
+ const expression = TemplateLiteralParseExact(schema.pattern);
2548
2637
  const finite = IsTemplateLiteralExpressionFinite(expression);
2549
2638
  if (!finite)
2550
- return { ...schema10, pattern: FromLiteralValue(schema10.pattern, mode) };
2639
+ return { ...schema, pattern: FromLiteralValue(schema.pattern, mode) };
2551
2640
  const strings = [...TemplateLiteralExpressionGenerate(expression)];
2552
2641
  const literals = strings.map((value) => Literal(value));
2553
2642
  const mapped = FromRest5(literals, mode);
@@ -2560,14 +2649,14 @@ function FromLiteralValue(value, mode) {
2560
2649
  function FromRest5(T, M) {
2561
2650
  return T.map((L) => Intrinsic(L, M));
2562
2651
  }
2563
- function Intrinsic(schema10, mode, options = {}) {
2652
+ function Intrinsic(schema, mode, options = {}) {
2564
2653
  return (
2565
2654
  // Intrinsic-Mapped-Inference
2566
- IsMappedKey(schema10) ? IntrinsicFromMappedKey(schema10, mode, options) : (
2655
+ IsMappedKey(schema) ? IntrinsicFromMappedKey(schema, mode, options) : (
2567
2656
  // Standard-Inference
2568
- IsTemplateLiteral(schema10) ? FromTemplateLiteral3(schema10, mode, options) : IsUnion(schema10) ? Union(FromRest5(schema10.anyOf, mode), options) : IsLiteral(schema10) ? Literal(FromLiteralValue(schema10.const, mode), options) : (
2657
+ IsTemplateLiteral(schema) ? FromTemplateLiteral3(schema, mode, options) : IsUnion(schema) ? Union(FromRest5(schema.anyOf, mode), options) : IsLiteral(schema) ? Literal(FromLiteralValue(schema.const, mode), options) : (
2569
2658
  // Default Type
2570
- CreateType(schema10, options)
2659
+ CreateType(schema, options)
2571
2660
  )
2572
2661
  )
2573
2662
  );
@@ -2964,8 +3053,8 @@ function Not(type, options) {
2964
3053
  }
2965
3054
 
2966
3055
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/parameters/parameters.mjs
2967
- function Parameters(schema10, options) {
2968
- return IsFunction2(schema10) ? Tuple(schema10.parameters, options) : Never();
3056
+ function Parameters(schema, options) {
3057
+ return IsFunction2(schema) ? Tuple(schema.parameters, options) : Never();
2969
3058
  }
2970
3059
 
2971
3060
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/recursive/recursive.mjs
@@ -2993,40 +3082,40 @@ function Rest(T) {
2993
3082
  }
2994
3083
 
2995
3084
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/return-type/return-type.mjs
2996
- function ReturnType(schema10, options) {
2997
- return IsFunction2(schema10) ? CreateType(schema10.returns, options) : Never(options);
3085
+ function ReturnType(schema, options) {
3086
+ return IsFunction2(schema) ? CreateType(schema.returns, options) : Never(options);
2998
3087
  }
2999
3088
 
3000
3089
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/transform/transform.mjs
3001
3090
  var TransformDecodeBuilder = class {
3002
- constructor(schema10) {
3003
- this.schema = schema10;
3091
+ constructor(schema) {
3092
+ this.schema = schema;
3004
3093
  }
3005
3094
  Decode(decode) {
3006
3095
  return new TransformEncodeBuilder(this.schema, decode);
3007
3096
  }
3008
3097
  };
3009
3098
  var TransformEncodeBuilder = class {
3010
- constructor(schema10, decode) {
3011
- this.schema = schema10;
3099
+ constructor(schema, decode) {
3100
+ this.schema = schema;
3012
3101
  this.decode = decode;
3013
3102
  }
3014
- EncodeTransform(encode, schema10) {
3015
- const Encode = (value) => schema10[TransformKind].Encode(encode(value));
3016
- const Decode = (value) => this.decode(schema10[TransformKind].Decode(value));
3103
+ EncodeTransform(encode, schema) {
3104
+ const Encode = (value) => schema[TransformKind].Encode(encode(value));
3105
+ const Decode = (value) => this.decode(schema[TransformKind].Decode(value));
3017
3106
  const Codec = { Encode, Decode };
3018
- return { ...schema10, [TransformKind]: Codec };
3107
+ return { ...schema, [TransformKind]: Codec };
3019
3108
  }
3020
- EncodeSchema(encode, schema10) {
3109
+ EncodeSchema(encode, schema) {
3021
3110
  const Codec = { Decode: this.decode, Encode: encode };
3022
- return { ...schema10, [TransformKind]: Codec };
3111
+ return { ...schema, [TransformKind]: Codec };
3023
3112
  }
3024
3113
  Encode(encode) {
3025
3114
  return IsTransform(this.schema) ? this.EncodeTransform(encode, this.schema) : this.EncodeSchema(encode, this.schema);
3026
3115
  }
3027
3116
  };
3028
- function Transform(schema10) {
3029
- return new TransformDecodeBuilder(schema10);
3117
+ function Transform(schema) {
3118
+ return new TransformDecodeBuilder(schema);
3030
3119
  }
3031
3120
 
3032
3121
  // ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/unsafe/unsafe.mjs
@@ -3404,6 +3493,33 @@ var changePasswordContract = {
3404
3493
  })
3405
3494
  )
3406
3495
  };
3496
+ var getMeContract = {
3497
+ method: "GET",
3498
+ path: "/_auth/me",
3499
+ body: Type.Object({}),
3500
+ response: ApiResponseSchema(
3501
+ Type.Object({
3502
+ userId: Type.String({ description: "User ID" }),
3503
+ email: Type.Optional(Type.String({ description: "User email address" })),
3504
+ phone: Type.Optional(Type.String({ description: "User phone number" })),
3505
+ role: Type.Object({
3506
+ id: Type.Number({ description: "Role ID" }),
3507
+ name: Type.String({ description: "Role name (e.g., user, admin)" }),
3508
+ displayName: Type.String({ description: "Display name for UI" }),
3509
+ priority: Type.Number({ description: "Role priority level" })
3510
+ }, { description: "User role information" }),
3511
+ permissions: Type.Array(
3512
+ Type.Object({
3513
+ id: Type.Number({ description: "Permission ID" }),
3514
+ name: Type.String({ description: "Permission name (e.g., user:delete)" }),
3515
+ displayName: Type.String({ description: "Display name for UI" }),
3516
+ category: Type.Optional(Type.String({ description: "Permission category" }))
3517
+ }),
3518
+ { description: "List of permissions granted through role" }
3519
+ )
3520
+ })
3521
+ )
3522
+ };
3407
3523
 
3408
3524
  // src/lib/contracts/invitation.ts
3409
3525
  var UUID_PATTERN2 = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$";
@@ -3637,45 +3753,8 @@ var deleteInvitationContract = {
3637
3753
  )
3638
3754
  };
3639
3755
 
3640
- // src/server/helpers/jwt.ts
3641
- import jwt from "jsonwebtoken";
3642
- import crypto from "crypto";
3643
- var JWT_SECRET = process.env.SPFN_AUTH_JWT_SECRET || // New prefixed version (recommended)
3644
- process.env.JWT_SECRET || // Legacy fallback
3645
- "dev-secret-key-change-in-production";
3646
- var JWT_EXPIRES_IN = process.env.SPFN_AUTH_JWT_EXPIRES_IN || // New prefixed version (recommended)
3647
- process.env.JWT_EXPIRES_IN || // Legacy fallback
3648
- "7d";
3649
- function verifyClientToken(token, publicKeyB64, algorithm) {
3650
- try {
3651
- const publicKeyDER = Buffer.from(publicKeyB64, "base64");
3652
- const publicKeyObject = crypto.createPublicKey({
3653
- key: publicKeyDER,
3654
- format: "der",
3655
- type: "spki"
3656
- });
3657
- const decoded = jwt.verify(token, publicKeyObject, {
3658
- algorithms: [algorithm],
3659
- // Prevent algorithm confusion attacks
3660
- issuer: "spfn-client"
3661
- // Validate token issuer
3662
- });
3663
- if (typeof decoded === "string") {
3664
- throw new Error("Invalid token format: expected object payload");
3665
- }
3666
- return decoded;
3667
- } catch (error) {
3668
- if (error instanceof jwt.TokenExpiredError) {
3669
- throw new Error("Token has expired");
3670
- }
3671
- if (error instanceof jwt.JsonWebTokenError) {
3672
- throw new Error("Invalid token signature");
3673
- }
3674
- throw new Error(`Token verification failed: ${error instanceof Error ? error.message : "Unknown error"}`);
3675
- }
3676
- }
3677
-
3678
3756
  // src/server/middleware/authenticate.ts
3757
+ init_jwt();
3679
3758
  init_entities();
3680
3759
  import { findOne, getDatabase } from "@spfn/core/db";
3681
3760
 
@@ -3706,9 +3785,8 @@ var KeyExpiredError = class extends UnauthorizedError {
3706
3785
  };
3707
3786
  var AccountDisabledError = class extends ForbiddenError {
3708
3787
  constructor(status = "disabled") {
3709
- super(`Account is ${status}`);
3788
+ super(`Account is ${status}`, { details: { status } });
3710
3789
  this.name = "AccountDisabledError";
3711
- this.details = { status };
3712
3790
  }
3713
3791
  };
3714
3792
 
@@ -3717,14 +3795,16 @@ import { UnauthorizedError as UnauthorizedError2 } from "@spfn/core/errors";
3717
3795
  import { eq, and } from "drizzle-orm";
3718
3796
  async function authenticate(c, next) {
3719
3797
  const authHeader = c.req.header("Authorization");
3720
- const keyId = c.req.header("X-Key-Id");
3721
3798
  if (!authHeader || !authHeader.startsWith("Bearer ")) {
3722
3799
  throw new UnauthorizedError2("Missing or invalid authorization header");
3723
3800
  }
3724
- if (!keyId) {
3725
- throw new UnauthorizedError2("Missing X-Key-Id header");
3726
- }
3727
3801
  const token = authHeader.substring(7);
3802
+ const { decodeToken: decodeToken2 } = await Promise.resolve().then(() => (init_jwt(), jwt_exports));
3803
+ const decoded = decodeToken2(token);
3804
+ if (!decoded || !decoded.keyId) {
3805
+ throw new UnauthorizedError2("Invalid token: missing keyId");
3806
+ }
3807
+ const keyId = decoded.keyId;
3728
3808
  const db = getDatabase();
3729
3809
  const [keyRecord] = await db.select().from(userPublicKeys).where(
3730
3810
  and(
@@ -3783,12 +3863,107 @@ function getAuth(c) {
3783
3863
  init_entities();
3784
3864
  import { getDatabase as getDatabase2 } from "@spfn/core/db";
3785
3865
  import { eq as eq2, and as and2 } from "drizzle-orm";
3866
+ async function getUserPermissions(userId) {
3867
+ const db = getDatabase2();
3868
+ if (!db) {
3869
+ throw new Error("[Auth] Database not initialized");
3870
+ }
3871
+ const userIdNum = typeof userId === "string" ? Number(userId) : Number(userId);
3872
+ const [user] = await db.select({ roleId: users.roleId }).from(users).where(eq2(users.id, userIdNum)).limit(1);
3873
+ if (!user || !user.roleId) {
3874
+ return [];
3875
+ }
3876
+ const permSet = /* @__PURE__ */ new Set();
3877
+ const rolePerms = await db.select({ name: permissions.name }).from(rolePermissions).innerJoin(permissions, eq2(rolePermissions.permissionId, permissions.id)).where(
3878
+ and2(
3879
+ eq2(rolePermissions.roleId, user.roleId),
3880
+ eq2(permissions.isActive, true)
3881
+ )
3882
+ );
3883
+ for (const perm of rolePerms) {
3884
+ permSet.add(perm.name);
3885
+ }
3886
+ const userPerms = await db.select({
3887
+ name: permissions.name,
3888
+ granted: userPermissions.granted,
3889
+ expiresAt: userPermissions.expiresAt
3890
+ }).from(userPermissions).innerJoin(permissions, eq2(userPermissions.permissionId, permissions.id)).where(eq2(userPermissions.userId, userIdNum));
3891
+ const now = /* @__PURE__ */ new Date();
3892
+ for (const userPerm of userPerms) {
3893
+ if (userPerm.expiresAt && userPerm.expiresAt < now) {
3894
+ continue;
3895
+ }
3896
+ if (userPerm.granted) {
3897
+ permSet.add(userPerm.name);
3898
+ } else {
3899
+ permSet.delete(userPerm.name);
3900
+ }
3901
+ }
3902
+ return Array.from(permSet);
3903
+ }
3904
+ async function hasAllPermissions(userId, permissionNames) {
3905
+ const perms = await getUserPermissions(userId);
3906
+ return permissionNames.every((p) => perms.includes(p));
3907
+ }
3908
+ async function hasRole(userId, roleName) {
3909
+ const db = getDatabase2();
3910
+ if (!db) {
3911
+ throw new Error("[Auth] Database not initialized");
3912
+ }
3913
+ const userIdNum = typeof userId === "string" ? Number(userId) : Number(userId);
3914
+ const [user] = await db.select({ roleId: users.roleId }).from(users).where(eq2(users.id, userIdNum)).limit(1);
3915
+ if (!user || !user.roleId) {
3916
+ return false;
3917
+ }
3918
+ const [role] = await db.select({ name: roles.name }).from(roles).where(eq2(roles.id, user.roleId)).limit(1);
3919
+ return role?.name === roleName;
3920
+ }
3921
+ async function hasAnyRole(userId, roleNames) {
3922
+ for (const roleName of roleNames) {
3923
+ if (await hasRole(userId, roleName)) {
3924
+ return true;
3925
+ }
3926
+ }
3927
+ return false;
3928
+ }
3786
3929
 
3787
3930
  // src/server/middleware/require-permission.ts
3788
3931
  import { ForbiddenError as ForbiddenError2 } from "@spfn/core/errors";
3932
+ function requirePermissions(...permissionNames) {
3933
+ return async (c, next) => {
3934
+ const auth = getAuth(c);
3935
+ if (!auth) {
3936
+ throw new ForbiddenError2("Authentication required");
3937
+ }
3938
+ const { userId } = auth;
3939
+ const allowed = await hasAllPermissions(userId, permissionNames);
3940
+ if (!allowed) {
3941
+ throw new ForbiddenError2(
3942
+ `Missing required permissions: ${permissionNames.join(", ")}`
3943
+ );
3944
+ }
3945
+ await next();
3946
+ };
3947
+ }
3789
3948
 
3790
3949
  // src/server/middleware/require-role.ts
3791
3950
  import { ForbiddenError as ForbiddenError3 } from "@spfn/core/errors";
3951
+ function requireRole(...roleNames) {
3952
+ return async (c, next) => {
3953
+ const auth = getAuth(c);
3954
+ if (!auth) {
3955
+ throw new ForbiddenError3("Authentication required");
3956
+ }
3957
+ const { userId } = auth;
3958
+ const allowed = await hasAnyRole(userId, roleNames);
3959
+ if (!allowed) {
3960
+ throw new ForbiddenError3(
3961
+ `Required roles: ${roleNames.join(", ")}`
3962
+ );
3963
+ }
3964
+ await next();
3965
+ };
3966
+ }
3792
3967
 
3793
3968
  // src/server/helpers/password.ts
3794
3969
  import bcrypt from "bcrypt";
@@ -3805,6 +3980,9 @@ async function hashPassword(password) {
3805
3980
  return bcrypt.hash(password, SALT_ROUNDS);
3806
3981
  }
3807
3982
 
3983
+ // src/server/helpers/index.ts
3984
+ init_jwt();
3985
+
3808
3986
  // src/server/helpers/verification.ts
3809
3987
  init_verification_codes();
3810
3988
  import jwt2 from "jsonwebtoken";
@@ -3818,6 +3996,7 @@ import { ValidationError as ValidationError2 } from "@spfn/core/errors";
3818
3996
 
3819
3997
  // src/server/services/key.service.ts
3820
3998
  init_entities();
3999
+ init_jwt();
3821
4000
  import { create as create2, getDatabase as getDatabase4 } from "@spfn/core/db";
3822
4001
  import { eq as eq4, and as and4 } from "drizzle-orm";
3823
4002
 
@@ -3825,18 +4004,25 @@ import { eq as eq4, and as and4 } from "drizzle-orm";
3825
4004
  init_entities();
3826
4005
  import { findOne as findOne2, updateOne } from "@spfn/core/db";
3827
4006
 
3828
- // src/server/services/rbac.service.ts
4007
+ // src/server/services/me.service.ts
3829
4008
  init_entities();
3830
4009
  import { getDatabase as getDatabase5 } from "@spfn/core/db";
3831
- import { eq as eq5, and as and5, inArray } from "drizzle-orm";
4010
+ import { eq as eq5, and as and5 } from "drizzle-orm";
4011
+
4012
+ // src/server/services/rbac.service.ts
4013
+ init_entities();
4014
+ import { getDatabase as getDatabase6 } from "@spfn/core/db";
4015
+ import { logger } from "@spfn/core/logger";
4016
+ import { eq as eq6, and as and6, inArray } from "drizzle-orm";
4017
+ var authLogger = logger.child("@spfn/auth");
3832
4018
 
3833
4019
  // src/server/services/index.ts
3834
4020
  init_role_service();
3835
4021
 
3836
4022
  // src/server/services/invitation.service.ts
3837
4023
  init_entities();
3838
- import { getDatabase as getDatabase7 } from "@spfn/core/db";
3839
- import { eq as eq7, and as and7, lt, desc, sql as sql2 } from "drizzle-orm";
4024
+ import { getDatabase as getDatabase8 } from "@spfn/core/db";
4025
+ import { eq as eq8, and as and8, lt, desc, sql as sql2 } from "drizzle-orm";
3840
4026
  import crypto2 from "crypto";
3841
4027
  function generateInvitationToken() {
3842
4028
  return crypto2.randomUUID();
@@ -3847,7 +4033,7 @@ function calculateExpiresAt(days = 7) {
3847
4033
  return expiresAt;
3848
4034
  }
3849
4035
  async function createInvitation(params) {
3850
- const db = getDatabase7();
4036
+ const db = getDatabase8();
3851
4037
  if (!db) {
3852
4038
  throw new Error("[Auth] Database not initialized");
3853
4039
  }
@@ -3856,24 +4042,24 @@ async function createInvitation(params) {
3856
4042
  if (!emailRegex.test(email)) {
3857
4043
  throw new Error("Invalid email format");
3858
4044
  }
3859
- const existingUser = await db.select().from(users).where(eq7(users.email, email)).limit(1);
4045
+ const existingUser = await db.select().from(users).where(eq8(users.email, email)).limit(1);
3860
4046
  if (existingUser.length > 0) {
3861
4047
  throw new Error("User with this email already exists");
3862
4048
  }
3863
4049
  const existingInvitation = await db.select().from(invitations).where(
3864
- and7(
3865
- eq7(invitations.email, email),
3866
- eq7(invitations.status, "pending")
4050
+ and8(
4051
+ eq8(invitations.email, email),
4052
+ eq8(invitations.status, "pending")
3867
4053
  )
3868
4054
  ).limit(1);
3869
4055
  if (existingInvitation.length > 0) {
3870
4056
  throw new Error("Pending invitation already exists for this email");
3871
4057
  }
3872
- const role = await db.select().from(roles).where(eq7(roles.id, roleId)).limit(1);
4058
+ const role = await db.select().from(roles).where(eq8(roles.id, roleId)).limit(1);
3873
4059
  if (role.length === 0) {
3874
4060
  throw new Error(`Role with id ${roleId} not found`);
3875
4061
  }
3876
- const inviter = await db.select().from(users).where(eq7(users.id, invitedBy)).limit(1);
4062
+ const inviter = await db.select().from(users).where(eq8(users.id, invitedBy)).limit(1);
3877
4063
  if (inviter.length === 0) {
3878
4064
  throw new Error(`User with id ${invitedBy} not found`);
3879
4065
  }
@@ -3892,15 +4078,15 @@ async function createInvitation(params) {
3892
4078
  return invitation;
3893
4079
  }
3894
4080
  async function getInvitationByToken(token) {
3895
- const db = getDatabase7();
4081
+ const db = getDatabase8();
3896
4082
  if (!db) {
3897
4083
  throw new Error("[Auth] Database not initialized");
3898
4084
  }
3899
- const result = await db.select().from(invitations).where(eq7(invitations.token, token)).limit(1);
4085
+ const result = await db.select().from(invitations).where(eq8(invitations.token, token)).limit(1);
3900
4086
  return result[0] || null;
3901
4087
  }
3902
4088
  async function getInvitationWithDetails(token) {
3903
- const db = getDatabase7();
4089
+ const db = getDatabase8();
3904
4090
  if (!db) {
3905
4091
  throw new Error("[Auth] Database not initialized");
3906
4092
  }
@@ -3926,7 +4112,7 @@ async function getInvitationWithDetails(token) {
3926
4112
  id: users.id,
3927
4113
  email: users.email
3928
4114
  }
3929
- }).from(invitations).innerJoin(roles, eq7(invitations.roleId, roles.id)).innerJoin(users, eq7(invitations.invitedBy, users.id)).where(eq7(invitations.token, token)).limit(1);
4115
+ }).from(invitations).innerJoin(roles, eq8(invitations.roleId, roles.id)).innerJoin(users, eq8(invitations.invitedBy, users.id)).where(eq8(invitations.token, token)).limit(1);
3930
4116
  return result[0] || null;
3931
4117
  }
3932
4118
  async function validateInvitation(token) {
@@ -3949,7 +4135,7 @@ async function validateInvitation(token) {
3949
4135
  return { valid: true, invitation };
3950
4136
  }
3951
4137
  async function acceptInvitation(params) {
3952
- const db = getDatabase7();
4138
+ const db = getDatabase8();
3953
4139
  if (!db) {
3954
4140
  throw new Error("[Auth] Database not initialized");
3955
4141
  }
@@ -3959,7 +4145,7 @@ async function acceptInvitation(params) {
3959
4145
  throw new Error(validation.error || "Invalid invitation");
3960
4146
  }
3961
4147
  const invitation = validation.invitation;
3962
- const role = await db.select().from(roles).where(eq7(roles.id, invitation.roleId)).limit(1);
4148
+ const role = await db.select().from(roles).where(eq8(roles.id, invitation.roleId)).limit(1);
3963
4149
  if (role.length === 0) {
3964
4150
  throw new Error("Role not found");
3965
4151
  }
@@ -3989,7 +4175,7 @@ async function acceptInvitation(params) {
3989
4175
  status: "accepted",
3990
4176
  acceptedAt: /* @__PURE__ */ new Date(),
3991
4177
  updatedAt: /* @__PURE__ */ new Date()
3992
- }).where(eq7(invitations.id, invitation.id));
4178
+ }).where(eq8(invitations.id, invitation.id));
3993
4179
  return { newUser, role: role[0] };
3994
4180
  });
3995
4181
  console.log(`[Auth] \u2705 Invitation accepted: ${invitation.email} as ${result.role.name}`);
@@ -4000,7 +4186,7 @@ async function acceptInvitation(params) {
4000
4186
  };
4001
4187
  }
4002
4188
  async function listInvitations(params) {
4003
- const db = getDatabase7();
4189
+ const db = getDatabase8();
4004
4190
  if (!db) {
4005
4191
  throw new Error("[Auth] Database not initialized");
4006
4192
  }
@@ -4008,12 +4194,12 @@ async function listInvitations(params) {
4008
4194
  const offset = (page - 1) * limit;
4009
4195
  const conditions = [];
4010
4196
  if (status) {
4011
- conditions.push(eq7(invitations.status, status));
4197
+ conditions.push(eq8(invitations.status, status));
4012
4198
  }
4013
4199
  if (invitedBy) {
4014
- conditions.push(eq7(invitations.invitedBy, invitedBy));
4200
+ conditions.push(eq8(invitations.invitedBy, invitedBy));
4015
4201
  }
4016
- const whereClause = conditions.length > 0 ? and7(...conditions) : void 0;
4202
+ const whereClause = conditions.length > 0 ? and8(...conditions) : void 0;
4017
4203
  const countResult = await db.select({ count: sql2`count(*)` }).from(invitations).where(whereClause);
4018
4204
  const total = Number(countResult[0]?.count || 0);
4019
4205
  const results = await db.select({
@@ -4038,7 +4224,7 @@ async function listInvitations(params) {
4038
4224
  id: users.id,
4039
4225
  email: users.email
4040
4226
  }
4041
- }).from(invitations).innerJoin(roles, eq7(invitations.roleId, roles.id)).innerJoin(users, eq7(invitations.invitedBy, users.id)).where(whereClause).orderBy(desc(invitations.createdAt)).limit(limit).offset(offset);
4227
+ }).from(invitations).innerJoin(roles, eq8(invitations.roleId, roles.id)).innerJoin(users, eq8(invitations.invitedBy, users.id)).where(whereClause).orderBy(desc(invitations.createdAt)).limit(limit).offset(offset);
4042
4228
  return {
4043
4229
  invitations: results,
4044
4230
  total,
@@ -4048,11 +4234,11 @@ async function listInvitations(params) {
4048
4234
  };
4049
4235
  }
4050
4236
  async function cancelInvitation(id10, cancelledBy, reason) {
4051
- const db = getDatabase7();
4237
+ const db = getDatabase8();
4052
4238
  if (!db) {
4053
4239
  throw new Error("[Auth] Database not initialized");
4054
4240
  }
4055
- const invitation = await db.select().from(invitations).where(eq7(invitations.id, id10)).limit(1);
4241
+ const invitation = await db.select().from(invitations).where(eq8(invitations.id, id10)).limit(1);
4056
4242
  if (invitation.length === 0) {
4057
4243
  throw new Error("Invitation not found");
4058
4244
  }
@@ -4064,23 +4250,23 @@ async function cancelInvitation(id10, cancelledBy, reason) {
4064
4250
  cancelledAt: /* @__PURE__ */ new Date(),
4065
4251
  updatedAt: /* @__PURE__ */ new Date(),
4066
4252
  metadata: invitation[0].metadata ? { ...invitation[0].metadata, cancelReason: reason, cancelledBy } : { cancelReason: reason, cancelledBy }
4067
- }).where(eq7(invitations.id, id10));
4253
+ }).where(eq8(invitations.id, id10));
4068
4254
  console.log(`[Auth] \u26A0\uFE0F Invitation cancelled: ${invitation[0].email} (reason: ${reason || "none"})`);
4069
4255
  }
4070
4256
  async function deleteInvitation(id10) {
4071
- const db = getDatabase7();
4257
+ const db = getDatabase8();
4072
4258
  if (!db) {
4073
4259
  throw new Error("[Auth] Database not initialized");
4074
4260
  }
4075
- await db.delete(invitations).where(eq7(invitations.id, id10));
4261
+ await db.delete(invitations).where(eq8(invitations.id, id10));
4076
4262
  console.log(`[Auth] \u{1F5D1}\uFE0F Invitation deleted: ${id10}`);
4077
4263
  }
4078
4264
  async function resendInvitation(id10, expiresInDays = 7) {
4079
- const db = getDatabase7();
4265
+ const db = getDatabase8();
4080
4266
  if (!db) {
4081
4267
  throw new Error("[Auth] Database not initialized");
4082
4268
  }
4083
- const invitation = await db.select().from(invitations).where(eq7(invitations.id, id10)).limit(1);
4269
+ const invitation = await db.select().from(invitations).where(eq8(invitations.id, id10)).limit(1);
4084
4270
  if (invitation.length === 0) {
4085
4271
  throw new Error("Invitation not found");
4086
4272
  }
@@ -4092,7 +4278,7 @@ async function resendInvitation(id10, expiresInDays = 7) {
4092
4278
  status: "pending",
4093
4279
  expiresAt: newExpiresAt,
4094
4280
  updatedAt: /* @__PURE__ */ new Date()
4095
- }).where(eq7(invitations.id, id10)).returning();
4281
+ }).where(eq8(invitations.id, id10)).returning();
4096
4282
  console.log(`[Auth] \u{1F4E7} Invitation resent: ${invitation[0].email} (new expiry: ${newExpiresAt.toISOString()})`);
4097
4283
  return updated;
4098
4284
  }
@@ -4131,7 +4317,7 @@ app.bind(acceptInvitationContract, async (c) => {
4131
4317
  });
4132
4318
  return c.success(result);
4133
4319
  });
4134
- app.bind(createInvitationContract, [authenticate], async (c) => {
4320
+ app.bind(createInvitationContract, [authenticate, requirePermissions("user:invite")], async (c) => {
4135
4321
  const body = await c.data();
4136
4322
  const { userId } = getAuth(c);
4137
4323
  const invitation = await createInvitation({
@@ -4152,7 +4338,7 @@ app.bind(createInvitationContract, [authenticate], async (c) => {
4152
4338
  invitationUrl
4153
4339
  });
4154
4340
  });
4155
- app.bind(listInvitationsContract, [authenticate], async (c) => {
4341
+ app.bind(listInvitationsContract, [authenticate, requirePermissions("user:read")], async (c) => {
4156
4342
  const query = await c.data();
4157
4343
  const result = await listInvitations({
4158
4344
  status: query.status,
@@ -4171,7 +4357,7 @@ app.bind(listInvitationsContract, [authenticate], async (c) => {
4171
4357
  invitations: formattedInvitations
4172
4358
  });
4173
4359
  });
4174
- app.bind(cancelInvitationContract, [authenticate], async (c) => {
4360
+ app.bind(cancelInvitationContract, [authenticate, requirePermissions("user:invite")], async (c) => {
4175
4361
  const data = await c.data();
4176
4362
  const { userId } = getAuth(c);
4177
4363
  await cancelInvitation(
@@ -4184,7 +4370,7 @@ app.bind(cancelInvitationContract, [authenticate], async (c) => {
4184
4370
  cancelledAt: (/* @__PURE__ */ new Date()).toISOString()
4185
4371
  });
4186
4372
  });
4187
- app.bind(resendInvitationContract, [authenticate], async (c) => {
4373
+ app.bind(resendInvitationContract, [authenticate, requirePermissions("user:invite")], async (c) => {
4188
4374
  const data = await c.data();
4189
4375
  const updated = await resendInvitation(
4190
4376
  data.id,
@@ -4195,7 +4381,7 @@ app.bind(resendInvitationContract, [authenticate], async (c) => {
4195
4381
  expiresAt: updated.expiresAt.toISOString()
4196
4382
  });
4197
4383
  });
4198
- app.bind(deleteInvitationContract, [authenticate], async (c) => {
4384
+ app.bind(deleteInvitationContract, [authenticate, requireRole("superadmin")], async (c) => {
4199
4385
  const data = await c.data();
4200
4386
  await deleteInvitation(data.id);
4201
4387
  return c.success({