@access-dlsu/leapify 0.260505.5 → 0.260507.1

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 (199) hide show
  1. package/dist/app.d.ts +15 -0
  2. package/dist/app.d.ts.map +1 -0
  3. package/dist/auth/auth.d.ts +99 -0
  4. package/dist/auth/auth.d.ts.map +1 -0
  5. package/dist/auth/middleware.d.ts +20 -0
  6. package/dist/auth/middleware.d.ts.map +1 -0
  7. package/dist/auth/types.d.ts +17 -0
  8. package/dist/auth/types.d.ts.map +1 -0
  9. package/dist/bun-sqlite-dialect-na--YwnN-NIYANHVJ.cjs +162 -0
  10. package/dist/bun-sqlite-dialect-na--YwnN-NIYANHVJ.cjs.map +1 -0
  11. package/dist/bun-sqlite-dialect-na--YwnN-XVQNOKSL.js +160 -0
  12. package/dist/bun-sqlite-dialect-na--YwnN-XVQNOKSL.js.map +1 -0
  13. package/dist/chunk-4DPT2KQR.cjs +467 -0
  14. package/dist/chunk-4DPT2KQR.cjs.map +1 -0
  15. package/dist/chunk-5JKLV7IE.cjs +2962 -0
  16. package/dist/chunk-5JKLV7IE.cjs.map +1 -0
  17. package/dist/chunk-5OQD5ALM.cjs +76 -0
  18. package/dist/chunk-5OQD5ALM.cjs.map +1 -0
  19. package/dist/{chunk-FLR7TNLN.js → chunk-63CUZGSZ.js} +4 -12
  20. package/dist/chunk-63CUZGSZ.js.map +1 -0
  21. package/dist/chunk-6MMWL46O.cjs +7170 -0
  22. package/dist/chunk-6MMWL46O.cjs.map +1 -0
  23. package/dist/chunk-ANNHE3PZ.js +2285 -0
  24. package/dist/chunk-ANNHE3PZ.js.map +1 -0
  25. package/dist/chunk-EGRHWZRV.js +3 -0
  26. package/dist/chunk-EGRHWZRV.js.map +1 -0
  27. package/dist/chunk-EMMSS5I5.cjs +37 -0
  28. package/dist/chunk-EMMSS5I5.cjs.map +1 -0
  29. package/dist/chunk-FUCJEA2S.js +6196 -0
  30. package/dist/chunk-FUCJEA2S.js.map +1 -0
  31. package/dist/chunk-G3PMV62Z.js +33 -0
  32. package/dist/chunk-G3PMV62Z.js.map +1 -0
  33. package/dist/chunk-GNRL67OU.js +2949 -0
  34. package/dist/chunk-GNRL67OU.js.map +1 -0
  35. package/dist/chunk-HHNEB7YR.js +8 -0
  36. package/dist/chunk-HHNEB7YR.js.map +1 -0
  37. package/dist/chunk-IQEWVHLM.js +889 -0
  38. package/dist/chunk-IQEWVHLM.js.map +1 -0
  39. package/dist/chunk-JIZPYG6H.js +72 -0
  40. package/dist/chunk-JIZPYG6H.js.map +1 -0
  41. package/dist/chunk-JPVIXCF5.cjs +10 -0
  42. package/dist/chunk-JPVIXCF5.cjs.map +1 -0
  43. package/dist/chunk-JQSZJWBN.cjs +3075 -0
  44. package/dist/chunk-JQSZJWBN.cjs.map +1 -0
  45. package/dist/chunk-MNEW2V4T.js +447 -0
  46. package/dist/chunk-MNEW2V4T.js.map +1 -0
  47. package/dist/chunk-MY37YE52.js +3034 -0
  48. package/dist/chunk-MY37YE52.js.map +1 -0
  49. package/dist/chunk-NKIQRCOM.cjs +4 -0
  50. package/dist/chunk-NKIQRCOM.cjs.map +1 -0
  51. package/dist/chunk-OK6RVPEH.cjs +6200 -0
  52. package/dist/chunk-OK6RVPEH.cjs.map +1 -0
  53. package/dist/chunk-QARF2YFF.cjs +2296 -0
  54. package/dist/chunk-QARF2YFF.cjs.map +1 -0
  55. package/dist/chunk-RFP2X2FA.cjs +903 -0
  56. package/dist/chunk-RFP2X2FA.cjs.map +1 -0
  57. package/dist/chunk-XJSWMHDL.js +7142 -0
  58. package/dist/chunk-XJSWMHDL.js.map +1 -0
  59. package/dist/{chunk-3ZWIJNZG.cjs → chunk-YFJBE3AU.cjs} +4 -12
  60. package/dist/chunk-YFJBE3AU.cjs.map +1 -0
  61. package/dist/client/{index.d.cts → auth.d.ts} +140 -394
  62. package/dist/client/auth.d.ts.map +1 -0
  63. package/dist/client/index.cjs +909 -48
  64. package/dist/client/index.cjs.map +1 -1
  65. package/dist/client/index.d.ts +83 -1134
  66. package/dist/client/index.d.ts.map +1 -0
  67. package/dist/client/index.js +908 -47
  68. package/dist/client/index.js.map +1 -1
  69. package/dist/client/pow.d.ts +28 -0
  70. package/dist/client/pow.d.ts.map +1 -0
  71. package/dist/client/session.d.ts +29 -0
  72. package/dist/client/session.d.ts.map +1 -0
  73. package/dist/client/types.d.ts +58 -38
  74. package/dist/client/types.d.ts.map +1 -0
  75. package/dist/cron/batch-release.d.ts +9 -0
  76. package/dist/cron/batch-release.d.ts.map +1 -0
  77. package/dist/cron/lifecycle-check.d.ts +10 -0
  78. package/dist/cron/lifecycle-check.d.ts.map +1 -0
  79. package/dist/cron/reconcile-slots.d.ts +10 -0
  80. package/dist/cron/reconcile-slots.d.ts.map +1 -0
  81. package/dist/cron/reminder-emails.d.ts +9 -0
  82. package/dist/cron/reminder-emails.d.ts.map +1 -0
  83. package/dist/cron/renew-watches.d.ts +9 -0
  84. package/dist/cron/renew-watches.d.ts.map +1 -0
  85. package/dist/d1-sqlite-dialect-C2B7YsIT-6TVV7EJ5.js +122 -0
  86. package/dist/d1-sqlite-dialect-C2B7YsIT-6TVV7EJ5.js.map +1 -0
  87. package/dist/d1-sqlite-dialect-C2B7YsIT-PE74FLHQ.cjs +124 -0
  88. package/dist/d1-sqlite-dialect-C2B7YsIT-PE74FLHQ.cjs.map +1 -0
  89. package/dist/db/index.d.ts +7 -0
  90. package/dist/db/index.d.ts.map +1 -0
  91. package/dist/db/migrate.d.ts +23 -0
  92. package/dist/db/migrate.d.ts.map +1 -0
  93. package/dist/db/schema/auth.d.ts +649 -0
  94. package/dist/db/schema/auth.d.ts.map +1 -0
  95. package/dist/db/schema/bookmarks.d.ts +88 -0
  96. package/dist/db/schema/bookmarks.d.ts.map +1 -0
  97. package/dist/db/schema/events.d.ts +546 -0
  98. package/dist/db/schema/events.d.ts.map +1 -0
  99. package/dist/db/schema/faqs.d.ts +137 -0
  100. package/dist/db/schema/faqs.d.ts.map +1 -0
  101. package/dist/db/schema/index.d.ts +9 -0
  102. package/dist/db/schema/index.d.ts.map +1 -0
  103. package/dist/db/schema/organizations.d.ts +125 -0
  104. package/dist/db/schema/organizations.d.ts.map +1 -0
  105. package/dist/db/schema/site-config.d.ts +64 -0
  106. package/dist/db/schema/site-config.d.ts.map +1 -0
  107. package/dist/db/schema/themes.d.ts +104 -0
  108. package/dist/db/schema/themes.d.ts.map +1 -0
  109. package/dist/{types-lTjxCp88.d.cts → db/schema/users.d.ts} +11 -96
  110. package/dist/db/schema/users.d.ts.map +1 -0
  111. package/dist/dist-DZHA5VYX.cjs +260 -0
  112. package/dist/dist-DZHA5VYX.cjs.map +1 -0
  113. package/dist/dist-RRQUBLLO.js +258 -0
  114. package/dist/dist-RRQUBLLO.js.map +1 -0
  115. package/dist/index.cjs +38065 -937
  116. package/dist/index.cjs.map +1 -1
  117. package/dist/index.d.ts +23 -1818
  118. package/dist/index.d.ts.map +1 -0
  119. package/dist/index.js +37940 -816
  120. package/dist/index.js.map +1 -1
  121. package/dist/kysely-adapter-C76KJVG7.js +10 -0
  122. package/dist/kysely-adapter-C76KJVG7.js.map +1 -0
  123. package/dist/kysely-adapter-TGY4UUP5.cjs +27 -0
  124. package/dist/kysely-adapter-TGY4UUP5.cjs.map +1 -0
  125. package/dist/lib/errors.d.ts +15 -0
  126. package/dist/lib/errors.d.ts.map +1 -0
  127. package/dist/lib/middleware/cors.d.ts +3 -0
  128. package/dist/lib/middleware/cors.d.ts.map +1 -0
  129. package/dist/lib/middleware/error-handler.d.ts +3 -0
  130. package/dist/lib/middleware/error-handler.d.ts.map +1 -0
  131. package/dist/lib/middleware/pow-challenge.cjs +7 -7
  132. package/dist/lib/middleware/pow-challenge.d.ts +29 -18
  133. package/dist/lib/middleware/pow-challenge.d.ts.map +1 -0
  134. package/dist/lib/middleware/pow-challenge.js +2 -2
  135. package/dist/lib/middleware/rate-limit.d.ts +48 -0
  136. package/dist/lib/middleware/rate-limit.d.ts.map +1 -0
  137. package/dist/lib/middleware/referer-guard.d.ts +18 -0
  138. package/dist/lib/middleware/referer-guard.d.ts.map +1 -0
  139. package/dist/lib/retry.d.ts +12 -0
  140. package/dist/lib/retry.d.ts.map +1 -0
  141. package/dist/node-sqlite-dialect-B3H37T3R.cjs +162 -0
  142. package/dist/node-sqlite-dialect-B3H37T3R.cjs.map +1 -0
  143. package/dist/node-sqlite-dialect-GDP7ZE54.js +160 -0
  144. package/dist/node-sqlite-dialect-GDP7ZE54.js.map +1 -0
  145. package/dist/queues/handlers.d.ts +13 -0
  146. package/dist/queues/handlers.d.ts.map +1 -0
  147. package/dist/queues/jobs.d.ts +42 -0
  148. package/dist/queues/jobs.d.ts.map +1 -0
  149. package/dist/routes/events.d.ts +4 -0
  150. package/dist/routes/events.d.ts.map +1 -0
  151. package/dist/routes/faqs.d.ts +4 -0
  152. package/dist/routes/faqs.d.ts.map +1 -0
  153. package/dist/routes/health.d.ts +4 -0
  154. package/dist/routes/health.d.ts.map +1 -0
  155. package/dist/routes/internal/gforms-webhook.d.ts +4 -0
  156. package/dist/routes/internal/gforms-webhook.d.ts.map +1 -0
  157. package/dist/routes/organizations.d.ts +4 -0
  158. package/dist/routes/organizations.d.ts.map +1 -0
  159. package/dist/routes/site-config.d.ts +4 -0
  160. package/dist/routes/site-config.d.ts.map +1 -0
  161. package/dist/routes/themes.d.ts +4 -0
  162. package/dist/routes/themes.d.ts.map +1 -0
  163. package/dist/routes/uploads.d.ts +4 -0
  164. package/dist/routes/uploads.d.ts.map +1 -0
  165. package/dist/routes/users.d.ts +4 -0
  166. package/dist/routes/users.d.ts.map +1 -0
  167. package/dist/services/cache.d.ts +22 -0
  168. package/dist/services/cache.d.ts.map +1 -0
  169. package/dist/services/contentful-management.d.ts +38 -0
  170. package/dist/services/contentful-management.d.ts.map +1 -0
  171. package/dist/services/contentful.d.ts +97 -0
  172. package/dist/services/contentful.d.ts.map +1 -0
  173. package/dist/services/email.d.ts +75 -0
  174. package/dist/services/email.d.ts.map +1 -0
  175. package/dist/services/gforms.d.ts +60 -0
  176. package/dist/services/gforms.d.ts.map +1 -0
  177. package/dist/services/resend.d.ts +35 -0
  178. package/dist/services/resend.d.ts.map +1 -0
  179. package/dist/services/ses.d.ts +58 -0
  180. package/dist/services/ses.d.ts.map +1 -0
  181. package/dist/services/slots.d.ts +48 -0
  182. package/dist/services/slots.d.ts.map +1 -0
  183. package/dist/services/snapshot.d.ts +95 -0
  184. package/dist/services/snapshot.d.ts.map +1 -0
  185. package/dist/types.d.ts +66 -0
  186. package/dist/types.d.ts.map +1 -0
  187. package/dist/worker-handler.d.ts +64 -0
  188. package/dist/worker-handler.d.ts.map +1 -0
  189. package/dist/worker.d.ts +36 -0
  190. package/dist/worker.d.ts.map +1 -0
  191. package/dist/worker.js +1172 -583
  192. package/dist/worker.js.map +1 -1
  193. package/package.json +153 -152
  194. package/dist/chunk-3ZWIJNZG.cjs.map +0 -1
  195. package/dist/chunk-FLR7TNLN.js.map +0 -1
  196. package/dist/client/types.d.cts +0 -192
  197. package/dist/index.d.cts +0 -1879
  198. package/dist/lib/middleware/pow-challenge.d.cts +0 -47
  199. package/dist/types-lTjxCp88.d.ts +0 -208
