appflare 0.0.28 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. package/cli/commands/index.ts +140 -0
  2. package/cli/generate.ts +149 -0
  3. package/cli/index.ts +56 -447
  4. package/cli/load-config.ts +182 -0
  5. package/cli/schema-compiler.ts +657 -0
  6. package/cli/templates/auth/README.md +156 -0
  7. package/cli/templates/auth/config.ts +61 -0
  8. package/cli/templates/auth/route-config.ts +18 -0
  9. package/cli/templates/auth/route-handler.ts +18 -0
  10. package/cli/templates/auth/route-request-utils.ts +55 -0
  11. package/cli/templates/auth/route.ts +14 -0
  12. package/cli/templates/core/README.md +266 -0
  13. package/cli/templates/core/app-creation.ts +19 -0
  14. package/cli/templates/core/client/appflare.ts +37 -0
  15. package/cli/templates/core/client/index.ts +6 -0
  16. package/cli/templates/core/client/storage.ts +100 -0
  17. package/cli/templates/core/client/types.ts +54 -0
  18. package/cli/templates/core/client-modules/appflare.ts +112 -0
  19. package/cli/templates/core/client-modules/handlers/index.ts +740 -0
  20. package/cli/templates/core/client-modules/handlers.ts +1 -0
  21. package/cli/templates/core/client-modules/index.ts +7 -0
  22. package/cli/templates/core/client-modules/storage.ts +180 -0
  23. package/cli/templates/core/client-modules/types.ts +145 -0
  24. package/cli/templates/core/client.ts +39 -0
  25. package/cli/templates/core/drizzle.ts +15 -0
  26. package/cli/templates/core/export.ts +14 -0
  27. package/cli/templates/core/handlers-route.ts +23 -0
  28. package/cli/templates/core/handlers.ts +1 -0
  29. package/cli/templates/core/imports.ts +8 -0
  30. package/cli/templates/core/server.ts +38 -0
  31. package/cli/templates/core/types.ts +6 -0
  32. package/cli/templates/core/wrangler.ts +109 -0
  33. package/cli/templates/handlers/README.md +265 -0
  34. package/cli/templates/handlers/auth.ts +36 -0
  35. package/cli/templates/handlers/execution.ts +39 -0
  36. package/cli/templates/handlers/generators/context/context-creation.ts +80 -0
  37. package/cli/templates/handlers/generators/context/error-helpers.ts +11 -0
  38. package/cli/templates/handlers/generators/context/scheduler.ts +24 -0
  39. package/cli/templates/handlers/generators/context/storage-api.ts +112 -0
  40. package/cli/templates/handlers/generators/context/storage-helpers.ts +59 -0
  41. package/cli/templates/handlers/generators/context/types.ts +18 -0
  42. package/cli/templates/handlers/generators/context.ts +43 -0
  43. package/cli/templates/handlers/generators/execution.ts +15 -0
  44. package/cli/templates/handlers/generators/handlers.ts +13 -0
  45. package/cli/templates/handlers/index.ts +43 -0
  46. package/cli/templates/handlers/operations.ts +116 -0
  47. package/cli/templates/handlers/registration.ts +1114 -0
  48. package/cli/templates/handlers/types.ts +960 -0
  49. package/cli/templates/handlers/utils.ts +48 -0
  50. package/cli/types.ts +108 -0
  51. package/cli/utils/handler-discovery.ts +366 -0
  52. package/cli/utils/json-utils.ts +24 -0
  53. package/cli/utils/path-utils.ts +19 -0
  54. package/cli/utils/schema-discovery.ts +390 -0
  55. package/index.ts +27 -4
  56. package/package.json +23 -20
  57. package/react/index.ts +5 -3
  58. package/react/use-infinite-query.ts +190 -0
  59. package/react/use-mutation.ts +54 -0
  60. package/react/use-query.ts +158 -0
  61. package/schema.ts +262 -0
  62. package/tsconfig.json +2 -4
  63. package/cli/README.md +0 -108
  64. package/cli/core/build.ts +0 -187
  65. package/cli/core/config.ts +0 -92
  66. package/cli/core/discover-handlers.ts +0 -143
  67. package/cli/core/handlers.ts +0 -7
  68. package/cli/core/index.ts +0 -205
  69. package/cli/generators/generate-api-client/client.ts +0 -163
  70. package/cli/generators/generate-api-client/extract-configuration.ts +0 -121
  71. package/cli/generators/generate-api-client/index.ts +0 -973
  72. package/cli/generators/generate-api-client/types.ts +0 -164
  73. package/cli/generators/generate-api-client/utils.ts +0 -22
  74. package/cli/generators/generate-api-client.ts +0 -1
  75. package/cli/generators/generate-cloudflare-worker/helpers.ts +0 -24
  76. package/cli/generators/generate-cloudflare-worker/index.ts +0 -2
  77. package/cli/generators/generate-cloudflare-worker/worker.ts +0 -148
  78. package/cli/generators/generate-cloudflare-worker/wrangler.ts +0 -108
  79. package/cli/generators/generate-cloudflare-worker.ts +0 -4
  80. package/cli/generators/generate-cron-handlers/cron-handlers-block.ts +0 -2
  81. package/cli/generators/generate-cron-handlers/handler-entries.ts +0 -29
  82. package/cli/generators/generate-cron-handlers/index.ts +0 -61
  83. package/cli/generators/generate-cron-handlers/runtime-block.ts +0 -49
  84. package/cli/generators/generate-cron-handlers/type-helpers-block.ts +0 -60
  85. package/cli/generators/generate-db-handlers/index.ts +0 -33
  86. package/cli/generators/generate-db-handlers/prepare.ts +0 -24
  87. package/cli/generators/generate-db-handlers/templates.ts +0 -189
  88. package/cli/generators/generate-db-handlers.ts +0 -1
  89. package/cli/generators/generate-hono-server/auth.ts +0 -97
  90. package/cli/generators/generate-hono-server/imports.ts +0 -55
  91. package/cli/generators/generate-hono-server/index.ts +0 -52
  92. package/cli/generators/generate-hono-server/routes.ts +0 -115
  93. package/cli/generators/generate-hono-server/template.ts +0 -371
  94. package/cli/generators/generate-hono-server.ts +0 -1
  95. package/cli/generators/generate-scheduler-handlers/constants.ts +0 -8
  96. package/cli/generators/generate-scheduler-handlers/handler-entries.ts +0 -22
  97. package/cli/generators/generate-scheduler-handlers/index.ts +0 -51
  98. package/cli/generators/generate-scheduler-handlers/runtime-block.ts +0 -68
  99. package/cli/generators/generate-scheduler-handlers/scheduler-handlers-block.ts +0 -2
  100. package/cli/generators/generate-scheduler-handlers/type-helpers-block.ts +0 -68
  101. package/cli/generators/generate-scheduler-handlers.ts +0 -1
  102. package/cli/generators/generate-websocket-durable-object/auth.ts +0 -30
  103. package/cli/generators/generate-websocket-durable-object/imports.ts +0 -55
  104. package/cli/generators/generate-websocket-durable-object/index.ts +0 -41
  105. package/cli/generators/generate-websocket-durable-object/query-handlers.ts +0 -18
  106. package/cli/generators/generate-websocket-durable-object/template.ts +0 -714
  107. package/cli/generators/generate-websocket-durable-object.ts +0 -1
  108. package/cli/schema/schema-static-types.ts +0 -702
  109. package/cli/schema/schema.ts +0 -151
  110. package/cli/utils/tsc.ts +0 -54
  111. package/cli/utils/utils.ts +0 -190
  112. package/cli/utils/zod-utils.ts +0 -121
  113. package/lib/README.md +0 -50
  114. package/lib/db.ts +0 -19
  115. package/lib/location.ts +0 -110
  116. package/lib/values.ts +0 -27
  117. package/react/README.md +0 -67
  118. package/react/hooks/useMutation.ts +0 -89
  119. package/react/hooks/usePaginatedQuery.ts +0 -213
  120. package/react/hooks/useQuery.ts +0 -106
  121. package/react/shared/queryShared.ts +0 -174
  122. package/server/README.md +0 -218
  123. package/server/auth.ts +0 -107
  124. package/server/database/builders.ts +0 -83
  125. package/server/database/context.ts +0 -327
  126. package/server/database/populate.ts +0 -234
  127. package/server/database/query-builder.ts +0 -161
  128. package/server/database/query-utils.ts +0 -25
  129. package/server/db.ts +0 -2
  130. package/server/storage/auth.ts +0 -16
  131. package/server/storage/bucket.ts +0 -22
  132. package/server/storage/context.ts +0 -34
  133. package/server/storage/index.ts +0 -38
  134. package/server/storage/operations.ts +0 -149
  135. package/server/storage/route-handler.ts +0 -60
  136. package/server/storage/types.ts +0 -55
  137. package/server/storage/utils.ts +0 -47
  138. package/server/storage.ts +0 -6
  139. package/server/types/schema-refs.ts +0 -66
  140. package/server/types/types.ts +0 -633
  141. package/server/utils/id-utils.ts +0 -230
