@aotter/mantle-cloudflare 0.0.11-alpha.11

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 (99) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +10 -0
  3. package/dist/assets/aotterFavicon.d.ts +2 -0
  4. package/dist/assets/aotterFavicon.d.ts.map +1 -0
  5. package/dist/assets/aotterFavicon.js +5 -0
  6. package/dist/assets/aotterFavicon.js.map +1 -0
  7. package/dist/auth/ConsoleEmailSender.d.ts +15 -0
  8. package/dist/auth/ConsoleEmailSender.d.ts.map +1 -0
  9. package/dist/auth/ConsoleEmailSender.js +19 -0
  10. package/dist/auth/ConsoleEmailSender.js.map +1 -0
  11. package/dist/auth/appleClientSecret.d.ts +70 -0
  12. package/dist/auth/appleClientSecret.d.ts.map +1 -0
  13. package/dist/auth/appleClientSecret.js +111 -0
  14. package/dist/auth/appleClientSecret.js.map +1 -0
  15. package/dist/auth/createAuth.d.ts +176 -0
  16. package/dist/auth/createAuth.d.ts.map +1 -0
  17. package/dist/auth/createAuth.js +360 -0
  18. package/dist/auth/createAuth.js.map +1 -0
  19. package/dist/bindings/AssetsAssetServer.d.ts +14 -0
  20. package/dist/bindings/AssetsAssetServer.d.ts.map +1 -0
  21. package/dist/bindings/AssetsAssetServer.js +20 -0
  22. package/dist/bindings/AssetsAssetServer.js.map +1 -0
  23. package/dist/bindings/D1DatabaseDriver.d.ts +21 -0
  24. package/dist/bindings/D1DatabaseDriver.d.ts.map +1 -0
  25. package/dist/bindings/D1DatabaseDriver.js +126 -0
  26. package/dist/bindings/D1DatabaseDriver.js.map +1 -0
  27. package/dist/bindings/KvCacheBinding.d.ts +14 -0
  28. package/dist/bindings/KvCacheBinding.d.ts.map +1 -0
  29. package/dist/bindings/KvCacheBinding.js +27 -0
  30. package/dist/bindings/KvCacheBinding.js.map +1 -0
  31. package/dist/bindings/R2MediaStorage.d.ts +80 -0
  32. package/dist/bindings/R2MediaStorage.d.ts.map +1 -0
  33. package/dist/bindings/R2MediaStorage.js +189 -0
  34. package/dist/bindings/R2MediaStorage.js.map +1 -0
  35. package/dist/bindings/WorkersQueueHookDispatcher.d.ts +38 -0
  36. package/dist/bindings/WorkersQueueHookDispatcher.d.ts.map +1 -0
  37. package/dist/bindings/WorkersQueueHookDispatcher.js +68 -0
  38. package/dist/bindings/WorkersQueueHookDispatcher.js.map +1 -0
  39. package/dist/bindings/index.d.ts +6 -0
  40. package/dist/bindings/index.d.ts.map +1 -0
  41. package/dist/bindings/index.js +6 -0
  42. package/dist/bindings/index.js.map +1 -0
  43. package/dist/handlers/index.d.ts +2 -0
  44. package/dist/handlers/index.d.ts.map +1 -0
  45. package/dist/handlers/index.js +2 -0
  46. package/dist/handlers/index.js.map +1 -0
  47. package/dist/handlers/turnstile.d.ts +43 -0
  48. package/dist/handlers/turnstile.d.ts.map +1 -0
  49. package/dist/handlers/turnstile.js +71 -0
  50. package/dist/handlers/turnstile.js.map +1 -0
  51. package/dist/index.d.ts +13 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +13 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/mount/bootRuntimeOnce.d.ts +17 -0
  56. package/dist/mount/bootRuntimeOnce.d.ts.map +1 -0
  57. package/dist/mount/bootRuntimeOnce.js +35 -0
  58. package/dist/mount/bootRuntimeOnce.js.map +1 -0
  59. package/dist/mount/cmsConfig.d.ts +33 -0
  60. package/dist/mount/cmsConfig.d.ts.map +1 -0
  61. package/dist/mount/cmsConfig.js +2 -0
  62. package/dist/mount/cmsConfig.js.map +1 -0
  63. package/dist/mount/index.d.ts +6 -0
  64. package/dist/mount/index.d.ts.map +1 -0
  65. package/dist/mount/index.js +5 -0
  66. package/dist/mount/index.js.map +1 -0
  67. package/dist/mount/mountMcp.d.ts +32 -0
  68. package/dist/mount/mountMcp.d.ts.map +1 -0
  69. package/dist/mount/mountMcp.js +107 -0
  70. package/dist/mount/mountMcp.js.map +1 -0
  71. package/dist/mount/mountPublicRoutes.d.ts +82 -0
  72. package/dist/mount/mountPublicRoutes.d.ts.map +1 -0
  73. package/dist/mount/mountPublicRoutes.js +243 -0
  74. package/dist/mount/mountPublicRoutes.js.map +1 -0
  75. package/dist/mount/mountServerEndpoints.d.ts +10 -0
  76. package/dist/mount/mountServerEndpoints.d.ts.map +1 -0
  77. package/dist/mount/mountServerEndpoints.js +503 -0
  78. package/dist/mount/mountServerEndpoints.js.map +1 -0
  79. package/dist/oauth/consentHtml.d.ts +15 -0
  80. package/dist/oauth/consentHtml.d.ts.map +1 -0
  81. package/dist/oauth/consentHtml.js +89 -0
  82. package/dist/oauth/consentHtml.js.map +1 -0
  83. package/dist/oauth/index.d.ts +4 -0
  84. package/dist/oauth/index.d.ts.map +1 -0
  85. package/dist/oauth/index.js +4 -0
  86. package/dist/oauth/index.js.map +1 -0
  87. package/dist/oauth/mountOAuth.d.ts +29 -0
  88. package/dist/oauth/mountOAuth.d.ts.map +1 -0
  89. package/dist/oauth/mountOAuth.js +105 -0
  90. package/dist/oauth/mountOAuth.js.map +1 -0
  91. package/dist/oauth/oauthConstants.d.ts +15 -0
  92. package/dist/oauth/oauthConstants.d.ts.map +1 -0
  93. package/dist/oauth/oauthConstants.js +15 -0
  94. package/dist/oauth/oauthConstants.js.map +1 -0
  95. package/dist/oauth/oauthSingleton.d.ts +34 -0
  96. package/dist/oauth/oauthSingleton.d.ts.map +1 -0
  97. package/dist/oauth/oauthSingleton.js +22 -0
  98. package/dist/oauth/oauthSingleton.js.map +1 -0
  99. package/package.json +61 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createAuth.d.ts","sourceRoot":"","sources":["../../src/auth/createAuth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,360 @@