@@ -0,0 +1,48 @@
1
+ import type { LeapifyDb } from '../db';
2
+ import type { CacheService } from './cache';
3
+ export interface SlotInfo {
4
+ available: number;
5
+ total: number;
6
+ registered: number;
7
+ isFull: boolean;
8
+ }
9
+ /**
10
+ * Manages real-time slot counts using a local D1 counter + KV cache.
11
+ * Google Forms Watch webhook increments the counter; reads go through KV.
12
+ *
13
+ * CF Cache (Cache-Control: public, max-age=5) sits in front of the /slots
14
+ * endpoint, so KV is only read once per 5-second window per edge location.
15
+ */
16
+ export declare class SlotsService {
17
+ private readonly db;
18
+ private readonly cache;
19
+ constructor(db: LeapifyDb, cache: CacheService);
20
+ kvKey(slug: string): string;
21
+ /**
22
+ * Read current slot info — KV first, D1 on miss.
23
+ */
24
+ getSlots(slug: string): Promise<SlotInfo | null>;
25
+ /**
26
+ * Atomically increment registered_slots in D1 and update KV.
27
+ * Called by the Google Forms Watch webhook handler.
28
+ */
29
+ increment(slug: string): Promise<SlotInfo | null>;
30
+ /**
31
+ * Atomically decrement registered_slots in D1 and update KV.
32
+ * Used during reconciliation drift correction (not from user actions).
33
+ */
34
+ decrement(slug: string): Promise<SlotInfo | null>;
35
+ /**
36
+ * Set registered_slots to a specific value (used by reconciliation cron).
37
+ */
38
+ correctCount(slug: string, actualCount: number): Promise<void>;
39
+ /**
40
+ * Read from D1, write to KV, and return slot info.
41
+ */
42
+ refreshFromDb(slug: string): Promise<SlotInfo | null>;
43
+ /**
44
+ * Invalidate the KV cache for a specific event.
45
+ */
46
+ invalidate(slug: string): Promise<void>;
47
+ }
48
+ //# sourceMappingURL=slots.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slots.d.ts","sourceRoot":"","sources":["../../src/services/slots.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAI3C,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,OAAO,CAAA;CAChB;AAED;;;;;;GAMG;AACH,qBAAa,YAAY;IAErB,OAAO,CAAC,QAAQ,CAAC,EAAE;IACnB,OAAO,CAAC,QAAQ,CAAC,KAAK;gBADL,EAAE,EAAE,SAAS,EACb,KAAK,EAAE,YAAY;IAGtC,KAAK,CAAC,IAAI,EAAE,MAAM;IAIlB;;OAEG;IACG,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAStD;;;OAGG;IACG,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IASvD;;;OAGG;IACG,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAWvD;;OAEG;IACG,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASpE;;OAEG;IACG,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAqB3D;;OAEG;IACG,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAG9C"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Contentful → D1 + R2 snapshot service.
3
+ *
4
+ * Pulls published content from Contentful, downloads images into R2
5
+ * (with SHA-256 dedup to skip unchanged files), and upserts rows into D1.
6
+ * Caches fetched Contentful entries in KV to reduce API strain.
7
+ *
8
+ * Called by the `snapshot_content` queue handler and the admin sync endpoint.
9
+ */
10
+ import type { R2Bucket, KVNamespace } from '@cloudflare/workers-types';
11
+ import { ContentfulService } from './contentful';
12
+ import { ContentfulManagement } from './contentful-management';
13
+ import type { LeapifyDb } from '../db';
14
+ export interface SnapshotConfig {
15
+ eventTypeId: string;
16
+ themeTypeId: string;
17
+ faqTypeId: string;
18
+ organizationTypeId: string;
19
+ fields: {
20
+ event: {
21
+ title: string;
22
+ slug: string;
23
+ theme: string;
24
+ organization: string;
25
+ venue: string;
26
+ date: string;
27
+ startTime: string;
28
+ endTime: string;
29
+ price: string;
30
+ image: string;
31
+ isMajor: string;
32
+ maxSlots: string;
33
+ gformsUrl: string;
34
+ gformsEditorUrl: string;
35
+ registrationClosesAt: string;
36
+ classCode: string;
37
+ };
38
+ theme: {
39
+ name: string;
40
+ path: string;
41
+ };
42
+ faq: {
43
+ question: string;
44
+ answer: string;
45
+ category: string;
46
+ sortOrder: string;
47
+ };
48
+ organization: {
49
+ name: string;
50
+ acronym: string;
51
+ logoUrl: string;
52
+ link: string;
53
+ };
54
+ siteConfig: {
55
+ key: string;
56
+ value: string;
57
+ };
58
+ };
59
+ }
60
+ export interface SnapshotResult {
61
+ themesSynced: number;
62
+ eventsSynced: number;
63
+ faqsSynced: number;
64
+ organizationsSynced: number;
65
+ imagesUploaded: number;
66
+ imagesSkipped: number;
67
+ errors: string[];
68
+ }
69
+ /**
70
+ * Run a full Contentful → D1 + R2 snapshot.
71
+ *
72
+ * 1. Fetches all themes, events, and FAQs from Contentful (or KV cache).
73
+ * 2. For each image asset: downloads from Contentful CDN, computes SHA-256,
74
+ * checks R2 for an existing object with the same SHA, and skips the upload
75
+ * if unchanged (dedup).
76
+ * 3. Upserts all entries into D1.
77
+ * 4. Caches fetched Contentful entries in KV for 5 minutes.
78
+ */
79
+ export declare function snapshotAllContent(db: LeapifyDb, bucket: R2Bucket | undefined, contentful: ContentfulService, config?: Partial<SnapshotConfig>, kv?: KVNamespace): Promise<SnapshotResult>;
80
+ /**
81
+ * Ensure all Leapify content types exist in Contentful.
82
+ * Creates them if missing, updates if fields changed.
83
+ *
84
+ * Call this once on first sync or when the schema changes.
85
+ */
86
+ export declare function ensureContentTypes(mgmt: ContentfulManagement, config?: Partial<SnapshotConfig>): Promise<void>;
87
+ /**
88
+ * Push D1 content to Contentful, skipping entities that haven't changed
89
+ * since the last successful push.
90
+ *
91
+ * Uses KV to store the last push timestamp. If `forceFull` is true,
92
+ * pushes all entities regardless of changes.
93
+ */
94
+ export declare function pushToContentful(db: LeapifyDb, mgmt: ContentfulManagement, config?: Partial<SnapshotConfig>, kv?: KVNamespace, forceFull?: boolean): Promise<SnapshotResult>;
95
+ //# sourceMappingURL=snapshot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../../src/services/snapshot.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAA;AAEtE,OAAO,EAAE,iBAAiB,EAA8C,MAAM,cAAc,CAAA;AAC5F,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAA;AAC9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAQtC,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,kBAAkB,EAAE,MAAM,CAAA;IAC1B,MAAM,EAAE;QACN,KAAK,EAAE;YACL,KAAK,EAAE,MAAM,CAAA;YACb,IAAI,EAAE,MAAM,CAAA;YACZ,KAAK,EAAE,MAAM,CAAA;YACb,YAAY,EAAE,MAAM,CAAA;YACpB,KAAK,EAAE,MAAM,CAAA;YACb,IAAI,EAAE,MAAM,CAAA;YACZ,SAAS,EAAE,MAAM,CAAA;YACjB,OAAO,EAAE,MAAM,CAAA;YACf,KAAK,EAAE,MAAM,CAAA;YACb,KAAK,EAAE,MAAM,CAAA;YACb,OAAO,EAAE,MAAM,CAAA;YACf,QAAQ,EAAE,MAAM,CAAA;YAChB,SAAS,EAAE,MAAM,CAAA;YACjB,eAAe,EAAE,MAAM,CAAA;YACvB,oBAAoB,EAAE,MAAM,CAAA;YAC5B,SAAS,EAAE,MAAM,CAAA;SAClB,CAAA;QACD,KAAK,EAAE;YACL,IAAI,EAAE,MAAM,CAAA;YACZ,IAAI,EAAE,MAAM,CAAA;SACb,CAAA;QACD,GAAG,EAAE;YACH,QAAQ,EAAE,MAAM,CAAA;YAChB,MAAM,EAAE,MAAM,CAAA;YACd,QAAQ,EAAE,MAAM,CAAA;YAChB,SAAS,EAAE,MAAM,CAAA;SAClB,CAAA;QACD,YAAY,EAAE;YACZ,IAAI,EAAE,MAAM,CAAA;YACZ,OAAO,EAAE,MAAM,CAAA;YACf,OAAO,EAAE,MAAM,CAAA;YACf,IAAI,EAAE,MAAM,CAAA;SACb,CAAA;QACD,UAAU,EAAE;YACV,GAAG,EAAE,MAAM,CAAA;YACX,KAAK,EAAE,MAAM,CAAA;SACd,CAAA;KACF,CAAA;CACF;AAED,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,MAAM,CAAA;IACpB,UAAU,EAAE,MAAM,CAAA;IAClB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,cAAc,EAAE,MAAM,CAAA;IACtB,aAAa,EAAE,MAAM,CAAA;IACrB,MAAM,EAAE,MAAM,EAAE,CAAA;CACjB;AAkDD;;;;;;;;;GASG;AACH,wBAAsB,kBAAkB,CACtC,EAAE,EAAE,SAAS,EACb,MAAM,EAAE,QAAQ,GAAG,SAAS,EAC5B,UAAU,EAAE,iBAAiB,EAC7B,MAAM,GAAE,OAAO,CAAC,cAAc,CAAM,EACpC,EAAE,CAAC,EAAE,WAAW,GACf,OAAO,CAAC,cAAc,CAAC,CA2HzB;AAkTD;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,oBAAoB,EAC1B,MAAM,GAAE,OAAO,CAAC,cAAc,CAAM,GACnC,OAAO,CAAC,IAAI,CAAC,CA+Cf;AAMD;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CACpC,EAAE,EAAE,SAAS,EACb,IAAI,EAAE,oBAAoB,EAC1B,MAAM,GAAE,OAAO,CAAC,cAAc,CAAM,EACpC,EAAE,CAAC,EAAE,WAAW,EAChB,SAAS,UAAQ,GAChB,OAAO,CAAC,cAAc,CAAC,CAwJzB"}
@@ -0,0 +1,66 @@
1
+ import type { D1Database, KVNamespace, R2Bucket, Queue } from '@cloudflare/workers-types';
2
+ /**
3
+ * Cloudflare bindings expected in the Worker environment.
4
+ * These map directly to wrangler.toml bindings + Worker Secrets.
5
+ */
6
+ export interface LeapifyBindings {
7
+ DB: D1Database;
8
+ KV: KVNamespace;
9
+ FILES?: R2Bucket;
10
+ EMAIL_QUEUE?: Queue;
11
+ /**
12
+ * Standalone mode only: comma-separated list of allowed origins.
13
+ * Example: "https://mysite.com,https://www.mysite.com"
14
+ * In npm module mode, pass allowedOrigins to createLeapify() instead.
15
+ */
16
+ ALLOWED_ORIGINS?: string;
17
+ BETTER_AUTH_SECRET: string;
18
+ /**
19
+ * Public HTTPS base URL of this Worker, used by Better Auth for OAuth redirects.
20
+ * Example: "https://leap.yourdomain.com"
21
+ */
22
+ BETTER_AUTH_URL: string;
23
+ GOOGLE_CLIENT_ID: string;
24
+ GOOGLE_CLIENT_SECRET: string;
25
+ /** Optional Google Workspace hosted domain (e.g. "dlsu.edu.ph"). Restricts the OAuth account picker to this domain. */
26
+ GOOGLE_HD?: string;
27
+ GFORMS_SERVICE_ACCOUNT_JSON: string;
28
+ GFORMS_WEBHOOK_SECRET: string;
29
+ CONTENTFUL_SPACE_ID?: string;
30
+ CONTENTFUL_ACCESS_TOKEN?: string;
31
+ CONTENTFUL_MANAGEMENT_TOKEN?: string;
32
+ CONTENTFUL_ENVIRONMENT?: string;
33
+ SES_REGION?: string;
34
+ SES_ACCESS_KEY_ID?: string;
35
+ SES_SECRET_ACCESS_KEY?: string;
36
+ SES_FROM_ADDRESS?: string;
37
+ EMAIL_FROM_NAME?: string;
38
+ RESEND_API_KEY?: string;
39
+ RESEND_FROM_ADDRESS?: string;
40
+ INTERNAL_API_SECRET: string;
41
+ /** PoW challenge difficulty (leading zero bits). Default: 4. Range: 1-8. */
42
+ POW_DIFFICULTY?: string;
43
+ }
44
+ /**
45
+ * Hono environment type for use across all route handlers.
46
+ */
47
+ export interface LeapifyEnv {
48
+ Bindings: LeapifyBindings;
49
+ Variables: {
50
+ user: import('./auth/types').LeapifyUser;
51
+ gformsWebhookUrl: string | undefined;
52
+ };
53
+ }
54
+ /**
55
+ * Known site_config keys with their value types.
56
+ */
57
+ export interface SiteConfigMap {
58
+ coming_soon_until: number;
59
+ site_ends_at: number;
60
+ site_name: string;
61
+ registration_globally_open: boolean;
62
+ maintenance_mode: boolean;
63
+ snapshot_completed: boolean;
64
+ }
65
+ export type SiteConfigKey = keyof SiteConfigMap;
66
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,WAAW,EACX,QAAQ,EACR,KAAK,EACN,MAAM,2BAA2B,CAAA;AAElC;;;GAGG;AACH,MAAM,WAAW,eAAe;IAE9B,EAAE,EAAE,UAAU,CAAA;IACd,EAAE,EAAE,WAAW,CAAA;IACf,KAAK,CAAC,EAAE,QAAQ,CAAA;IAChB,WAAW,CAAC,EAAE,KAAK,CAAA;IACnB;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;IAGxB,kBAAkB,EAAE,MAAM,CAAA;IAC1B;;;OAGG;IACH,eAAe,EAAE,MAAM,CAAA;IACvB,gBAAgB,EAAE,MAAM,CAAA;IACxB,oBAAoB,EAAE,MAAM,CAAA;IAC5B,uHAAuH;IACvH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,2BAA2B,EAAE,MAAM,CAAA;IACnC,qBAAqB,EAAE,MAAM,CAAA;IAC7B,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,uBAAuB,CAAC,EAAE,MAAM,CAAA;IAChC,2BAA2B,CAAC,EAAE,MAAM,CAAA;IACpC,sBAAsB,CAAC,EAAE,MAAM,CAAA;IAE/B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,eAAe,CAAC,EAAE,MAAM,CAAA;IAExB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,mBAAmB,EAAE,MAAM,CAAA;IAC3B,4EAA4E;IAC5E,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,eAAe,CAAA;IACzB,SAAS,EAAE;QACT,IAAI,EAAE,OAAO,cAAc,EAAE,WAAW,CAAA;QACxC,gBAAgB,EAAE,MAAM,GAAG,SAAS,CAAA;KACrC,CAAA;CACF;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,iBAAiB,EAAE,MAAM,CAAA;IACzB,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,0BAA0B,EAAE,OAAO,CAAA;IACnC,gBAAgB,EAAE,OAAO,CAAA;IACzB,kBAAkB,EAAE,OAAO,CAAA;CAC5B;AAED,MAAM,MAAM,aAAa,GAAG,MAAM,aAAa,CAAA"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Worker handler factory — eliminates duplicated worker entry boilerplate.
3
+ *
4
+ * Encapsulates: API prefix routing, lazy singleton init, config injection,
5
+ * and fetch/scheduled/queue delegation. Consumer provides only the
6
+ * "serve the frontend" callback.
7
+ *
8
+ * Import from 'leapify' — server-only.
9
+ *
10
+ * @example
11
+ * // worker.ts (Angular console)
12
+ * import { createWorkerHandler } from 'leapify'
13
+ * import { AngularAppEngine } from '@angular/ssr'
14
+ *
15
+ * const angularApp = new AngularAppEngine({ ... })
16
+ *
17
+ * export default createWorkerHandler({
18
+ * serveFrontend: async (request, env) => {
19
+ * const res = await angularApp.handle(request, { env })
20
+ * return res ?? new Response('Not found', { status: 404 })
21
+ * },
22
+ * })
23
+ */
24
+ import type { LeapifyBindings } from "./types";
25
+ import type { LeapifyJob } from "./queues/jobs";
26
+ export interface RuntimeConfig {
27
+ production: boolean;
28
+ leapifyApiUrl: string;
29
+ }
30
+ export interface CreateWorkerHandlerOptions {
31
+ /** CORS origins. Falls back to ALLOWED_ORIGINS env var, then ["*"]. */
32
+ allowedOrigins?: string[];
33
+ /**
34
+ * Public HTTPS URL of your Worker.
35
+ * Required for Google Forms Watch push notifications.
36
+ */
37
+ gformsWebhookUrl?: string;
38
+ /**
39
+ * Automatically ensure all required tables exist on first request.
40
+ * Safe for production — idempotent (only runs on fresh databases).
41
+ * @default false
42
+ */
43
+ autoMigrate?: boolean;
44
+ /**
45
+ * Serve the frontend (SSR or static assets).
46
+ * Return a Response for HTML pages, or null for non-HTML requests.
47
+ * The factory handles config injection into HTML responses automatically.
48
+ */
49
+ serveFrontend: (request: Request, env: LeapifyBindings, ctx: ExecutionContext) => Promise<Response | null>;
50
+ /**
51
+ * Build the runtime config object injected into HTML pages.
52
+ * Defaults to extracting LEAPIFY_API_URL and GOOGLE_CLIENT_ID from env.
53
+ */
54
+ getRuntimeConfig?: (env: LeapifyBindings) => RuntimeConfig;
55
+ }
56
+ /**
57
+ * Create a complete Cloudflare Worker handler with API routing + frontend serving.
58
+ */
59
+ export declare function createWorkerHandler(options: CreateWorkerHandlerOptions): {
60
+ fetch(request: Request, env: LeapifyBindings, ctx: ExecutionContext): Promise<Response>;
61
+ scheduled(event: ScheduledEvent, env: LeapifyBindings, ctx: ExecutionContext): Promise<void>;
62
+ queue(batch: MessageBatch<LeapifyJob>, env: LeapifyBindings): Promise<void>;
63
+ };
64
+ //# sourceMappingURL=worker-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-handler.d.ts","sourceRoot":"","sources":["../src/worker-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAmBhD,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,0BAA0B;IACzC,uEAAuE;IACvE,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;OAIG;IACH,aAAa,EAAE,CACb,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,gBAAgB,KAClB,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;IAC9B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,eAAe,KAAK,aAAa,CAAC;CAC5D;AAcD;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,0BAA0B;mBAyBxD,OAAO,OACX,eAAe,OACf,gBAAgB,GACpB,OAAO,CAAC,QAAQ,CAAC;qBAoCX,cAAc,OAChB,eAAe,OACf,gBAAgB,GACpB,OAAO,CAAC,IAAI,CAAC;iBAKP,YAAY,CAAC,UAAU,CAAC,OAC1B,eAAe,GACnB,OAAO,CAAC,IAAI,CAAC;EAInB"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Leapify — Standalone Cloudflare Worker entry point.
3
+ *
4
+ * ─────────────────────────────────────────────────────────────────────
5
+ * MODE 1: Standalone Server (this file)
6
+ * ─────────────────────────────────────────────────────────────────────
7
+ * Deploy Leapify directly as a Cloudflare Worker — no frontend code
8
+ * required. Configure wrangler.toml with your bindings + secrets and run:
9
+ *
10
+ * wrangler deploy
11
+ *
12
+ * CORS is controlled via the ALLOWED_ORIGINS Worker secret:
13
+ * wrangler secret put ALLOWED_ORIGINS
14
+ * # value: "https://yoursite.com,https://www.yoursite.com"
15
+ *
16
+ * ─────────────────────────────────────────────────────────────────────
17
+ * MODE 2: npm module (src/index.ts)
18
+ * ─────────────────────────────────────────────────────────────────────
19
+ * Install leapify into your own project and mount it:
20
+ *
21
+ * npm install leapify
22
+ *
23
+ * import { createLeapify } from 'leapify'
24
+ * export default createLeapify({ allowedOrigins: ['https://yoursite.com'] })
25
+ *
26
+ * See README.md for full mode comparison.
27
+ */
28
+ import type { LeapifyBindings } from './types';
29
+ import type { LeapifyJob } from './queues/jobs';
30
+ declare const leapify: {
31
+ fetch(request: Request, env: LeapifyBindings, ctx: ExecutionContext): Promise<Response>;
32
+ scheduled(event: ScheduledEvent, env: LeapifyBindings, ctx: ExecutionContext): Promise<void>;
33
+ queue(batch: MessageBatch<LeapifyJob>, env: LeapifyBindings): Promise<void>;
34
+ };
35
+ export default leapify;
36
+ //# sourceMappingURL=worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AA8B/C,QAAA,MAAM,OAAO;mBACI,OAAO,OAAO,eAAe,OAAO,gBAAgB,GAAG,OAAO,CAAC,QAAQ,CAAC;qBAIhE,cAAc,OAAO,eAAe,OAAO,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;iBAI/E,YAAY,CAAC,UAAU,CAAC,OAAO,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;CAGlF,CAAC;AAEF,eAAe,OAAO,CAAC"}