@@ -0,0 +1,156 @@
1
+ # Auth Template Generators
2
+
3
+ This directory contains source generators used by the Appflare CLI to scaffold authentication integration for a Cloudflare Worker backend.
4
+
5
+ The files here **do not directly implement runtime auth logic** in this folder. Instead, they generate TypeScript source strings that are written into generated backend files (for example under `backend/_generated`).
6
+
7
+ ---
8
+
9
+ ## Purpose
10
+
11
+ The auth template layer provides:
12
+
13
+ - A generated `createAuth()` factory based on `better-auth` + Cloudflare integrations.
14
+ - Route-level wiring for auth endpoints (`GET`/`POST` on an auth base path).
15
+ - Request sanitization helpers to normalize header forwarding behavior.
16
+ - Small composition utilities so the CLI can include/exclude KV support based on config.
17
+
18
+ ---
19
+
20
+ ## File-by-file breakdown
21
+
22
+ ## `config.ts`
23
+
24
+ ### `generateAuthConfigSource(configPathImport: string): string`
25
+
26
+ Builds the full source code for an auth configuration module.
27
+
28
+ Generated module characteristics:
29
+
30
+ - Imports:
31
+ - `better-auth`
32
+ - `withCloudflare` from `better-auth-cloudflare`
33
+ - `drizzleAdapter` from `better-auth/adapters/drizzle`
34
+ - `drizzle` from `drizzle-orm/d1`
35
+ - Cloudflare worker types (`D1Database`, `KVNamespace`, `IncomingRequestCfProperties`)
36
+ - Local `auth.schema`
37
+ - User config module from `configPathImport`
38
+ - Defines `CloudflareBindings` with:
39
+ - required `DATABASE: D1Database`
40
+ - optional `KV?: KVNamespace`
41
+ - Exposes:
42
+ - `createAuth(env?, cf?)`
43
+ - `auth = createAuth()`
44
+
45
+ Behavior details:
46
+
47
+ - If `env` is provided:
48
+ - Creates a Drizzle D1 database instance.
49
+ - Configures `withCloudflare` with D1 and optional KV.
50
+ - If `env` is missing:
51
+ - Falls back to a placeholder `drizzleAdapter` setup to keep type-level/runtime shape valid in non-worker contexts.
52
+ - Merges Cloudflare options with `config.auth.options` so user config can extend behavior.
53
+
54
+ ---
55
+
56
+ ## `route-config.ts`
57
+
58
+ ### `generateKvField(kvBinding?: string): string`
59
+
60
+ Returns a generated object field snippet for KV binding when configured.
61
+
62
+ - If `kvBinding` is missing: returns empty string.
63
+ - If present: returns `KV: c.env["<binding>"] as KVNamespace` (prefixed with comma/newline for embedding).
64
+
65
+ ### `generateAuthConfig(databaseBinding: string, kvBinding?: string): string`
66
+
67
+ Generates the `env` argument payload passed into `createAuth()` in route handlers:
68
+
69
+ - Always includes `DATABASE: c.env["<databaseBinding>"] as D1Database`.
70
+ - Optionally includes `KV` using `generateKvField()`.
71
+
72
+ This keeps route generation dynamic for projects that may or may not enable KV.
73
+
74
+ ---
75
+
76
+ ## `route-handler.ts`
77
+
78
+ ### `generateAuthHandler(authBasePath: string, databaseBinding: string, kvBinding?: string): string`
79
+
80
+ Generates the auth route registration snippet:
81
+
82
+ - Registers `app.on(["GET", "POST"], "<authBasePath>/*", async (c) => { ... })`.
83
+ - Creates an auth instance per request:
84
+ - injects generated env bindings from `generateAuthConfig(...)`
85
+ - injects `c.req.raw.cf` as Cloudflare request metadata
86
+ - Returns `auth.handler(getSanitizedRequest(c.req.raw))`.
87
+
88
+ This is the bridge between framework routing and Better Auth request handling.
89
+
90
+ ---
91
+
92
+ ## `route-request-utils.ts`
93
+
94
+ Contains generated helper functions to sanitize incoming request headers.
95
+
96
+ ### `generateGetHeadersFunction(): string`
97
+
98
+ Generates `getHeaders(headers: Headers)`:
99
+
100
+ - Converts headers into a plain object.
101
+ - Detects whether a `cookie` header exists.
102
+ - Keeps `authorization` only when it contains a `Bearer` token.
103
+ - If cookies are present, suppresses `authorization` to avoid conflicting auth sources.
104
+ - Returns a rebuilt header object cast back to `Headers`.
105
+
106
+ ### `generateSanitizedRequestFunction(): string`
107
+
108
+ Generates `getSanitizedRequest(req: Request)`:
109
+
110
+ - Creates a cloned `Request` with filtered headers from `getHeaders()`.
111
+
112
+ ### `generateRequestUtilities(): string`
113
+
114
+ Concatenates both helper function source blocks into one string for route output.
115
+
116
+ ---
117
+
118
+ ## `route.ts`
119
+
120
+ ### `generateAuthRoute(authBasePath: string, databaseBinding: string, kvBinding?: string): string`
121
+
122
+ Top-level composition entry for route generation.
123
+
124
+ - Combines:
125
+ - `generateAuthHandler(...)`
126
+ - `generateRequestUtilities()`
127
+ - Returns one complete source block ready to be written to generated route files.
128
+
129
+ ---
130
+
131
+ ## Generation flow in this directory
132
+
133
+ 1. CLI calls `generateAuthRoute(...)` when producing backend route code.
134
+ 2. Route snippet includes handler + request sanitizers.
135
+ 3. Handler calls `createAuth(...)` with bindings generated by `generateAuthConfig(...)`.
136
+ 4. Separately, CLI can emit full auth configuration module using `generateAuthConfigSource(...)`.
137
+ 5. Resulting generated backend code is ready for Cloudflare Worker runtime with D1 (and optional KV).
138
+
139
+ ---
140
+
141
+ ## Design notes
142
+
143
+ - **String-template based generation**: keeps template logic small and explicit.
144
+ - **Conditional KV support**: avoids forcing KV binding when not configured.
145
+ - **Request normalization**: helps prevent ambiguous auth precedence between cookies and authorization headers.
146
+ - **Cloudflare-first integration**: targets Worker runtime (`cf`, D1, KV) while preserving local compatibility shape.
147
+
148
+ ---
149
+
150
+ ## Expected consumers
151
+
152
+ These generators are intended to be used by internal CLI code under:
153
+
154
+ - `packages/appflare/cli/...`
155
+
156
+ They are implementation details of scaffolding and are not meant as public runtime APIs.
@@ -0,0 +1,61 @@
1
+ export function generateAuthConfigSource(configPathImport: string): string {
2
+ return `import { betterAuth } from "better-auth";
3
+ import { withCloudflare } from "better-auth-cloudflare";
4
+ import { drizzleAdapter } from "better-auth/adapters/drizzle";
5
+ import { drizzle } from "drizzle-orm/d1";
6
+ import type {
7
+ D1Database,
8
+ IncomingRequestCfProperties,
9
+ KVNamespace,
10
+ } from "@cloudflare/workers-types";
11
+ import * as Schema from "./auth.schema";
12
+ import config from "${configPathImport}";
13
+
14
+ type CloudflareBindings = {
15
+ DATABASE: D1Database;
16
+ KV?: KVNamespace;
17
+ };
18
+
19
+ export const createAuth = (
20
+ env?: CloudflareBindings,
21
+ cf?: IncomingRequestCfProperties,
22
+ ) => {
23
+ const db = env
24
+ ? drizzle(env.DATABASE, {
25
+ schema: Schema,
26
+ })
27
+ : ({} as any);
28
+
29
+ return betterAuth({
30
+ ...withCloudflare(
31
+ {
32
+ autoDetectIpAddress: true,
33
+ geolocationTracking: true,
34
+ cf: cf ?? {},
35
+ d1: env
36
+ ? {
37
+ db,
38
+ options: {
39
+ usePlural: true,
40
+ debugLogs: true,
41
+ },
42
+ }
43
+ : undefined,
44
+ kv: env?.KV,
45
+ },
46
+ config.auth.options,
47
+ ),
48
+ ...(env
49
+ ? {}
50
+ : {
51
+ database: drizzleAdapter({} as D1Database, {
52
+ provider: "sqlite",
53
+ usePlural: true,
54
+ debugLogs: true,
55
+ }),
56
+ }),
57
+ });
58
+ };
59
+ export const auth = createAuth();
60
+ `;
61
+ }
@@ -0,0 +1,18 @@
1
+ function generateKvField(kvBinding?: string): string {
2
+ if (!kvBinding) {
3
+ return "";
4
+ }
5
+
6
+ return `,\n\t\t\tKV: c.env["${kvBinding}"] as KVNamespace`;
7
+ }
8
+
9
+ function generateAuthConfig(
10
+ databaseBinding: string,
11
+ kvBinding?: string,
12
+ ): string {
13
+ return `{
14
+ DATABASE: c.env["${databaseBinding}"] as D1Database${generateKvField(kvBinding)}
15
+ }`;
16
+ }
17
+
18
+ export { generateKvField, generateAuthConfig };
@@ -0,0 +1,18 @@
1
+ import { generateAuthConfig } from "./route-config";
2
+
3
+ function generateAuthHandler(
4
+ authBasePath: string,
5
+ databaseBinding: string,
6
+ kvBinding?: string,
7
+ ): string {
8
+ return `app.on(["GET", "POST"], "${authBasePath}/*", async (c) => {
9
+ const auth = createAuth(
10
+ ${generateAuthConfig(databaseBinding, kvBinding)},
11
+ c.req.raw.cf as IncomingRequestCfProperties | undefined,
12
+ );
13
+ return auth.handler(getSanitizedRequest(c.req.raw));
14
+ });
15
+ `;
16
+ }
17
+
18
+ export { generateAuthHandler };
@@ -0,0 +1,55 @@
1
+ function generateGetHeadersFunction(): string {
2
+ return `export const getHeaders = (headers: Headers) => {
3
+ const newHeaders = Object.fromEntries(headers as any);
4
+ const headerObject: Record<string, any> = {};
5
+ let hasCookie = false;
6
+
7
+ for (const key in newHeaders) {
8
+ if (key.toLowerCase() === "cookie") {
9
+ hasCookie = true;
10
+ break;
11
+ }
12
+ }
13
+
14
+ for (const key in newHeaders) {
15
+ const isAuthorization =
16
+ key.toLowerCase() === "authorization" &&
17
+ newHeaders[key]?.includes("Bearer");
18
+
19
+ if (hasCookie && key.toLowerCase() === "authorization") {
20
+ continue;
21
+ }
22
+
23
+ if (key.toLowerCase() === "authorization" && !isAuthorization) {
24
+ continue;
25
+ }
26
+
27
+ headerObject[key] = newHeaders[key];
28
+ }
29
+
30
+ return headerObject as any as Headers;
31
+ };
32
+ `;
33
+ }
34
+
35
+ function generateSanitizedRequestFunction(): string {
36
+ return `export const getSanitizedRequest = (req: Request) => {
37
+ const newRequest = new Request(req, {
38
+ headers: getHeaders(req.headers),
39
+ });
40
+ return newRequest;
41
+ };
42
+ `;
43
+ }
44
+
45
+ function generateRequestUtilities(): string {
46
+ return (
47
+ generateGetHeadersFunction() + "\n" + generateSanitizedRequestFunction()
48
+ );
49
+ }
50
+
51
+ export {
52
+ generateGetHeadersFunction,
53
+ generateSanitizedRequestFunction,
54
+ generateRequestUtilities,
55
+ };
@@ -0,0 +1,14 @@
1
+ import { generateAuthHandler } from "./route-handler";
2
+ import { generateRequestUtilities } from "./route-request-utils";
3
+
4
+ export function generateAuthRoute(
5
+ authBasePath: string,
6
+ databaseBinding: string,
7
+ kvBinding?: string,
8
+ ): string {
9
+ return (
10
+ generateAuthHandler(authBasePath, databaseBinding, kvBinding) +
11
+ "\n" +
12
+ generateRequestUtilities()
13
+ );
14
+ }
@@ -0,0 +1,266 @@
1
+ # Core Template Generators
2
+
3
+ This directory contains **code generators** used by the Appflare CLI to produce the backend runtime scaffolding for Cloudflare Workers + Hono + Better Auth.
4
+
5
+ Instead of shipping static template files, each module returns source code strings (or JSON objects) assembled by higher-level generation flows.
6
+
7
+ ---
8
+
9
+ ## What this folder does
10
+
11
+ The core template modules are responsible for generating:
12
+
13
+ 1. **Worker server source** (`src/index.ts` style output)
14
+ 2. **Cloudflare Wrangler config** (`wrangler.json` shape)
15
+ 3. **Drizzle config source** (`drizzle.config.ts`)
16
+ 4. **Typed Appflare client source** (Better Auth client wrapper)
17
+ 5. **Generated handlers integration** (registering auto-generated route handlers)
18
+
19
+ In short: this folder is the backbone that wires auth, handlers, CORS, DB/KV bindings, and deployment configuration together.
20
+
21
+ ---
22
+
23
+ ## Generation flow
24
+
25
+ The main composition entry is:
26
+
27
+ - `generateServerSource()` in `server.ts`
28
+
29
+ It assembles output in this order:
30
+
31
+ 1. `generateImports()`
32
+ 2. `generateTypes()`
33
+ 3. `generateAppCreation()`
34
+ 4. `generateHandlersRoute()`
35
+ 5. `generateAuthRoute()` (from `../auth/route`)
36
+ 6. `generateExport()`
37
+
38
+ This produces one server entry file that:
39
+
40
+ - Creates a Hono app
41
+ - Adds CORS middleware
42
+ - Registers generated handlers
43
+ - Adds auth routes
44
+ - Exports a Worker-compatible `fetch` handler
45
+
46
+ ---
47
+
48
+ ## File-by-file documentation
49
+
50
+ ### `app-creation.ts`
51
+
52
+ Provides `generateAppCreation()`.
53
+
54
+ Generated behavior:
55
+
56
+ - Creates `const app = new Hono<WorkerEnv>()`
57
+ - Installs `cors()` middleware for all routes (`app.use('*', ...)`)
58
+ - Implements dynamic origin allow-list logic based on `c.env.ALLOWED_DOMAINS`
59
+
60
+ CORS behavior details:
61
+
62
+ - If `ALLOWED_DOMAINS` is missing, all origins are allowed
63
+ - If `ALLOWED_DOMAINS` contains `*`, all origins are allowed
64
+ - Otherwise only exact origin matches are allowed
65
+ - `credentials: true` is enabled
66
+
67
+ ---
68
+
69
+ ### `client.ts`
70
+
71
+ Provides `generateClientArtifacts(configPathImport)`.
72
+
73
+ Generates modular typed client artifacts under a `client/` directory:
74
+
75
+ - `client/types.ts` for shared client/auth/storage types
76
+ - `client/storage.ts` for storage API methods
77
+ - `client/appflare.ts` for `Appflare` and `createAppflare()`
78
+ - `client/index.ts` as barrel export
79
+ - a root `client.ts` barrel (`export * from "./client"`)
80
+
81
+ Runtime behavior:
82
+
83
+ - Normalizes `endpoint` by removing trailing slash
84
+ - Builds auth base URL as:
85
+ - `${endpoint}${authPath ?? "/api/auth"}`
86
+ - Uses provided `fetch` override or global `fetch`
87
+
88
+ This gives app consumers a stable, strongly typed client API.
89
+
90
+ ---
91
+
92
+ ### `drizzle.ts`
93
+
94
+ Provides `generateDrizzleConfigSource(schema)`.
95
+
96
+ Generates a `drizzle-kit` config with:
97
+
98
+ - `dialect: "sqlite"`
99
+ - `driver: "d1-http"`
100
+ - provided `schema` paths
101
+ - placeholder `dbCredentials` values (`accountId`, `databaseId`, `token`)
102
+
103
+ Purpose: bootstrap Drizzle migrations/introspection for Cloudflare D1-backed projects.
104
+
105
+ ---
106
+
107
+ ### `export.ts`
108
+
109
+ Provides `generateExport()`.
110
+
111
+ Generates the Worker export:
112
+
113
+ ```ts
114
+ export default {
115
+ fetch: app.fetch,
116
+ };
117
+ ```
118
+
119
+ This is the standard Cloudflare Worker module format.
120
+
121
+ ---
122
+
123
+ ### `handlers-route.ts`
124
+
125
+ Provides `generateHandlersRoute(databaseBinding, kvBinding?)`.
126
+
127
+ Generates a call to `registerGeneratedHandlers(app, { ... })` with:
128
+
129
+ - required `databaseBinding`
130
+ - optional `kvBinding`
131
+
132
+ This bridges generated handler artifacts into the live Hono router.
133
+
134
+ ---
135
+
136
+ ### `handlers.ts`
137
+
138
+ Re-exports `generateHandlersArtifacts` from `../handlers/index`.
139
+
140
+ Role:
141
+
142
+ - Keeps core template entrypoints centralized
143
+ - Lets higher-level orchestration import handler generation through core exports
144
+
145
+ ---
146
+
147
+ ### `imports.ts`
148
+
149
+ Provides `generateImports()`.
150
+
151
+ Generates import statements used by server source:
152
+
153
+ - `createAuth` from `./auth.config`
154
+ - `registerGeneratedHandlers` from `./handlers.routes`
155
+ - `Hono` from `hono`
156
+ - `cors` from `hono/cors`
157
+ - Worker-related types from `@cloudflare/workers-types`
158
+
159
+ This keeps import assembly in one place so server template composition stays simple.
160
+
161
+ ---
162
+
163
+ ### `server.ts`
164
+
165
+ Provides `generateServerSource(authBasePath, databaseBinding, kvBinding?)`.
166
+
167
+ This is the **composition root** for server template output. It concatenates string fragments from all generator modules (including auth route generator from the auth template area).
168
+
169
+ Inputs:
170
+
171
+ - `authBasePath`: mount path for auth route generation
172
+ - `databaseBinding`: D1 binding key used by handlers/auth wiring
173
+ - `kvBinding` (optional): KV namespace binding key
174
+
175
+ Output:
176
+
177
+ - Full Worker/Hono server source file text
178
+
179
+ ---
180
+
181
+ ### `types.ts`
182
+
183
+ Provides `generateTypes()`.
184
+
185
+ Generates:
186
+
187
+ ```ts
188
+ type WorkerEnv = {
189
+ Bindings: Record<string, unknown>;
190
+ };
191
+ ```
192
+
193
+ This gives the Hono app a generic Worker env shape and avoids hard-coding concrete bindings in this template fragment.
194
+
195
+ ---
196
+
197
+ ### `wrangler.ts`
198
+
199
+ Provides `generateWranglerJson(config)`.
200
+
201
+ Builds a base Wrangler JSON object from loaded Appflare config:
202
+
203
+ - `name: "appflare-worker"`
204
+ - `main: "./src/index.ts"`
205
+ - maps `database` definitions -> `d1_databases`
206
+ - maps `kv` definitions -> `kv_namespaces`
207
+
208
+ Additional behavior:
209
+
210
+ - Adds `migrations_dir` only when present
211
+ - Adds KV `preview_id` only when present
212
+ - If `wranglerOverrides` exists, merges it into base output via `deepMergeJson()`
213
+
214
+ This lets generated defaults stay predictable while still supporting user overrides.
215
+
216
+ ---
217
+
218
+ ## Design patterns used
219
+
220
+ 1. **String-template generators**
221
+ - Each module returns source text with minimal side effects
222
+ 2. **Composable assembly**
223
+ - `server.ts` composes focused fragments in deterministic order
224
+ 3. **Config-driven output**
225
+ - Wrangler generation maps structured config into deploy-ready shape
226
+ 4. **Type inference for SDK ergonomics**
227
+ - Client generator infers auth options from config types
228
+ 5. **Optional feature toggles via args**
229
+ - KV-related code paths are included only when KV binding is provided
230
+
231
+ ---
232
+
233
+ ## Typical usage in CLI pipeline
234
+
235
+ At a high level, CLI code can:
236
+
237
+ 1. Load and validate Appflare config
238
+ 2. Generate server source and write to `_generated/server.ts` (or similar)
239
+ 3. Generate handler/auth artifacts
240
+ 4. Generate wrangler JSON with merged overrides
241
+ 5. Generate client source for application consumption
242
+
243
+ This folder specifically owns the **core primitives** used in steps 2, 4, and part of 5.
244
+
245
+ ---
246
+
247
+ ## Maintenance notes
248
+
249
+ - Keep generator outputs deterministic for stable diffs.
250
+ - When changing generated code contracts, update both:
251
+ - template generators
252
+ - consuming runtime code expecting those contracts
253
+ - Prefer extending via optional args/config (as done with `kvBinding`) instead of branching per project type.
254
+ - If new Worker bindings are added, update both:
255
+ - route registration generation
256
+ - wrangler JSON generation
257
+
258
+ ---
259
+
260
+ ## Quick reference
261
+
262
+ - Server composition: `generateServerSource()`
263
+ - Client generation: `generateClientArtifacts()`
264
+ - Wrangler config generation: `generateWranglerJson()`
265
+ - Drizzle config generation: `generateDrizzleConfigSource()`
266
+ - Handlers artifacts export: `generateHandlersArtifacts` (re-exported)
@@ -0,0 +1,19 @@
1
+ export function generateAppCreation(): string {
2
+ return `const app = new Hono<WorkerEnv>();
3
+
4
+ app.use('*', cors({
5
+ origin: (origin, c) => {
6
+ const allowedDomains = c.env.ALLOWED_DOMAINS;
7
+ if (!allowedDomains) {
8
+ return origin; // Allow everything if not set
9
+ }
10
+ const allowed = allowedDomains.split(',').map(d => d.trim());
11
+ if (allowed.includes('*')) {
12
+ return origin;
13
+ }
14
+ return allowed.includes(origin) ? origin : null;
15
+ },
16
+ credentials: true
17
+ }));
18
+ `;
19
+ }
@@ -0,0 +1,37 @@
1
+ export function generateClientAppflareSource(): string {
2
+ return `import { createAuthClient, type BetterAuthClientOptions } from "better-auth/client";
3
+ import type {
4
+ AppflareAuth,
5
+ AppflareOptions,
6
+ InferredAuthOptions,
7
+ StorageClient,
8
+ } from "./types";
9
+ import { createStorageClient } from "./storage";
10
+
11
+ export class Appflare<Options extends BetterAuthClientOptions = InferredAuthOptions> {
12
+ public readonly endpoint: string;
13
+ public readonly auth: AppflareAuth<Options>;
14
+ public readonly storage: StorageClient;
15
+
16
+ public constructor(options: AppflareOptions<Options>) {
17
+ this.endpoint = options.endpoint.replace(/\/$/, "");
18
+ const authOptions = (options.authOptions ?? {}) as Options;
19
+ const request = options.fetch ?? fetch;
20
+
21
+ this.auth = createAuthClient<Options>({
22
+ ...authOptions,
23
+ baseURL: \`\${this.endpoint}\${options.authPath ?? "/api/auth"}\`,
24
+ fetch: request,
25
+ });
26
+
27
+ this.storage = createStorageClient(this.endpoint, request);
28
+ }
29
+ }
30
+
31
+ export function createAppflare<Options extends BetterAuthClientOptions = InferredAuthOptions>(
32
+ options: AppflareOptions<Options>,
33
+ ): Appflare<Options> {
34
+ return new Appflare(options);
35
+ }
36
+ `;
37
+ }
@@ -0,0 +1,6 @@
1
+ export function generateClientIndexSource(): string {
2
+ return `export * from "./types";
3
+ export * from "./appflare";
4
+ export * from "./storage";
5
+ `;
6
+ }