appflare 0.2.48 → 0.2.49
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.
- package/Documentation.md +898 -898
- package/cli/commands/index.ts +247 -247
- package/cli/generate.ts +360 -360
- package/cli/index.ts +120 -120
- package/cli/load-config.ts +184 -184
- package/cli/schema-compiler.ts +1366 -1366
- package/cli/templates/auth/README.md +156 -156
- package/cli/templates/auth/config.ts +61 -61
- package/cli/templates/auth/route-config.ts +1 -1
- package/cli/templates/auth/route-handler.ts +1 -1
- package/cli/templates/auth/route-request-utils.ts +5 -5
- package/cli/templates/auth/route.config.ts +18 -18
- package/cli/templates/auth/route.handler.ts +18 -18
- package/cli/templates/auth/route.request-utils.ts +55 -55
- package/cli/templates/auth/route.ts +14 -14
- package/cli/templates/core/README.md +266 -266
- package/cli/templates/core/app-creation.ts +19 -19
- package/cli/templates/core/client/appflare.ts +112 -112
- package/cli/templates/core/client/handlers/index.ts +763 -763
- package/cli/templates/core/client/handlers.ts +1 -1
- package/cli/templates/core/client/index.ts +7 -7
- package/cli/templates/core/client/storage.ts +195 -195
- package/cli/templates/core/client/types.ts +187 -187
- package/cli/templates/core/client-modules/appflare.ts +1 -1
- package/cli/templates/core/client-modules/handlers.ts +1 -1
- package/cli/templates/core/client-modules/index.ts +1 -1
- package/cli/templates/core/client-modules/storage.ts +1 -1
- package/cli/templates/core/client-modules/types.ts +1 -1
- package/cli/templates/core/client.artifacts.ts +39 -39
- package/cli/templates/core/client.ts +4 -4
- package/cli/templates/core/drizzle.ts +15 -15
- package/cli/templates/core/export.ts +14 -14
- package/cli/templates/core/handlers.route.ts +24 -24
- package/cli/templates/core/handlers.ts +1 -1
- package/cli/templates/core/imports.ts +9 -9
- package/cli/templates/core/server.ts +38 -38
- package/cli/templates/core/types.ts +6 -6
- package/cli/templates/core/wrangler.ts +109 -109
- package/cli/templates/dashboard/builders/functions/index.ts +17 -17
- package/cli/templates/dashboard/builders/functions/render-page/header.ts +20 -20
- package/cli/templates/dashboard/builders/functions/render-page/index.ts +33 -33
- package/cli/templates/dashboard/builders/functions/render-page/request-panel.ts +271 -271
- package/cli/templates/dashboard/builders/functions/render-page/result-panel.ts +85 -85
- package/cli/templates/dashboard/builders/functions/render-page/scripts.ts +703 -703
- package/cli/templates/dashboard/builders/functions/tree-builder.ts +47 -47
- package/cli/templates/dashboard/builders/navigation.ts +155 -155
- package/cli/templates/dashboard/builders/storage/index.ts +13 -13
- package/cli/templates/dashboard/builders/storage/routes/create-directory-route.ts +29 -29
- package/cli/templates/dashboard/builders/storage/routes/delete-route.ts +18 -18
- package/cli/templates/dashboard/builders/storage/routes/download-route.ts +23 -23
- package/cli/templates/dashboard/builders/storage/routes/index.ts +22 -22
- package/cli/templates/dashboard/builders/storage/routes/list-route.ts +25 -25
- package/cli/templates/dashboard/builders/storage/routes/preview-route.ts +21 -21
- package/cli/templates/dashboard/builders/storage/routes/upload-route.ts +21 -21
- package/cli/templates/dashboard/builders/storage/runtime/helpers.ts +72 -72
- package/cli/templates/dashboard/builders/storage/runtime/storage-page.ts +130 -130
- package/cli/templates/dashboard/builders/table-routes/common/drawer-panel.ts +27 -27
- package/cli/templates/dashboard/builders/table-routes/common/pagination.ts +30 -30
- package/cli/templates/dashboard/builders/table-routes/common/search-bar.ts +23 -23
- package/cli/templates/dashboard/builders/table-routes/fragments.ts +257 -217
- package/cli/templates/dashboard/builders/table-routes/helpers.ts +45 -45
- package/cli/templates/dashboard/builders/table-routes/index.ts +8 -8
- package/cli/templates/dashboard/builders/table-routes/table/actions-cell.ts +71 -71
- package/cli/templates/dashboard/builders/table-routes/table/get-route.ts +291 -291
- package/cli/templates/dashboard/builders/table-routes/table/index.ts +80 -80
- package/cli/templates/dashboard/builders/table-routes/table/post-routes.ts +163 -163
- package/cli/templates/dashboard/builders/table-routes/table-route.ts +7 -7
- package/cli/templates/dashboard/builders/table-routes/users/get-route.ts +69 -69
- package/cli/templates/dashboard/builders/table-routes/users/html/modals.ts +57 -57
- package/cli/templates/dashboard/builders/table-routes/users/html/page.ts +27 -27
- package/cli/templates/dashboard/builders/table-routes/users/html/table.ts +128 -128
- package/cli/templates/dashboard/builders/table-routes/users/index.ts +32 -32
- package/cli/templates/dashboard/builders/table-routes/users/post-routes.ts +150 -150
- package/cli/templates/dashboard/builders/table-routes/users/redirect.ts +14 -14
- package/cli/templates/dashboard/builders/table-routes/users-route.ts +10 -10
- package/cli/templates/dashboard/components/dashboard-home.ts +23 -23
- package/cli/templates/dashboard/components/layout.ts +420 -420
- package/cli/templates/dashboard/components/login-page.ts +65 -65
- package/cli/templates/dashboard/index.ts +61 -61
- package/cli/templates/dashboard/types.ts +9 -9
- package/cli/templates/handlers/README.md +353 -353
- package/cli/templates/handlers/auth.ts +37 -37
- package/cli/templates/handlers/execution.ts +44 -42
- package/cli/templates/handlers/generators/context/context-creation.ts +101 -101
- package/cli/templates/handlers/generators/context/error-helpers.ts +11 -11
- package/cli/templates/handlers/generators/context/scheduler.ts +24 -24
- package/cli/templates/handlers/generators/context/storage-api.ts +82 -82
- package/cli/templates/handlers/generators/context/storage-helpers.ts +59 -59
- package/cli/templates/handlers/generators/context/types.ts +40 -40
- package/cli/templates/handlers/generators/context.ts +43 -43
- package/cli/templates/handlers/generators/execution.ts +15 -15
- package/cli/templates/handlers/generators/handlers.ts +14 -14
- package/cli/templates/handlers/generators/registration/modules/cron.ts +35 -35
- package/cli/templates/handlers/generators/registration/modules/realtime/auth.ts +75 -75
- package/cli/templates/handlers/generators/registration/modules/realtime/durable-object.ts +144 -144
- package/cli/templates/handlers/generators/registration/modules/realtime/index.ts +14 -14
- package/cli/templates/handlers/generators/registration/modules/realtime/publisher.ts +102 -102
- package/cli/templates/handlers/generators/registration/modules/realtime/routes.ts +164 -164
- package/cli/templates/handlers/generators/registration/modules/realtime/types.ts +30 -30
- package/cli/templates/handlers/generators/registration/modules/realtime/utils.ts +510 -510
- package/cli/templates/handlers/generators/registration/modules/scheduler.ts +65 -65
- package/cli/templates/handlers/generators/registration/modules/storage.ts +199 -199
- package/cli/templates/handlers/generators/registration/sections.ts +210 -210
- package/cli/templates/handlers/generators/types/context.ts +121 -121
- package/cli/templates/handlers/generators/types/core.ts +108 -108
- package/cli/templates/handlers/generators/types/operations.ts +135 -135
- package/cli/templates/handlers/generators/types/query-definitions/filter-and-where-types.ts +291 -291
- package/cli/templates/handlers/generators/types/query-definitions/query-api-types.ts +135 -135
- package/cli/templates/handlers/generators/types/query-definitions/query-helper-functions.ts +1382 -1382
- package/cli/templates/handlers/generators/types/query-definitions/schema-and-table-types.ts +278 -278
- package/cli/templates/handlers/generators/types/query-definitions.ts +13 -13
- package/cli/templates/handlers/generators/types/query-runtime/handled-error.ts +13 -13
- package/cli/templates/handlers/generators/types/query-runtime/runtime-aggregate-and-footer.ts +174 -174
- package/cli/templates/handlers/generators/types/query-runtime/runtime-read.ts +156 -156
- package/cli/templates/handlers/generators/types/query-runtime/runtime-setup.ts +45 -45
- package/cli/templates/handlers/generators/types/query-runtime/runtime-write.ts +958 -958
- package/cli/templates/handlers/generators/types/query-runtime.ts +15 -15
- package/cli/templates/handlers/index.ts +47 -47
- package/cli/templates/handlers/operations.ts +116 -116
- package/cli/templates/handlers/registration.ts +91 -91
- package/cli/templates/handlers/types.ts +17 -17
- package/cli/templates/handlers/utils.ts +48 -48
- package/cli/types.ts +110 -110
- package/cli/utils/handler-discovery.ts +501 -501
- package/cli/utils/json-utils.ts +24 -24
- package/cli/utils/path-utils.ts +19 -19
- package/cli/utils/schema-discovery.ts +402 -399
- package/dist/cli/index.js +77 -55
- package/dist/cli/index.mjs +77 -55
- package/index.ts +18 -18
- package/package.json +58 -58
- package/react/index.ts +5 -5
- package/react/use-infinite-query.ts +255 -255
- package/react/use-mutation.ts +89 -89
- package/react/use-query.ts +210 -210
- package/schema.ts +641 -641
- package/test-better-auth-hash.ts +2 -2
- package/tsconfig.json +6 -6
- package/tsup.config.ts +82 -82
package/cli/index.ts
CHANGED
|
@@ -1,120 +1,120 @@
|
|
|
1
|
-
import { Command } from "commander";
|
|
2
|
-
import { runBuild, runDev, runMigrate, runAddAdmin } from "./commands/index";
|
|
3
|
-
|
|
4
|
-
const program = new Command();
|
|
5
|
-
|
|
6
|
-
program
|
|
7
|
-
.name("appflare")
|
|
8
|
-
.description(
|
|
9
|
-
"Appflare compiler/bundler for Cloudflare-native backends and SDK generation",
|
|
10
|
-
)
|
|
11
|
-
.version("0.0.28");
|
|
12
|
-
|
|
13
|
-
program
|
|
14
|
-
.command("build")
|
|
15
|
-
.description(
|
|
16
|
-
"Generate server.ts, client.ts, auth.config.js, drizzle.config.js, and wrangler.json artifacts",
|
|
17
|
-
)
|
|
18
|
-
.option(
|
|
19
|
-
"-c, --config <path>",
|
|
20
|
-
"Path to appflare.config.ts",
|
|
21
|
-
"appflare.config.ts",
|
|
22
|
-
)
|
|
23
|
-
.option("--no-build", "Skip TypeScript build step")
|
|
24
|
-
.action(async (options: { config: string; build: boolean }) => {
|
|
25
|
-
await runBuild(options.config, { build: options.build });
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
program
|
|
29
|
-
.command("dev")
|
|
30
|
-
.description("Run generator in development mode")
|
|
31
|
-
.option(
|
|
32
|
-
"-c, --config <path>",
|
|
33
|
-
"Path to appflare.config.ts",
|
|
34
|
-
"appflare.config.ts",
|
|
35
|
-
)
|
|
36
|
-
.option("-w, --watch", "Watch scanDir and regenerate on changes", false)
|
|
37
|
-
.option("--no-build", "Skip TypeScript build step")
|
|
38
|
-
.action(
|
|
39
|
-
async (options: { config: string; watch: boolean; build: boolean }) => {
|
|
40
|
-
await runDev(options.config, { watch: options.watch, build: options.build });
|
|
41
|
-
},
|
|
42
|
-
);
|
|
43
|
-
|
|
44
|
-
program
|
|
45
|
-
.command("migrate")
|
|
46
|
-
.description(
|
|
47
|
-
"Generate drizzle migration files from outDir/auth.schema.ts and apply them to the configured D1 database",
|
|
48
|
-
)
|
|
49
|
-
.option(
|
|
50
|
-
"-c, --config <path>",
|
|
51
|
-
"Path to appflare.config.ts",
|
|
52
|
-
"appflare.config.ts",
|
|
53
|
-
)
|
|
54
|
-
.option(
|
|
55
|
-
"--local",
|
|
56
|
-
"Execute commands/files against a local DB for use with wrangler dev",
|
|
57
|
-
false,
|
|
58
|
-
)
|
|
59
|
-
.option(
|
|
60
|
-
"--remote",
|
|
61
|
-
"Execute commands/files against a remote DB for use with wrangler dev --remote",
|
|
62
|
-
false,
|
|
63
|
-
)
|
|
64
|
-
.option("--preview", "Execute commands/files against a preview D1 DB", false)
|
|
65
|
-
.action(
|
|
66
|
-
async (options: {
|
|
67
|
-
config: string;
|
|
68
|
-
local: boolean;
|
|
69
|
-
remote: boolean;
|
|
70
|
-
preview: boolean;
|
|
71
|
-
}) => {
|
|
72
|
-
await runMigrate(options.config, {
|
|
73
|
-
local: options.local,
|
|
74
|
-
remote: options.remote,
|
|
75
|
-
preview: options.preview,
|
|
76
|
-
});
|
|
77
|
-
},
|
|
78
|
-
);
|
|
79
|
-
|
|
80
|
-
program
|
|
81
|
-
.command("add-admin")
|
|
82
|
-
.description("Add an admin user to the database")
|
|
83
|
-
.requiredOption("-n, --name <name>", "Admin's display name")
|
|
84
|
-
.requiredOption("-e, --email <email>", "Admin's email address")
|
|
85
|
-
.requiredOption("-p, --password <password>", "Admin's password")
|
|
86
|
-
.option(
|
|
87
|
-
"-c, --config <path>",
|
|
88
|
-
"Path to appflare.config.ts",
|
|
89
|
-
"appflare.config.ts",
|
|
90
|
-
)
|
|
91
|
-
.option(
|
|
92
|
-
"--local",
|
|
93
|
-
"Execute command against a local DB for use with wrangler dev",
|
|
94
|
-
false,
|
|
95
|
-
)
|
|
96
|
-
.option(
|
|
97
|
-
"--remote",
|
|
98
|
-
"Execute command against a remote DB for use with wrangler dev --remote",
|
|
99
|
-
false,
|
|
100
|
-
)
|
|
101
|
-
.action(async (options: any) => {
|
|
102
|
-
await runAddAdmin(options.config, {
|
|
103
|
-
name: options.name,
|
|
104
|
-
email: options.email,
|
|
105
|
-
password: options.password,
|
|
106
|
-
local: options.local,
|
|
107
|
-
remote: options.remote,
|
|
108
|
-
});
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
(async () => {
|
|
112
|
-
if (!process.versions.bun) {
|
|
113
|
-
console.error("Appflare CLI must be run with Bun.");
|
|
114
|
-
process.exit(1);
|
|
115
|
-
}
|
|
116
|
-
await program.parseAsync(process.argv);
|
|
117
|
-
})().catch((error) => {
|
|
118
|
-
console.error(error);
|
|
119
|
-
process.exit(1);
|
|
120
|
-
});
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { runBuild, runDev, runMigrate, runAddAdmin } from "./commands/index";
|
|
3
|
+
|
|
4
|
+
const program = new Command();
|
|
5
|
+
|
|
6
|
+
program
|
|
7
|
+
.name("appflare")
|
|
8
|
+
.description(
|
|
9
|
+
"Appflare compiler/bundler for Cloudflare-native backends and SDK generation",
|
|
10
|
+
)
|
|
11
|
+
.version("0.0.28");
|
|
12
|
+
|
|
13
|
+
program
|
|
14
|
+
.command("build")
|
|
15
|
+
.description(
|
|
16
|
+
"Generate server.ts, client.ts, auth.config.js, drizzle.config.js, and wrangler.json artifacts",
|
|
17
|
+
)
|
|
18
|
+
.option(
|
|
19
|
+
"-c, --config <path>",
|
|
20
|
+
"Path to appflare.config.ts",
|
|
21
|
+
"appflare.config.ts",
|
|
22
|
+
)
|
|
23
|
+
.option("--no-build", "Skip TypeScript build step")
|
|
24
|
+
.action(async (options: { config: string; build: boolean }) => {
|
|
25
|
+
await runBuild(options.config, { build: options.build });
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
program
|
|
29
|
+
.command("dev")
|
|
30
|
+
.description("Run generator in development mode")
|
|
31
|
+
.option(
|
|
32
|
+
"-c, --config <path>",
|
|
33
|
+
"Path to appflare.config.ts",
|
|
34
|
+
"appflare.config.ts",
|
|
35
|
+
)
|
|
36
|
+
.option("-w, --watch", "Watch scanDir and regenerate on changes", false)
|
|
37
|
+
.option("--no-build", "Skip TypeScript build step")
|
|
38
|
+
.action(
|
|
39
|
+
async (options: { config: string; watch: boolean; build: boolean }) => {
|
|
40
|
+
await runDev(options.config, { watch: options.watch, build: options.build });
|
|
41
|
+
},
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
program
|
|
45
|
+
.command("migrate")
|
|
46
|
+
.description(
|
|
47
|
+
"Generate drizzle migration files from outDir/auth.schema.ts and apply them to the configured D1 database",
|
|
48
|
+
)
|
|
49
|
+
.option(
|
|
50
|
+
"-c, --config <path>",
|
|
51
|
+
"Path to appflare.config.ts",
|
|
52
|
+
"appflare.config.ts",
|
|
53
|
+
)
|
|
54
|
+
.option(
|
|
55
|
+
"--local",
|
|
56
|
+
"Execute commands/files against a local DB for use with wrangler dev",
|
|
57
|
+
false,
|
|
58
|
+
)
|
|
59
|
+
.option(
|
|
60
|
+
"--remote",
|
|
61
|
+
"Execute commands/files against a remote DB for use with wrangler dev --remote",
|
|
62
|
+
false,
|
|
63
|
+
)
|
|
64
|
+
.option("--preview", "Execute commands/files against a preview D1 DB", false)
|
|
65
|
+
.action(
|
|
66
|
+
async (options: {
|
|
67
|
+
config: string;
|
|
68
|
+
local: boolean;
|
|
69
|
+
remote: boolean;
|
|
70
|
+
preview: boolean;
|
|
71
|
+
}) => {
|
|
72
|
+
await runMigrate(options.config, {
|
|
73
|
+
local: options.local,
|
|
74
|
+
remote: options.remote,
|
|
75
|
+
preview: options.preview,
|
|
76
|
+
});
|
|
77
|
+
},
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
program
|
|
81
|
+
.command("add-admin")
|
|
82
|
+
.description("Add an admin user to the database")
|
|
83
|
+
.requiredOption("-n, --name <name>", "Admin's display name")
|
|
84
|
+
.requiredOption("-e, --email <email>", "Admin's email address")
|
|
85
|
+
.requiredOption("-p, --password <password>", "Admin's password")
|
|
86
|
+
.option(
|
|
87
|
+
"-c, --config <path>",
|
|
88
|
+
"Path to appflare.config.ts",
|
|
89
|
+
"appflare.config.ts",
|
|
90
|
+
)
|
|
91
|
+
.option(
|
|
92
|
+
"--local",
|
|
93
|
+
"Execute command against a local DB for use with wrangler dev",
|
|
94
|
+
false,
|
|
95
|
+
)
|
|
96
|
+
.option(
|
|
97
|
+
"--remote",
|
|
98
|
+
"Execute command against a remote DB for use with wrangler dev --remote",
|
|
99
|
+
false,
|
|
100
|
+
)
|
|
101
|
+
.action(async (options: any) => {
|
|
102
|
+
await runAddAdmin(options.config, {
|
|
103
|
+
name: options.name,
|
|
104
|
+
email: options.email,
|
|
105
|
+
password: options.password,
|
|
106
|
+
local: options.local,
|
|
107
|
+
remote: options.remote,
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
(async () => {
|
|
112
|
+
if (!process.versions.bun) {
|
|
113
|
+
console.error("Appflare CLI must be run with Bun.");
|
|
114
|
+
process.exit(1);
|
|
115
|
+
}
|
|
116
|
+
await program.parseAsync(process.argv);
|
|
117
|
+
})().catch((error) => {
|
|
118
|
+
console.error(error);
|
|
119
|
+
process.exit(1);
|
|
120
|
+
});
|
package/cli/load-config.ts
CHANGED
|
@@ -1,184 +1,184 @@
|
|
|
1
|
-
import { dirname, isAbsolute, resolve } from "node:path";
|
|
2
|
-
import { pathToFileURL } from "node:url";
|
|
3
|
-
import { z } from "zod";
|
|
4
|
-
import type {
|
|
5
|
-
AppflareConfig,
|
|
6
|
-
LoadedAppflareConfig,
|
|
7
|
-
NormalizedAppflareConfig,
|
|
8
|
-
} from "./types";
|
|
9
|
-
|
|
10
|
-
const databaseSchema = z
|
|
11
|
-
.object({
|
|
12
|
-
binding: z.string().min(1),
|
|
13
|
-
databaseName: z.string().min(1),
|
|
14
|
-
databaseId: z.string().min(1),
|
|
15
|
-
previewDatabaseId: z.string().min(1).optional(),
|
|
16
|
-
migrationsDir: z.string().min(1).optional(),
|
|
17
|
-
})
|
|
18
|
-
.strict();
|
|
19
|
-
|
|
20
|
-
const kvSchema = z
|
|
21
|
-
.object({
|
|
22
|
-
binding: z.string().min(1),
|
|
23
|
-
id: z.string().min(1),
|
|
24
|
-
previewId: z.string().min(1).optional(),
|
|
25
|
-
})
|
|
26
|
-
.strict();
|
|
27
|
-
|
|
28
|
-
const r2Schema = z
|
|
29
|
-
.object({
|
|
30
|
-
binding: z.string().min(1),
|
|
31
|
-
bucketName: z.string().min(1),
|
|
32
|
-
previewBucketName: z.string().min(1).optional(),
|
|
33
|
-
jurisdiction: z.string().min(1).optional(),
|
|
34
|
-
})
|
|
35
|
-
.strict();
|
|
36
|
-
|
|
37
|
-
const schedulerConfigSchema = z
|
|
38
|
-
.object({
|
|
39
|
-
enabled: z.boolean().optional(),
|
|
40
|
-
binding: z.string().min(1).optional(),
|
|
41
|
-
queue: z.string().min(1).optional(),
|
|
42
|
-
})
|
|
43
|
-
.strict();
|
|
44
|
-
|
|
45
|
-
const realtimeConfigSchema = z
|
|
46
|
-
.object({
|
|
47
|
-
enabled: z.boolean().optional(),
|
|
48
|
-
binding: z.string().min(1).optional(),
|
|
49
|
-
className: z.string().min(1).optional(),
|
|
50
|
-
objectName: z.string().min(1).optional(),
|
|
51
|
-
subscribePath: z.string().min(1).optional(),
|
|
52
|
-
websocketPath: z.string().min(1).optional(),
|
|
53
|
-
protocol: z.string().min(1).optional(),
|
|
54
|
-
})
|
|
55
|
-
.strict();
|
|
56
|
-
|
|
57
|
-
const appflareConfigSchema = z
|
|
58
|
-
.object({
|
|
59
|
-
scanDir: z.string().min(1),
|
|
60
|
-
outDir: z.string().min(1),
|
|
61
|
-
wranglerOutDir: z.string().min(1).optional(),
|
|
62
|
-
wranglerOutPath: z.string().min(1).optional(),
|
|
63
|
-
schema: z.array(z.string()).min(1),
|
|
64
|
-
schemaDsl: z
|
|
65
|
-
.object({
|
|
66
|
-
entry: z.string().min(1),
|
|
67
|
-
exportName: z.string().min(1).optional(),
|
|
68
|
-
outFile: z.string().min(1).optional(),
|
|
69
|
-
typesOutFile: z.string().min(1).optional(),
|
|
70
|
-
zodOutFile: z.string().min(1).optional(),
|
|
71
|
-
namingStrategy: z.literal("camelToSnake").optional(),
|
|
72
|
-
})
|
|
73
|
-
.strict()
|
|
74
|
-
.optional(),
|
|
75
|
-
database: z.union([databaseSchema, z.array(databaseSchema).min(1)]),
|
|
76
|
-
kv: z.union([kvSchema, z.array(kvSchema)]).optional(),
|
|
77
|
-
r2: z.union([r2Schema, z.array(r2Schema)]).optional(),
|
|
78
|
-
auth: z
|
|
79
|
-
.object({
|
|
80
|
-
enabled: z.boolean(),
|
|
81
|
-
basePath: z.string().min(1),
|
|
82
|
-
options: z.custom<AppflareConfig["auth"]["options"]>((value) => {
|
|
83
|
-
return typeof value === "object" && value !== null;
|
|
84
|
-
}),
|
|
85
|
-
clientOptions: z.custom<AppflareConfig["auth"]["clientOptions"]>(
|
|
86
|
-
(value) => {
|
|
87
|
-
return typeof value === "object" && value !== null;
|
|
88
|
-
},
|
|
89
|
-
),
|
|
90
|
-
})
|
|
91
|
-
.strict(),
|
|
92
|
-
scheduler: schedulerConfigSchema.optional(),
|
|
93
|
-
realtime: realtimeConfigSchema.optional(),
|
|
94
|
-
wranglerOverrides: z.record(z.string(), z.unknown()).optional(),
|
|
95
|
-
build: z.boolean().optional(),
|
|
96
|
-
})
|
|
97
|
-
.strict();
|
|
98
|
-
|
|
99
|
-
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
100
|
-
return typeof value === "object" && value !== null;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
function readLegacySchedulerConfig(
|
|
104
|
-
input: AppflareConfig,
|
|
105
|
-
): Partial<NonNullable<AppflareConfig["scheduler"]>> {
|
|
106
|
-
const raw = isRecord(input.wranglerOverrides)
|
|
107
|
-
? input.wranglerOverrides.scheduler
|
|
108
|
-
: undefined;
|
|
109
|
-
const parsed = schedulerConfigSchema.safeParse(raw);
|
|
110
|
-
if (!parsed.success) {
|
|
111
|
-
return {};
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
return parsed.data;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
function removeLegacySchedulerOverride(
|
|
118
|
-
overrides: AppflareConfig["wranglerOverrides"],
|
|
119
|
-
): AppflareConfig["wranglerOverrides"] {
|
|
120
|
-
if (!isRecord(overrides) || !("scheduler" in overrides)) {
|
|
121
|
-
return overrides;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
const { scheduler: _scheduler, ...rest } = overrides;
|
|
125
|
-
return rest;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
function normalizeConfig(input: AppflareConfig): NormalizedAppflareConfig {
|
|
129
|
-
const legacyScheduler = readLegacySchedulerConfig(input);
|
|
130
|
-
const scheduler = {
|
|
131
|
-
...(legacyScheduler ?? {}),
|
|
132
|
-
...(input.scheduler ?? {}),
|
|
133
|
-
};
|
|
134
|
-
const realtime = input.realtime ?? {};
|
|
135
|
-
|
|
136
|
-
return {
|
|
137
|
-
...input,
|
|
138
|
-
database: Array.isArray(input.database) ? input.database : [input.database],
|
|
139
|
-
kv: input.kv ? (Array.isArray(input.kv) ? input.kv : [input.kv]) : [],
|
|
140
|
-
r2: input.r2 ? (Array.isArray(input.r2) ? input.r2 : [input.r2]) : [],
|
|
141
|
-
scheduler: {
|
|
142
|
-
enabled: scheduler.enabled ?? true,
|
|
143
|
-
binding: scheduler.binding ?? "APPFLARE_SCHEDULER_QUEUE",
|
|
144
|
-
queue: scheduler.queue,
|
|
145
|
-
},
|
|
146
|
-
realtime: {
|
|
147
|
-
enabled: realtime.enabled ?? true,
|
|
148
|
-
binding: realtime.binding ?? "APPFLARE_REALTIME",
|
|
149
|
-
className: realtime.className ?? "AppflareRealtimeDurableObject",
|
|
150
|
-
objectName: realtime.objectName ?? "global",
|
|
151
|
-
subscribePath: realtime.subscribePath ?? "/realtime/subscribe",
|
|
152
|
-
websocketPath: realtime.websocketPath ?? "/realtime/ws",
|
|
153
|
-
protocol: realtime.protocol ?? "appflare.realtime.v1",
|
|
154
|
-
},
|
|
155
|
-
wranglerOverrides: removeLegacySchedulerOverride(input.wranglerOverrides),
|
|
156
|
-
wranglerOutDir:
|
|
157
|
-
input.wranglerOutDir ?? input.wranglerOutPath ?? input.outDir,
|
|
158
|
-
build: input.build ?? true,
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
export async function loadConfig(
|
|
163
|
-
configPathArg?: string,
|
|
164
|
-
): Promise<LoadedAppflareConfig> {
|
|
165
|
-
const configPath = isAbsolute(configPathArg ?? "")
|
|
166
|
-
? (configPathArg as string)
|
|
167
|
-
: resolve(process.cwd(), configPathArg ?? "appflare.config.ts");
|
|
168
|
-
|
|
169
|
-
const configDir = dirname(configPath);
|
|
170
|
-
const moduleUrl = pathToFileURL(configPath).href;
|
|
171
|
-
const configModule = await import(moduleUrl);
|
|
172
|
-
const raw = configModule.default;
|
|
173
|
-
const parsed = appflareConfigSchema.parse(raw) as AppflareConfig;
|
|
174
|
-
const config = normalizeConfig(parsed);
|
|
175
|
-
|
|
176
|
-
return {
|
|
177
|
-
configPath,
|
|
178
|
-
configDir,
|
|
179
|
-
scanDirAbs: resolve(configDir, config.scanDir),
|
|
180
|
-
outDirAbs: resolve(configDir, config.outDir),
|
|
181
|
-
wranglerOutDirAbs: resolve(configDir, config.wranglerOutDir),
|
|
182
|
-
config,
|
|
183
|
-
};
|
|
184
|
-
}
|
|
1
|
+
import { dirname, isAbsolute, resolve } from "node:path";
|
|
2
|
+
import { pathToFileURL } from "node:url";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import type {
|
|
5
|
+
AppflareConfig,
|
|
6
|
+
LoadedAppflareConfig,
|
|
7
|
+
NormalizedAppflareConfig,
|
|
8
|
+
} from "./types";
|
|
9
|
+
|
|
10
|
+
const databaseSchema = z
|
|
11
|
+
.object({
|
|
12
|
+
binding: z.string().min(1),
|
|
13
|
+
databaseName: z.string().min(1),
|
|
14
|
+
databaseId: z.string().min(1),
|
|
15
|
+
previewDatabaseId: z.string().min(1).optional(),
|
|
16
|
+
migrationsDir: z.string().min(1).optional(),
|
|
17
|
+
})
|
|
18
|
+
.strict();
|
|
19
|
+
|
|
20
|
+
const kvSchema = z
|
|
21
|
+
.object({
|
|
22
|
+
binding: z.string().min(1),
|
|
23
|
+
id: z.string().min(1),
|
|
24
|
+
previewId: z.string().min(1).optional(),
|
|
25
|
+
})
|
|
26
|
+
.strict();
|
|
27
|
+
|
|
28
|
+
const r2Schema = z
|
|
29
|
+
.object({
|
|
30
|
+
binding: z.string().min(1),
|
|
31
|
+
bucketName: z.string().min(1),
|
|
32
|
+
previewBucketName: z.string().min(1).optional(),
|
|
33
|
+
jurisdiction: z.string().min(1).optional(),
|
|
34
|
+
})
|
|
35
|
+
.strict();
|
|
36
|
+
|
|
37
|
+
const schedulerConfigSchema = z
|
|
38
|
+
.object({
|
|
39
|
+
enabled: z.boolean().optional(),
|
|
40
|
+
binding: z.string().min(1).optional(),
|
|
41
|
+
queue: z.string().min(1).optional(),
|
|
42
|
+
})
|
|
43
|
+
.strict();
|
|
44
|
+
|
|
45
|
+
const realtimeConfigSchema = z
|
|
46
|
+
.object({
|
|
47
|
+
enabled: z.boolean().optional(),
|
|
48
|
+
binding: z.string().min(1).optional(),
|
|
49
|
+
className: z.string().min(1).optional(),
|
|
50
|
+
objectName: z.string().min(1).optional(),
|
|
51
|
+
subscribePath: z.string().min(1).optional(),
|
|
52
|
+
websocketPath: z.string().min(1).optional(),
|
|
53
|
+
protocol: z.string().min(1).optional(),
|
|
54
|
+
})
|
|
55
|
+
.strict();
|
|
56
|
+
|
|
57
|
+
const appflareConfigSchema = z
|
|
58
|
+
.object({
|
|
59
|
+
scanDir: z.string().min(1),
|
|
60
|
+
outDir: z.string().min(1),
|
|
61
|
+
wranglerOutDir: z.string().min(1).optional(),
|
|
62
|
+
wranglerOutPath: z.string().min(1).optional(),
|
|
63
|
+
schema: z.array(z.string()).min(1),
|
|
64
|
+
schemaDsl: z
|
|
65
|
+
.object({
|
|
66
|
+
entry: z.string().min(1),
|
|
67
|
+
exportName: z.string().min(1).optional(),
|
|
68
|
+
outFile: z.string().min(1).optional(),
|
|
69
|
+
typesOutFile: z.string().min(1).optional(),
|
|
70
|
+
zodOutFile: z.string().min(1).optional(),
|
|
71
|
+
namingStrategy: z.literal("camelToSnake").optional(),
|
|
72
|
+
})
|
|
73
|
+
.strict()
|
|
74
|
+
.optional(),
|
|
75
|
+
database: z.union([databaseSchema, z.array(databaseSchema).min(1)]),
|
|
76
|
+
kv: z.union([kvSchema, z.array(kvSchema)]).optional(),
|
|
77
|
+
r2: z.union([r2Schema, z.array(r2Schema)]).optional(),
|
|
78
|
+
auth: z
|
|
79
|
+
.object({
|
|
80
|
+
enabled: z.boolean(),
|
|
81
|
+
basePath: z.string().min(1),
|
|
82
|
+
options: z.custom<AppflareConfig["auth"]["options"]>((value) => {
|
|
83
|
+
return typeof value === "object" && value !== null;
|
|
84
|
+
}),
|
|
85
|
+
clientOptions: z.custom<AppflareConfig["auth"]["clientOptions"]>(
|
|
86
|
+
(value) => {
|
|
87
|
+
return typeof value === "object" && value !== null;
|
|
88
|
+
},
|
|
89
|
+
),
|
|
90
|
+
})
|
|
91
|
+
.strict(),
|
|
92
|
+
scheduler: schedulerConfigSchema.optional(),
|
|
93
|
+
realtime: realtimeConfigSchema.optional(),
|
|
94
|
+
wranglerOverrides: z.record(z.string(), z.unknown()).optional(),
|
|
95
|
+
build: z.boolean().optional(),
|
|
96
|
+
})
|
|
97
|
+
.strict();
|
|
98
|
+
|
|
99
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
100
|
+
return typeof value === "object" && value !== null;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function readLegacySchedulerConfig(
|
|
104
|
+
input: AppflareConfig,
|
|
105
|
+
): Partial<NonNullable<AppflareConfig["scheduler"]>> {
|
|
106
|
+
const raw = isRecord(input.wranglerOverrides)
|
|
107
|
+
? input.wranglerOverrides.scheduler
|
|
108
|
+
: undefined;
|
|
109
|
+
const parsed = schedulerConfigSchema.safeParse(raw);
|
|
110
|
+
if (!parsed.success) {
|
|
111
|
+
return {};
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return parsed.data;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function removeLegacySchedulerOverride(
|
|
118
|
+
overrides: AppflareConfig["wranglerOverrides"],
|
|
119
|
+
): AppflareConfig["wranglerOverrides"] {
|
|
120
|
+
if (!isRecord(overrides) || !("scheduler" in overrides)) {
|
|
121
|
+
return overrides;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const { scheduler: _scheduler, ...rest } = overrides;
|
|
125
|
+
return rest;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function normalizeConfig(input: AppflareConfig): NormalizedAppflareConfig {
|
|
129
|
+
const legacyScheduler = readLegacySchedulerConfig(input);
|
|
130
|
+
const scheduler = {
|
|
131
|
+
...(legacyScheduler ?? {}),
|
|
132
|
+
...(input.scheduler ?? {}),
|
|
133
|
+
};
|
|
134
|
+
const realtime = input.realtime ?? {};
|
|
135
|
+
|
|
136
|
+
return {
|
|
137
|
+
...input,
|
|
138
|
+
database: Array.isArray(input.database) ? input.database : [input.database],
|
|
139
|
+
kv: input.kv ? (Array.isArray(input.kv) ? input.kv : [input.kv]) : [],
|
|
140
|
+
r2: input.r2 ? (Array.isArray(input.r2) ? input.r2 : [input.r2]) : [],
|
|
141
|
+
scheduler: {
|
|
142
|
+
enabled: scheduler.enabled ?? true,
|
|
143
|
+
binding: scheduler.binding ?? "APPFLARE_SCHEDULER_QUEUE",
|
|
144
|
+
queue: scheduler.queue,
|
|
145
|
+
},
|
|
146
|
+
realtime: {
|
|
147
|
+
enabled: realtime.enabled ?? true,
|
|
148
|
+
binding: realtime.binding ?? "APPFLARE_REALTIME",
|
|
149
|
+
className: realtime.className ?? "AppflareRealtimeDurableObject",
|
|
150
|
+
objectName: realtime.objectName ?? "global",
|
|
151
|
+
subscribePath: realtime.subscribePath ?? "/realtime/subscribe",
|
|
152
|
+
websocketPath: realtime.websocketPath ?? "/realtime/ws",
|
|
153
|
+
protocol: realtime.protocol ?? "appflare.realtime.v1",
|
|
154
|
+
},
|
|
155
|
+
wranglerOverrides: removeLegacySchedulerOverride(input.wranglerOverrides),
|
|
156
|
+
wranglerOutDir:
|
|
157
|
+
input.wranglerOutDir ?? input.wranglerOutPath ?? input.outDir,
|
|
158
|
+
build: input.build ?? true,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export async function loadConfig(
|
|
163
|
+
configPathArg?: string,
|
|
164
|
+
): Promise<LoadedAppflareConfig> {
|
|
165
|
+
const configPath = isAbsolute(configPathArg ?? "")
|
|
166
|
+
? (configPathArg as string)
|
|
167
|
+
: resolve(process.cwd(), configPathArg ?? "appflare.config.ts");
|
|
168
|
+
|
|
169
|
+
const configDir = dirname(configPath);
|
|
170
|
+
const moduleUrl = pathToFileURL(configPath).href;
|
|
171
|
+
const configModule = await import(moduleUrl);
|
|
172
|
+
const raw = configModule.default;
|
|
173
|
+
const parsed = appflareConfigSchema.parse(raw) as AppflareConfig;
|
|
174
|
+
const config = normalizeConfig(parsed);
|
|
175
|
+
|
|
176
|
+
return {
|
|
177
|
+
configPath,
|
|
178
|
+
configDir,
|
|
179
|
+
scanDirAbs: resolve(configDir, config.scanDir),
|
|
180
|
+
outDirAbs: resolve(configDir, config.outDir),
|
|
181
|
+
wranglerOutDirAbs: resolve(configDir, config.wranglerOutDir),
|
|
182
|
+
config,
|
|
183
|
+
};
|
|
184
|
+
}
|