1
+ import { betterAuth } from "better-auth";
2
+ import { admin, emailOTP, magicLink } from "better-auth/plugins";
3
+ import { createAccessControl } from "better-auth/plugins/access";
4
+ import { defaultStatements } from "better-auth/plugins/admin/access";
5
+ export const ADMIN_ROLES = ["contributor", "editor", "owner"];
6
+ export const ADMIN_ROLE_SET = new Set(ADMIN_ROLES);
7
+ const ac = createAccessControl(defaultStatements);
8
+ const ownerAc = ac.newRole({
9
+ user: defaultStatements.user,
10
+ session: defaultStatements.session,
11
+ });
12
+ const editorAc = ac.newRole({
13
+ user: ["list", "ban", "get", "update"],
14
+ session: ["list", "revoke"],
15
+ });
16
+ const contributorAc = ac.newRole({
17
+ user: ["list", "get"],
18
+ session: [],
19
+ });
20
+ const userAc = ac.newRole({
21
+ user: [],
22
+ session: [],
23
+ });
24
+ /**
25
+ * Keys that `extras` MUST NOT contain — they have first-class fields
26
+ * on `AuthMethodConfig` and / or are managed by this adapter (the
27
+ * github `mapProfileToUser` shim). Allowing them through would let a
28
+ * stray entry shadow credentials or break bootstrap promotion.
29
+ */
30
+ const SOCIAL_EXTRAS_RESERVED_KEYS = new Set([
31
+ "clientId",
32
+ "clientSecret",
33
+ "redirectURI",
34
+ "scope",
35
+ "mapProfileToUser",
36
+ ]);
37
+ /** @internal exported for unit tests; not part of the public API. */
38
+ export function buildSocialProviders(methods) {
39
+ // Better Auth's typed `socialProviders` shape names every provider
40
+ // key individually; assigning by computed string requires an index
41
+ // signature, so we build through a plain map and cast once at the
42
+ // return. The runtime shape matches Better Auth's expectations.
43
+ const out = {};
44
+ for (const method of methods) {
45
+ if (method.kind !== "social")
46
+ continue;
47
+ if (method.extras) {
48
+ for (const key of Object.keys(method.extras)) {
49
+ if (SOCIAL_EXTRAS_RESERVED_KEYS.has(key)) {
50
+ throw new Error(`createAuth: social method '${method.provider}' has reserved key '${key}' in \`extras\`. ` +
51
+ `Use the first-class field instead — \`extras\` is for provider-specific options only.`);
52
+ }
53
+ }
54
+ }
55
+ // GitHub-specific: stash the github login on `user.githubLogin`
56
+ // so `bootstrapOwner: { match: "github-login" }` keeps working.
57
+ // Other providers don't need an analogous shim because bootstrap
58
+ // matches on email for them.
59
+ const githubProfileMapper = method.provider === "github"
60
+ ? {
61
+ mapProfileToUser: (profile) => ({
62
+ githubLogin: profile.login,
63
+ }),
64
+ }
65
+ : {};
66
+ out[method.provider] = {
67
+ clientId: method.clientId,
68
+ clientSecret: method.clientSecret,
69
+ ...(method.redirectURI ? { redirectURI: method.redirectURI } : {}),
70
+ ...(method.scope ? { scope: [...method.scope] } : {}),
71
+ ...(method.extras ?? {}),
72
+ ...githubProfileMapper,
73
+ };
74
+ }
75
+ return out;
76
+ }
77
+ /**
78
+ * First tag off `Accept-Language`, quality values ignored. Locale
79
+ * contract lives in `EmailSender.ts`.
80
+ */
81
+ /** @internal exported for unit tests; not part of the public API. */
82
+ export function pickLocale(req, fallback) {
83
+ const header = req?.headers.get("accept-language");
84
+ if (!header)
85
+ return fallback;
86
+ const first = header.split(",")[0]?.split(";")[0]?.trim();
87
+ return first && first.length > 0 ? first : fallback;
88
+ }
89
+ // Magic-link defaults override Better Auth's tighter built-ins:
90
+ // - 900s (15 min) link TTL — corporate mail (Outlook + Exchange,
91
+ // Mimecast, Proofpoint URL Defense) often has 30-60s delivery
92
+ // lag and users batch-check; 300s shipped too many "expired"
93
+ // receipts. Industry baseline: Slack 60min, Notion / Vercel
94
+ // 24h. We split the difference and let adopters override.
95
+ // - 3 allowed verification attempts — mail prefetchers (Outlook
96
+ // Safe Links, Mimecast URL Protect, Proofpoint URL Defense)
97
+ // routinely consume URLs once before the user opens the email.
98
+ // 1 attempt is genuinely broken on those inboxes.
99
+ const MAGIC_LINK_DEFAULT_EXPIRES_SECONDS = 900;
100
+ const MAGIC_LINK_DEFAULT_ALLOWED_ATTEMPTS = 3;
101
+ function buildMagicLinkPlugin(method) {
102
+ const fallback = method.fallbackLocale ?? "en";
103
+ return magicLink({
104
+ expiresIn: method.expiresInSeconds ?? MAGIC_LINK_DEFAULT_EXPIRES_SECONDS,
105
+ allowedAttempts: method.allowedAttempts ?? MAGIC_LINK_DEFAULT_ALLOWED_ATTEMPTS,
106
+ // Returned synchronously — same fire-and-forget contract as
107
+ // email-otp via `advanced.backgroundTasks.handler`. The body
108
+ // carries the click-URL; SDK doesn't ship a template, the
109
+ // sender can render plain text or richer HTML.
110
+ sendMagicLink: (data, ctx) => {
111
+ const locale = pickLocale(ctx?.request, fallback);
112
+ return method.sender.send({
113
+ to: data.email,
114
+ subject: "Your sign-in link",
115
+ text: `Click to sign in: ${data.url}\nThe link expires shortly. If you didn't request this, ignore this email.`,
116
+ locale,
117
+ category: "auth.magic-link.sign-in",
118
+ });
119
+ },
120
+ });
121
+ }
122
+ function buildEmailOTPPlugin(method) {
123
+ const fallback = method.fallbackLocale ?? "en";
124
+ return emailOTP({
125
+ ...(method.otpLength !== undefined ? { otpLength: method.otpLength } : {}),
126
+ ...(method.expiresInSeconds !== undefined
127
+ ? { expiresIn: method.expiresInSeconds }
128
+ : {}),
129
+ ...(method.allowedAttempts !== undefined
130
+ ? { allowedAttempts: method.allowedAttempts }
131
+ : {}),
132
+ // Return synchronously — the promise is fire-and-forget via the
133
+ // `advanced.backgroundTasks.handler` we wire in `buildAuth`. For
134
+ // `email-verification` / `forget-password` types Better Auth only
135
+ // calls this when the user exists, so awaiting would leak account
136
+ // existence through response latency. See Better Auth's own
137
+ // sendVerificationOTP docstring + reviewer finding in PR #161.
138
+ sendVerificationOTP: (data, ctx) => {
139
+ const locale = pickLocale(ctx?.request, fallback);
140
+ return method.sender.send({
141
+ to: data.email,
142
+ subject: `Your sign-in code: ${data.otp}`,
143
+ text: `Your one-time code is ${data.otp}. It expires shortly. If you didn't request this, ignore this email.`,
144
+ locale,
145
+ category: `auth.email-otp.${data.type}`,
146
+ });
147
+ },
148
+ });
149
+ }
150
+ /**
151
+ * Cross-check bootstrap rule against registered methods. Catches the
152
+ * silent-no-op case where the rule's discriminator can never match
153
+ * any signal a registered method actually produces — e.g.
154
+ * `match: "github-login"` with no `github` method registered. Throws
155
+ * at construction so vibe-coders see the mistake before the first
156
+ * sign-in attempt.
157
+ *
158
+ * `match: "email"` is permissive — every Better Auth method that
159
+ * creates a user populates `email`, including GitHub (via the
160
+ * upstream profile). No registration constraint to enforce.
161
+ */
162
+ /** @internal exported for unit tests; not part of the public API. */
163
+ export function validateBootstrap(rule, methods) {
164
+ if (rule.match === "github-login") {
165
+ const hasGithub = methods.some((m) => m.kind === "social" && m.provider === "github");
166
+ if (!hasGithub) {
167
+ throw new Error("createAuth: bootstrapOwner.match='github-login' but no `social` method with provider='github' is registered. " +
168
+ "Either register a github social method or switch to `bootstrapOwner: { match: 'email', value: '…' }`.");
169
+ }
170
+ }
171
+ }
172
+ /** @internal exported for unit tests; not part of the public API. */
173
+ export function shouldPromoteToOwner(rule, user) {
174
+ const target = rule.value.trim().toLowerCase();
175
+ switch (rule.match) {
176
+ case "github-login":
177
+ return !!user.githubLogin && user.githubLogin.toLowerCase() === target;
178
+ case "email":
179
+ return !!user.email && user.email.toLowerCase() === target;
180
+ }
181
+ }
182
+ /**
183
+ * Find the at-most-one method of `kind`. Throws when adopters register
184
+ * the same kind twice — Better Auth's plugin layer accepts duplicates
185
+ * silently, which would mask the intent at boot. One helper covers
186
+ * every singleton-shaped method (email-otp, magic-link, future ones).
187
+ */
188
+ function pickSingleton(methods, kind) {
189
+ const matches = methods.filter((m) => m.kind === kind);
190
+ if (matches.length > 1) {
191
+ throw new Error(`createAuth: more than one \`${kind}\` method registered. Combine into one.`);
192
+ }
193
+ return matches[0];
194
+ }
195
+ /**
196
+ * Origins each registered social provider needs in
197
+ * `trustedOrigins`. Adding a provider that demands an extra
198
+ * `trustedOrigins` entry = adding a row here. Apple is the only one
199
+ * in 1.6.9 that hard-requires this; if Better Auth ever drops the
200
+ * requirement, the entry stays harmless (Better Auth dedupes).
201
+ */
202
+ const SOCIAL_PROVIDER_TRUSTED_ORIGINS = {
203
+ apple: ["https://appleid.apple.com"],
204
+ };
205
+ function autoTrustedOriginsFor(methods) {
206
+ const origins = methods.flatMap((m) => m.kind === "social" ? SOCIAL_PROVIDER_TRUSTED_ORIGINS[m.provider] ?? [] : []);
207
+ return [...new Set(origins)];
208
+ }
209
+ /**
210
+ * Apple uses `response_mode=form_post` — Apple POSTs cross-site to
211
+ * our callback. The OAuth state cookie must have `sameSite: "none"`
212
+ * (and `secure: true`, which browsers require alongside) or the
213
+ * cookie won't ride the POST and Better Auth raises a state mismatch.
214
+ * Other providers don't need this. We only auto-set when Apple is
215
+ * registered AND the adopter hasn't already specified
216
+ * `defaultCookieAttributes.sameSite` themselves.
217
+ */
218
+ function methodsRequireSameSiteNone(methods) {
219
+ return methods.some((m) => m.kind === "social" && m.provider === "apple");
220
+ }
221
+ function buildAuth(config) {
222
+ if (config.methods.length === 0) {
223
+ throw new Error("createAuth: methods[] is empty — register at least one AuthMethodConfig so staff can sign in.");
224
+ }
225
+ if (config.bootstrapOwner) {
226
+ validateBootstrap(config.bootstrapOwner, config.methods);
227
+ }
228
+ const socialProviders = buildSocialProviders(config.methods);
229
+ const bootstrap = config.bootstrapOwner;
230
+ const emailOtpMethod = pickSingleton(config.methods, "email-otp");
231
+ const magicLinkMethod = pickSingleton(config.methods, "magic-link");
232
+ // Rate limit: Better Auth's per-route limits gate on
233
+ // `process.env.NODE_ENV === "production"`, which is unset on
234
+ // Cloudflare Workers — leaving the limits silently off. When any
235
+ // email-shaped method is wired (free email-send-to-any-address
236
+ // surface) we ALWAYS turn limits on; adopter can override
237
+ // window/max via `config.rateLimit`.
238
+ const hasEmailMethod = !!(emailOtpMethod || magicLinkMethod);
239
+ const rateLimitDefault = hasEmailMethod
240
+ ? { window: 60, max: 10, enabled: true }
241
+ : null;
242
+ const rateLimit = config.rateLimit
243
+ ? { ...config.rateLimit, enabled: true }
244
+ : rateLimitDefault;
245
+ // `trustedOrigins`: per-provider auto-origins (Apple needs
246
+ // `https://appleid.apple.com`). No adopter override — Better Auth
247
+ // configuration is fully owned by the SDK (no escape hatch).
248
+ const trustedOrigins = autoTrustedOriginsFor(config.methods);
249
+ const sdkPlugins = [
250
+ admin({
251
+ defaultRole: "user",
252
+ adminRoles: [...ADMIN_ROLES],
253
+ ac,
254
+ roles: {
255
+ owner: ownerAc,
256
+ editor: editorAc,
257
+ contributor: contributorAc,
258
+ user: userAc,
259
+ },
260
+ }),
261
+ ...(emailOtpMethod ? [buildEmailOTPPlugin(emailOtpMethod)] : []),
262
+ ...(magicLinkMethod ? [buildMagicLinkPlugin(magicLinkMethod)] : []),
263
+ ];
264
+ // `user.additionalFields`: SDK owns `githubLogin` only.
265
+ const userConfig = {
266
+ additionalFields: {
267
+ githubLogin: {
268
+ type: "string",
269
+ required: false,
270
+ input: false,
271
+ },
272
+ },
273
+ };
274
+ // `advanced`: SDK owns `backgroundTasks`. Apple auto-injects
275
+ // `defaultCookieAttributes.sameSite: "none"` because Apple's
276
+ // `form_post` callback is cross-site and a `lax` cookie won't ride
277
+ // it (Better Auth's default raises a state-mismatch).
278
+ const appleNeedsCrossSite = methodsRequireSameSiteNone(config.methods);
279
+ const advancedConfig = {
280
+ ...(appleNeedsCrossSite
281
+ ? {
282
+ // Browsers require `secure: true` whenever `sameSite: "none"`.
283
+ defaultCookieAttributes: { secure: true, sameSite: "none" },
284
+ }
285
+ : {}),
286
+ // Fire-and-forget hook closes the user-existence timing oracle
287
+ // on OTP send — see § "Auth as contract" notes in ADR-0014.
288
+ backgroundTasks: {
289
+ handler: (p) => {
290
+ p.catch((err) => {
291
+ // eslint-disable-next-line no-console
292
+ console.error("[better-auth backgroundTask]", err);
293
+ });
294
+ },
295
+ },
296
+ };
297
+ // `databaseHooks`: SDK owns `user.create.after` for bootstrap-owner
298
+ // promotion (when `bootstrapOwner` is configured).
299
+ const sdkUserCreateAfter = async (user) => {
300
+ if (!bootstrap)
301
+ return;
302
+ const u = user;
303
+ if (!shouldPromoteToOwner(bootstrap, u))
304
+ return;
305
+ // Atomic check-then-promote: the `NOT EXISTS` is a GLOBAL guard —
306
+ // it asks "does any user already hold an admin role?". The whole
307
+ // statement runs as one D1 op, so two concurrent first signups
308
+ // can't both win: the loser's UPDATE finds an admin in the
309
+ // subquery and silently writes zero rows.
310
+ const placeholders = ADMIN_ROLES.map(() => "?").join(",");
311
+ const result = await config.database
312
+ .prepare(`UPDATE user SET role = ? WHERE id = ? AND NOT EXISTS (SELECT 1 FROM user WHERE role IN (${placeholders}))`)
313
+ .bind("owner", u.id, ...ADMIN_ROLES)
314
+ .run();
315
+ if ((result.meta?.changes ?? 0) === 0) {
316
+ // Operator-visible signal that the rule matched but a prior
317
+ // admin already exists — otherwise the silent no-op makes a
318
+ // misconfigured bootstrap rule indistinguishable from a working
319
+ // first-promotion.
320
+ console.warn(`[bootstrap] user ${u.id} matched bootstrapOwner rule but promotion was blocked — an admin user already exists.`);
321
+ }
322
+ };
323
+ const databaseHooks = {
324
+ user: {
325
+ create: { after: sdkUserCreateAfter },
326
+ },
327
+ };
328
+ return betterAuth({
329
+ database: config.database,
330
+ secret: config.secret,
331
+ baseURL: config.baseURL,
332
+ socialProviders,
333
+ user: userConfig,
334
+ ...(rateLimit ? { rateLimit } : {}),
335
+ trustedOrigins,
336
+ advanced: advancedConfig,
337
+ plugins: sdkPlugins,
338
+ databaseHooks,
339
+ });
340
+ }
341
+ export function createAuth(config) {
342
+ const auth = buildAuth(config);
343
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
344
+ const api = auth.api;
345
+ return {
346
+ handler: (request) => auth.handler(request),
347
+ getSession: (request) => api.getSession({ headers: request.headers }).then((r) => r ?? null),
348
+ getUserRole: async (userId) => {
349
+ const row = await config.database
350
+ .prepare("SELECT role FROM user WHERE id = ? LIMIT 1")
351
+ .bind(userId)
352
+ .first();
353
+ return row?.role ?? null;
354
+ },
355
+ methods: config.methods.map((m) => m.kind === "social"
356
+ ? { kind: "social", provider: m.provider }
357
+ : { kind: m.kind }),
358
+ };
359
+ }
360
+ //# sourceMappingURL=createAuth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createAuth.js","sourceRoot":"","sources":["../../src/auth/createAuth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { AssetServer } from "@aotter/mantle-runtime";
2
+ /**
3
+ * `AssetServer` impl wrapping Cloudflare's `ASSETS` binding (a
4
+ * `Fetcher` that serves the worker's bundled static assets). Returns
5
+ * the asset Response, or `null` when the asset is not found so the
6
+ * runtime's HTTP layer can fall back to the SPA's `index.html`
7
+ * catchall (React Router model).
8
+ */
9
+ export declare class AssetsAssetServer implements AssetServer {
10
+ private readonly assets;
11
+ constructor(assets: Fetcher);
12
+ fetch(req: Request): Promise<Response | null>;
13
+ }
14
+ //# sourceMappingURL=AssetsAssetServer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AssetsAssetServer.d.ts","sourceRoot":"","sources":["../../src/bindings/AssetsAssetServer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAE1D;;;;;;GAMG;AACH,qBAAa,iBAAkB,YAAW,WAAW;IACvC,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,OAAO;IAEtC,KAAK,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;CAKpD"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * `AssetServer` impl wrapping Cloudflare's `ASSETS` binding (a
3
+ * `Fetcher` that serves the worker's bundled static assets). Returns
4
+ * the asset Response, or `null` when the asset is not found so the
5
+ * runtime's HTTP layer can fall back to the SPA's `index.html`
6
+ * catchall (React Router model).
7
+ */
8
+ export class AssetsAssetServer {
9
+ assets;
10
+ constructor(assets) {
11
+ this.assets = assets;
12
+ }
13
+ async fetch(req) {
14
+ const res = await this.assets.fetch(req);
15
+ if (res.status === 404)
16
+ return null;
17
+ return res;
18
+ }
19
+ }
20
+ //# sourceMappingURL=AssetsAssetServer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AssetsAssetServer.js","sourceRoot":"","sources":["../../src/bindings/AssetsAssetServer.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,OAAO,iBAAiB;IACC;IAA7B,YAA6B,MAAe;QAAf,WAAM,GAAN,MAAM,CAAS;IAAG,CAAC;IAEhD,KAAK,CAAC,KAAK,CAAC,GAAY;QACtB,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACzC,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG;YAAE,OAAO,IAAI,CAAC;QACpC,OAAO,GAAG,CAAC;IACb,CAAC;CACF"}
@@ -0,0 +1,21 @@
1
+ import type { BatchResult, DatabaseDriver, MigrationRunner, PreparedStatement } from "@aotter/mantle-runtime";
2
+ /**
3
+ * `DatabaseDriver` impl wrapping Cloudflare's `D1Database` binding.
4
+ *
5
+ * The runtime port shape is intentionally close to D1's API (which is
6
+ * itself close to the SQLite C API), so this wrapper is mostly a
7
+ * type-narrowing pass-through. The notable behaviour is the
8
+ * `D1Migrations` runner: it records applied migrations in a
9
+ * `_clam_migrations` table so subsequent boots are idempotent.
10
+ *
11
+ * Per ADR-0011 the runtime never imports `D1Database` itself — this
12
+ * file is the only place in the codebase that does.
13
+ */
14
+ export declare class D1DatabaseDriver implements DatabaseDriver {
15
+ private readonly db;
16
+ readonly migrations: MigrationRunner;
17
+ constructor(db: D1Database);
18
+ prepare(sql: string): PreparedStatement;
19
+ batch(stmts: ReadonlyArray<PreparedStatement>): Promise<readonly BatchResult[]>;
20
+ }
21
+ //# sourceMappingURL=D1DatabaseDriver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"D1DatabaseDriver.d.ts","sourceRoot":"","sources":["../../src/bindings/D1DatabaseDriver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,cAAc,EAEd,eAAe,EACf,iBAAiB,EAElB,MAAM,wBAAwB,CAAC;AAEhC;;;;;;;;;;;GAWG;AACH,qBAAa,gBAAiB,YAAW,cAAc;IAGzC,OAAO,CAAC,QAAQ,CAAC,EAAE;IAF/B,QAAQ,CAAC,UAAU,EAAE,eAAe,CAAC;gBAER,EAAE,EAAE,UAAU;IAI3C,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,iBAAiB;IAIjC,KAAK,CAAC,KAAK,EAAE,aAAa,CAAC,iBAAiB,CAAC,GAAG,OAAO,CAAC,SAAS,WAAW,EAAE,CAAC;CAStF"}
@@ -0,0 +1,126 @@
1
+ /**
2
+ * `DatabaseDriver` impl wrapping Cloudflare's `D1Database` binding.
3
+ *
4
+ * The runtime port shape is intentionally close to D1's API (which is
5
+ * itself close to the SQLite C API), so this wrapper is mostly a
6
+ * type-narrowing pass-through. The notable behaviour is the
7
+ * `D1Migrations` runner: it records applied migrations in a
8
+ * `_clam_migrations` table so subsequent boots are idempotent.
9
+ *
10
+ * Per ADR-0011 the runtime never imports `D1Database` itself — this
11
+ * file is the only place in the codebase that does.
12
+ */
13
+ export class D1DatabaseDriver {
14
+ db;
15
+ migrations;
16
+ constructor(db) {
17
+ this.db = db;
18
+ this.migrations = new D1Migrations(db);
19
+ }
20
+ prepare(sql) {
21
+ return wrap(this.db.prepare(sql));
22
+ }
23
+ async batch(stmts) {
24
+ const native = stmts.map((s) => unwrap(s));
25
+ const results = await this.db.batch(native);
26
+ return results.map((r) => ({
27
+ success: r.success,
28
+ meta: { changes: r.meta.changes ?? 0 },
29
+ results: r.results,
30
+ }));
31
+ }
32
+ }
33
+ const NATIVE = new WeakMap();
34
+ function wrap(native) {
35
+ const stmt = {
36
+ bind: (...params) => wrap(native.bind(...params)),
37
+ first: () => native.first().then((v) => v ?? null),
38
+ all: async () => {
39
+ const r = await native.all();
40
+ return (r.results ?? []);
41
+ },
42
+ run: async () => {
43
+ const r = await native.run();
44
+ return {
45
+ success: r.success,
46
+ meta: { changes: r.meta.changes ?? 0, lastRowId: r.meta.last_row_id },
47
+ };
48
+ },
49
+ };
50
+ NATIVE.set(stmt, native);
51
+ return stmt;
52
+ }
53
+ function unwrap(stmt) {
54
+ const native = NATIVE.get(stmt);
55
+ if (!native) {
56
+ throw new Error("D1DatabaseDriver.batch received a statement not produced by this driver. " +
57
+ "Build statements via `db.prepare(...)` on the same DatabaseDriver instance.");
58
+ }
59
+ return native;
60
+ }
61
+ /**
62
+ * Migration runner. Each migration runs in its own batch — the batch
63
+ * includes the migration's SQL plus the `_clam_migrations` row insert,
64
+ * so a single migration is all-or-nothing. Migrations across boots are
65
+ * NOT transactional: a worker restart between migration N and N+1
66
+ * leaves N applied, N+1 retried on the next boot. Authors must keep
67
+ * each migration's SQL idempotent on retry (use `IF NOT EXISTS`,
68
+ * `INSERT … ON CONFLICT DO NOTHING`, etc.).
69
+ */
70
+ class D1Migrations {
71
+ db;
72
+ constructor(db) {
73
+ this.db = db;
74
+ }
75
+ async runAll(migrations) {
76
+ await this.db
77
+ .prepare(`CREATE TABLE IF NOT EXISTS _migrations (id TEXT PRIMARY KEY, applied_at INTEGER NOT NULL)`)
78
+ .run();
79
+ // One-time copy from pre-rename `_clam_migrations`: idempotent
80
+ // via `INSERT OR IGNORE` + `IF EXISTS`, so re-running on every
81
+ // boot is harmless after the rows have landed. We deliberately
82
+ // DON'T drop the legacy table — codex CX1 showed that any
83
+ // copy-then-drop ordering races between concurrent boots
84
+ // (Worker B's INSERT runs after Worker A's DROP succeeds and
85
+ // crashes with `no such table`). Leaving the legacy table
86
+ // around costs a few KB; eliminating it isn't worth the race
87
+ // class. A standalone op (`mantle migrate drop-legacy`) can
88
+ // remove it later under operator control if desired.
89
+ const legacy = await this.db
90
+ .prepare(`SELECT name FROM sqlite_master WHERE type='table' AND name='_clam_migrations'`)
91
+ .first();
92
+ if (legacy) {
93
+ await this.db
94
+ .prepare(`INSERT OR IGNORE INTO _migrations (id, applied_at) SELECT id, applied_at FROM _clam_migrations`)
95
+ .run();
96
+ }
97
+ const applied = await this.db
98
+ .prepare(`SELECT id FROM _migrations`)
99
+ .all();
100
+ const seen = new Set((applied.results ?? []).map((r) => r.id));
101
+ for (const m of migrations) {
102
+ if (seen.has(m.id))
103
+ continue;
104
+ const statements = splitSql(m.sql);
105
+ const ops = statements.map((s) => this.db.prepare(s));
106
+ ops.push(this.db
107
+ .prepare(`INSERT INTO _migrations (id, applied_at) VALUES (?, ?)`)
108
+ .bind(m.id, Date.now()));
109
+ await this.db.batch(ops);
110
+ }
111
+ }
112
+ }
113
+ /**
114
+ * D1 / SQLite accept multi-statement SQL on the wire, but `.batch`
115
+ * expects each statement separately. Splitting on `;` is correct for
116
+ * our migration corpus (DDL + INSERT seeds, no string literals
117
+ * containing `;`). When that ever stops being true, switch to a
118
+ * lexer-aware split.
119
+ */
120
+ function splitSql(sql) {
121
+ return sql
122
+ .split(";")
123
+ .map((s) => s.trim())
124
+ .filter((s) => s.length > 0);
125
+ }
126
+ //# sourceMappingURL=D1DatabaseDriver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"D1DatabaseDriver.js","sourceRoot":"","sources":["../../src/bindings/D1DatabaseDriver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { KvCache, KvListResult, KvPutOptions } from "@aotter/mantle-runtime";
2
+ /**
3
+ * `KvCache` impl wrapping Cloudflare Workers KV. Pure pass-through —
4
+ * the port shape is a strict subset of the KV namespace API.
5
+ */
6
+ export declare class KvCacheBinding implements KvCache {
7
+ private readonly kv;
8
+ constructor(kv: KVNamespace);
9
+ get(key: string): Promise<string | null>;
10
+ put(key: string, value: string, opts?: KvPutOptions): Promise<void>;
11
+ delete(key: string): Promise<void>;
12
+ list(prefix: string, cursor?: string | null): Promise<KvListResult>;
13
+ }
14
+ //# sourceMappingURL=KvCacheBinding.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"KvCacheBinding.d.ts","sourceRoot":"","sources":["../../src/bindings/KvCacheBinding.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAElF;;;GAGG;AACH,qBAAa,cAAe,YAAW,OAAO;IAChC,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,WAAW;IAE5C,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAIxC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAInE,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI5B,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC;CAO1E"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * `KvCache` impl wrapping Cloudflare Workers KV. Pure pass-through —
3
+ * the port shape is a strict subset of the KV namespace API.
4
+ */
5
+ export class KvCacheBinding {
6
+ kv;
7
+ constructor(kv) {
8
+ this.kv = kv;
9
+ }
10
+ get(key) {
11
+ return this.kv.get(key, "text");
12
+ }
13
+ put(key, value, opts) {
14
+ return this.kv.put(key, value, opts ? { expirationTtl: opts.expirationTtl } : undefined);
15
+ }
16
+ delete(key) {
17
+ return this.kv.delete(key);
18
+ }
19
+ async list(prefix, cursor) {
20
+ const r = await this.kv.list({ prefix, cursor: cursor ?? undefined });
21
+ return {
22
+ keys: r.keys.map((k) => k.name),
23
+ cursor: r.list_complete ? null : r.cursor ?? null,
24
+ };
25
+ }
26
+ }
27
+ //# sourceMappingURL=KvCacheBinding.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"KvCacheBinding.js","sourceRoot":"","sources":["../../src/bindings/KvCacheBinding.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,OAAO,cAAc;IACI;IAA7B,YAA6B,EAAe;QAAf,OAAE,GAAF,EAAE,CAAa;IAAG,CAAC;IAEhD,GAAG,CAAC,GAAW;QACb,OAAO,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAClC,CAAC;IAED,GAAG,CAAC,GAAW,EAAE,KAAa,EAAE,IAAmB;QACjD,OAAO,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAC3F,CAAC;IAED,MAAM,CAAC,GAAW;QAChB,OAAO,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,MAAc,EAAE,MAAsB;QAC/C,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,IAAI,SAAS,EAAE,CAAC,CAAC;QACtE,OAAO;YACL,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;YAC/B,MAAM,EAAE,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,IAAI;SAClD,CAAC;IACJ,CAAC;CACF"}