appflare 0.2.40 → 0.2.41
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/dist/cli/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
|
-
import {Command}from'commander';import
|
|
2
|
+
import {Command}from'commander';import Ia from'chokidar';import {existsSync}from'fs';import {resolve,isAbsolute,dirname,join,relative,extname}from'path';import {mkdir,readdir,rm}from'fs/promises';import {pathToFileURL,fileURLToPath}from'url';import*as g from'typescript';import {z}from'zod';function xe(e){return `import { betterAuth } from "better-auth";
|
|
3
3
|
import { withCloudflare } from "better-auth-cloudflare";
|
|
4
4
|
import { drizzleAdapter } from "better-auth/adapters/drizzle";
|
|
5
5
|
import { drizzle } from "drizzle-orm/d1";
|
|
@@ -57,7 +57,7 @@ export const createAuth = (
|
|
|
57
57
|
});
|
|
58
58
|
};
|
|
59
59
|
export const auth = createAuth();
|
|
60
|
-
`}function
|
|
60
|
+
`}function Te(){return `import { createAuthClient, type BetterAuthClientOptions } from "better-auth/client";
|
|
61
61
|
import type {
|
|
62
62
|
AppflareAuth,
|
|
63
63
|
AppflareAuthTokenResolver,
|
|
@@ -166,21 +166,21 @@ export function createAppflare<Options extends BetterAuthClientOptions = Inferre
|
|
|
166
166
|
): Appflare<Options> {
|
|
167
167
|
return new Appflare(options);
|
|
168
168
|
}
|
|
169
|
-
`}function
|
|
170
|
-
`)}function
|
|
169
|
+
`}function rr(e){let n=e.replace(/[^A-Za-z0-9_]/g,"_");return /^[0-9]/.test(n)?`_${n}`:n||"_route"}function ve(e){return e.split(/[^A-Za-z0-9]+/).filter(Boolean).map(n=>n.charAt(0).toUpperCase()+n.slice(1)).join("")}function ar(e){return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(e)?e:JSON.stringify(e)}function Re(e){let n={children:new Map};for(let t of e){let r=n;for(let a of t.segments){let o=r.children.get(a);o||(o={children:new Map},r.children.set(a,o)),r=o;}r.operation=t;}return n}function J(e,n=1){let t=" ".repeat(n),r=" ".repeat(n+1),a=Array.from(e.children.entries()).sort(([i],[s])=>i.localeCompare(s));if(a.length===0)return e.operation?`${e.operation.alias}Route(runtime)`:"{}";let o=["{"];for(let[i,s]of a)o.push(`${r}${ar(i)}: ${J(s,n+1)},`);return e.operation&&(o.push(`${r}run: ${e.operation.alias}Route(runtime).run,`),o.push(`${r}schema: ${e.operation.alias}Route(runtime).schema,`),e.operation.kind==="query"&&o.push(`${r}subscribe: ${e.operation.alias}Route(runtime).subscribe,`)),o.push(`${t}}`),o.join(`
|
|
170
|
+
`)}function or(e,n){if(e.kind!=="query"&&e.kind!=="mutation")return null;let t=e.clientSegments&&e.clientSegments.length>0?e.clientSegments:e.routePath.replace(/^\//,"").split("/").filter(Boolean).slice(1);if(t.length>=2&&t[t.length-1]===t[t.length-2]&&t.pop(),t.length===0)return null;let r=rr(`op_${n}_${e.kind}_${t.join("_")}`);return {kind:e.kind,routePath:e.routePath,queryName:e.handlerName??t.join("/"),segments:t,importPath:e.clientImportPath,exportName:e.exportName,alias:r,schemaConst:`${r}Schema`,typeBase:`${ve(e.kind)}${ve(t.join("_"))}`}}function ir(e){let n=`${e.typeBase}Input`,t=`${e.typeBase}Output`,r=`${e.typeBase}Schema`,a=e.kind==="query"?"GET":"POST";return e.kind==="query"?`const ${e.alias}Route = (
|
|
171
171
|
runtime: RequestRuntime,
|
|
172
|
-
): AppflareQueryRouteClient<typeof ${e.schemaConst}, ${
|
|
173
|
-
const run: AppflareQueryRouteClient<typeof ${e.schemaConst}, ${
|
|
174
|
-
...params: AppflareRunParams<${
|
|
172
|
+
): AppflareQueryRouteClient<typeof ${e.schemaConst}, ${t}> => {
|
|
173
|
+
const run: AppflareQueryRouteClient<typeof ${e.schemaConst}, ${t}>["run"] = async (
|
|
174
|
+
...params: AppflareRunParams<${n}>
|
|
175
175
|
) => {
|
|
176
|
-
const { args, options } = resolveRunParams<${
|
|
176
|
+
const { args, options } = resolveRunParams<${n}>(params);
|
|
177
177
|
const mergedOptions = mergeRouteOptions(runtime.options, options);
|
|
178
178
|
const resultOptions: AppflareRouteCallOptions<"return"> = {
|
|
179
179
|
...(mergedOptions ?? {}),
|
|
180
180
|
errorMode: "return",
|
|
181
181
|
};
|
|
182
182
|
const parsed = ${e.schemaConst}.parse(args);
|
|
183
|
-
return requestRoute<${
|
|
183
|
+
return requestRoute<${t}>(runtime.endpoint, {
|
|
184
184
|
route: ${JSON.stringify(e.routePath)},
|
|
185
185
|
method: ${JSON.stringify(a)},
|
|
186
186
|
input: parsed,
|
|
@@ -195,7 +195,7 @@ export function createAppflare<Options extends BetterAuthClientOptions = Inferre
|
|
|
195
195
|
args,
|
|
196
196
|
requestOptions,
|
|
197
197
|
signal,
|
|
198
|
-
}: AppflareQuerySubscribeOptions<${
|
|
198
|
+
}: AppflareQuerySubscribeOptions<${n}, ${t}>): AppflareRealtimeSubscription => {
|
|
199
199
|
const mergedOptions = mergeRouteOptions(runtime.options, requestOptions);
|
|
200
200
|
const parsedArgs = ${e.schemaConst}.parse(normalizeRouteInput(args));
|
|
201
201
|
const requestAuthToken = resolveRealtimeAuthToken(authToken, mergedOptions?.headers);
|
|
@@ -299,8 +299,8 @@ export function createAppflare<Options extends BetterAuthClientOptions = Inferre
|
|
|
299
299
|
const payload = (message as { payload?: unknown }).payload;
|
|
300
300
|
if (typeof payload === "object" && payload !== null && "data" in payload) {
|
|
301
301
|
onChange(
|
|
302
|
-
(payload as { data: ${
|
|
303
|
-
message as AppflareRealtimeQueryUpdate<${
|
|
302
|
+
(payload as { data: ${t} }).data,
|
|
303
|
+
message as AppflareRealtimeQueryUpdate<${t}>,
|
|
304
304
|
);
|
|
305
305
|
}
|
|
306
306
|
}
|
|
@@ -329,18 +329,18 @@ export function createAppflare<Options extends BetterAuthClientOptions = Inferre
|
|
|
329
329
|
};
|
|
330
330
|
};`:`const ${e.alias}Route = (
|
|
331
331
|
runtime: RequestRuntime,
|
|
332
|
-
): AppflareRouteClient<typeof ${e.schemaConst}, ${
|
|
333
|
-
const run: AppflareRouteClient<typeof ${e.schemaConst}, ${
|
|
334
|
-
...params: AppflareRunParams<${
|
|
332
|
+
): AppflareRouteClient<typeof ${e.schemaConst}, ${t}> => {
|
|
333
|
+
const run: AppflareRouteClient<typeof ${e.schemaConst}, ${t}>["run"] = async (
|
|
334
|
+
...params: AppflareRunParams<${n}>
|
|
335
335
|
) => {
|
|
336
|
-
const { args, options } = resolveRunParams<${
|
|
336
|
+
const { args, options } = resolveRunParams<${n}>(params);
|
|
337
337
|
const mergedOptions = mergeRouteOptions(runtime.options, options);
|
|
338
338
|
const resultOptions: AppflareRouteCallOptions<"return"> = {
|
|
339
339
|
...(mergedOptions ?? {}),
|
|
340
340
|
errorMode: "return",
|
|
341
341
|
};
|
|
342
342
|
const parsed = ${e.schemaConst}.parse(args);
|
|
343
|
-
return requestRoute<${
|
|
343
|
+
return requestRoute<${t}>(runtime.endpoint, {
|
|
344
344
|
route: ${JSON.stringify(e.routePath)},
|
|
345
345
|
method: ${JSON.stringify(a)},
|
|
346
346
|
input: parsed,
|
|
@@ -353,15 +353,15 @@ export function createAppflare<Options extends BetterAuthClientOptions = Inferre
|
|
|
353
353
|
schema: ${r},
|
|
354
354
|
run,
|
|
355
355
|
};
|
|
356
|
-
};`}function G(e){let
|
|
357
|
-
`),o=
|
|
358
|
-
export type ${
|
|
356
|
+
};`}function G(e){let n=e.map((l,c)=>or(l,c)).filter(l=>l!==null),t=n.filter(l=>l.kind==="query"),r=n.filter(l=>l.kind==="mutation"),a=n.map(l=>`import { ${l.exportName} as ${l.alias} } from "${l.importPath}";`).join(`
|
|
357
|
+
`),o=n.map(l=>{let c=`${l.typeBase}Input`,p=`${l.typeBase}Output`,d=`${l.typeBase}Schema`;return `const ${l.schemaConst} = z.object(${l.alias}.definition.args);
|
|
358
|
+
export type ${c} = z.input<typeof ${l.schemaConst}>;
|
|
359
359
|
export type ${p} = Awaited<ReturnType<typeof ${l.alias}.definition.handler>>;
|
|
360
360
|
export const ${d} = ${l.schemaConst};`}).join(`
|
|
361
361
|
|
|
362
|
-
`),i=
|
|
362
|
+
`),i=n.map(l=>ir(l)).join(`
|
|
363
363
|
|
|
364
|
-
`),s=J(
|
|
364
|
+
`),s=J(Re(t)),u=J(Re(r));return `import { z } from "zod";
|
|
365
365
|
import type {
|
|
366
366
|
AppflareErrorMode,
|
|
367
367
|
AppflareRequestError,
|
|
@@ -732,16 +732,16 @@ export function createMutationsClient(
|
|
|
732
732
|
options,
|
|
733
733
|
};
|
|
734
734
|
|
|
735
|
-
return ${
|
|
735
|
+
return ${u} as const;
|
|
736
736
|
}
|
|
737
737
|
|
|
738
738
|
export type QueriesClient = ReturnType<typeof createQueriesClient>;
|
|
739
739
|
export type MutationsClient = ReturnType<typeof createMutationsClient>;
|
|
740
|
-
`}function
|
|
740
|
+
`}function ke(){return `export * from "./types";
|
|
741
741
|
export * from "./appflare";
|
|
742
742
|
export * from "./storage";
|
|
743
743
|
export * from "./handlers";
|
|
744
|
-
`}function
|
|
744
|
+
`}function Se(){return `import type { StorageClient, StorageSignedUrlResponse, StorageListResponse } from "./types";
|
|
745
745
|
|
|
746
746
|
type AuthTokenResolver = (() => string | Promise<string>) | undefined;
|
|
747
747
|
|
|
@@ -933,7 +933,7 @@ export function createStorageClient(
|
|
|
933
933
|
},
|
|
934
934
|
};
|
|
935
935
|
}
|
|
936
|
-
`}function
|
|
936
|
+
`}function Ae(e){return `import { createAuthClient, type BetterAuthClientOptions } from "better-auth/client";
|
|
937
937
|
import type appflareConfig from "${e}";
|
|
938
938
|
|
|
939
939
|
export type AppflareConfig = typeof appflareConfig;
|
|
@@ -1116,7 +1116,7 @@ export type RealtimeSubscriptionResponse = {
|
|
|
1116
1116
|
};
|
|
1117
1117
|
};
|
|
1118
1118
|
};
|
|
1119
|
-
`}function
|
|
1119
|
+
`}function Ne(e,n){return [{relativePath:"client/index.ts",source:ke()},{relativePath:"client/types.ts",source:Ae(e)},{relativePath:"client/storage.ts",source:Se()},{relativePath:"client/handlers.ts",source:G(n)},{relativePath:"client/appflare.ts",source:Te()}]}function $e(e){return `import { defineConfig } from "drizzle-kit";
|
|
1120
1120
|
|
|
1121
1121
|
export default defineConfig({
|
|
1122
1122
|
dialect: "sqlite",
|
|
@@ -1128,7 +1128,7 @@ export default defineConfig({
|
|
|
1128
1128
|
token: "token",
|
|
1129
1129
|
},
|
|
1130
1130
|
});
|
|
1131
|
-
`}function
|
|
1131
|
+
`}function Ce(){return `
|
|
1132
1132
|
|
|
1133
1133
|
import { getHeaders } from "./server";
|
|
1134
1134
|
export async function resolveSession(
|
|
@@ -1162,7 +1162,7 @@ export async function resolveSession(
|
|
|
1162
1162
|
}
|
|
1163
1163
|
}
|
|
1164
1164
|
|
|
1165
|
-
`}function
|
|
1165
|
+
`}function qe(){return `
|
|
1166
1166
|
type SchedulerQueueBinding = {
|
|
1167
1167
|
send: (body: unknown, options?: SchedulerEnqueueOptions) => Promise<void>;
|
|
1168
1168
|
};
|
|
@@ -1199,7 +1199,7 @@ type R2BucketBinding = {
|
|
|
1199
1199
|
options?: { expiresIn?: number },
|
|
1200
1200
|
) => Promise<URL>;
|
|
1201
1201
|
};
|
|
1202
|
-
`}function
|
|
1202
|
+
`}function Fe(){return `
|
|
1203
1203
|
export function createScheduler(
|
|
1204
1204
|
queue?: SchedulerQueueBinding,
|
|
1205
1205
|
): Scheduler {
|
|
@@ -1220,7 +1220,7 @@ export function createScheduler(
|
|
|
1220
1220
|
},
|
|
1221
1221
|
};
|
|
1222
1222
|
}
|
|
1223
|
-
`}function
|
|
1223
|
+
`}function Me(){return `
|
|
1224
1224
|
function createContextErrorHelpers() {
|
|
1225
1225
|
return {
|
|
1226
1226
|
error: (status: number, message: string, details?: unknown) => {
|
|
@@ -1228,7 +1228,7 @@ function createContextErrorHelpers() {
|
|
|
1228
1228
|
},
|
|
1229
1229
|
};
|
|
1230
1230
|
}
|
|
1231
|
-
`}function
|
|
1231
|
+
`}function Ie(){return `
|
|
1232
1232
|
function normalizeStoragePath(path: string): string {
|
|
1233
1233
|
const trimmed = path.trim();
|
|
1234
1234
|
if (trimmed.length === 0) {
|
|
@@ -1284,7 +1284,7 @@ function buildSignedRequest(
|
|
|
1284
1284
|
headers,
|
|
1285
1285
|
});
|
|
1286
1286
|
}
|
|
1287
|
-
`}function
|
|
1287
|
+
`}function Ee(){return `
|
|
1288
1288
|
function createStorageApi(
|
|
1289
1289
|
ctx: AppflareContext,
|
|
1290
1290
|
bucket: R2BucketBinding | undefined,
|
|
@@ -1363,7 +1363,7 @@ function createStorageApi(
|
|
|
1363
1363
|
},
|
|
1364
1364
|
};
|
|
1365
1365
|
}
|
|
1366
|
-
`}function
|
|
1366
|
+
`}function Pe(e){return `
|
|
1367
1367
|
export async function createSchedulerExecutionContext(
|
|
1368
1368
|
env: Record<string, unknown>,
|
|
1369
1369
|
options: RegisterHandlersOptions,
|
|
@@ -1461,7 +1461,7 @@ export async function createExecutionContext(
|
|
|
1461
1461
|
ctx.storage = createStorageApi(ctx, storageBucket);
|
|
1462
1462
|
return ctx;
|
|
1463
1463
|
}
|
|
1464
|
-
`}function
|
|
1464
|
+
`}function Oe(e){return `import type { Context } from "hono";
|
|
1465
1465
|
import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@cloudflare/workers-types";
|
|
1466
1466
|
import { createAuth } from "./auth.config";
|
|
1467
1467
|
import {
|
|
@@ -1480,20 +1480,20 @@ import {
|
|
|
1480
1480
|
createQueryDb,
|
|
1481
1481
|
} from "./handlers";
|
|
1482
1482
|
|
|
1483
|
-
${
|
|
1484
|
-
|
|
1485
|
-
${Ne()}
|
|
1483
|
+
${qe()}
|
|
1486
1484
|
|
|
1487
1485
|
${Ce()}
|
|
1488
1486
|
|
|
1489
|
-
${qe()}
|
|
1490
|
-
|
|
1491
1487
|
${Fe()}
|
|
1492
1488
|
|
|
1493
1489
|
${Me()}
|
|
1494
1490
|
|
|
1495
|
-
${Ie(
|
|
1496
|
-
|
|
1491
|
+
${Ie()}
|
|
1492
|
+
|
|
1493
|
+
${Ee()}
|
|
1494
|
+
|
|
1495
|
+
${Pe(e)}
|
|
1496
|
+
`}function je(){return `
|
|
1497
1497
|
export async function executeOperation<
|
|
1498
1498
|
TShape extends ZodRawShape,
|
|
1499
1499
|
TResult,
|
|
@@ -1532,7 +1532,7 @@ export function handleOperationError(
|
|
|
1532
1532
|
return c.json({ message: (error as Error).message ?? "Unknown error" }, 500);
|
|
1533
1533
|
}
|
|
1534
1534
|
|
|
1535
|
-
`}function
|
|
1535
|
+
`}function De(){return `import type { Context } from "hono";
|
|
1536
1536
|
import { ZodError, type ZodRawShape } from "zod";
|
|
1537
1537
|
import {
|
|
1538
1538
|
type AppflareContext,
|
|
@@ -1541,8 +1541,8 @@ import {
|
|
|
1541
1541
|
type WorkerEnv,
|
|
1542
1542
|
} from "./handlers";
|
|
1543
1543
|
|
|
1544
|
-
${
|
|
1545
|
-
`}function
|
|
1544
|
+
${je()}
|
|
1545
|
+
`}function Ve(){return `import { betterAuth } from "better-auth";
|
|
1546
1546
|
import { auth } from "./auth.config";
|
|
1547
1547
|
import {
|
|
1548
1548
|
and,
|
|
@@ -1645,7 +1645,7 @@ export async function isStorageAllowed(
|
|
|
1645
1645
|
|
|
1646
1646
|
return false;
|
|
1647
1647
|
}
|
|
1648
|
-
`}function
|
|
1648
|
+
`}function Be(){return `type Primitive = string | number | boolean | Date;
|
|
1649
1649
|
type NonNil<T> = Exclude<T, null | undefined>;
|
|
1650
1650
|
type Friendly<T> = T extends Date ? Date | number : T;
|
|
1651
1651
|
type Comparable<T> = Friendly<Extract<NonNil<T>, Primitive>>;
|
|
@@ -1913,7 +1913,7 @@ export type QueryDeleteArgs<TName extends TableName> = {
|
|
|
1913
1913
|
where?: WhereInput<TableModel<TName>, TName>;
|
|
1914
1914
|
limit?: number;
|
|
1915
1915
|
};
|
|
1916
|
-
`}function
|
|
1916
|
+
`}function We(){return `type AggregateWithInput<TName extends TableName> =
|
|
1917
1917
|
QueryWithInput<TName, NativeFindManyWith<TName>>;
|
|
1918
1918
|
|
|
1919
1919
|
type NumericFieldKey<TName extends TableName> = NumericModelFieldKey<
|
|
@@ -2045,7 +2045,7 @@ export type DbMutationEvent = {
|
|
|
2045
2045
|
export type QueryDbOptions = {
|
|
2046
2046
|
onMutation?: (event: DbMutationEvent) => void;
|
|
2047
2047
|
};
|
|
2048
|
-
`}function
|
|
2048
|
+
`}function He(){return `function isRecord(value: unknown): value is Record<string, unknown> {
|
|
2049
2049
|
return typeof value === "object" && value !== null;
|
|
2050
2050
|
}
|
|
2051
2051
|
|
|
@@ -3424,7 +3424,7 @@ function inferConflictTarget(table: unknown): string[] {
|
|
|
3424
3424
|
|
|
3425
3425
|
return [];
|
|
3426
3426
|
}
|
|
3427
|
-
`}function
|
|
3427
|
+
`}function Le(){return `const mergedSchema = {
|
|
3428
3428
|
...authSchema,
|
|
3429
3429
|
...schema,
|
|
3430
3430
|
};
|
|
@@ -3699,9 +3699,9 @@ type TableFindFirstResult<
|
|
|
3699
3699
|
type TableInsertModel<TName extends TableName> = InferInsertModel<
|
|
3700
3700
|
(typeof mergedSchema)[TName]
|
|
3701
3701
|
>;
|
|
3702
|
-
`}function
|
|
3702
|
+
`}function ze(){return [Le(),Be(),We(),He()].join(`
|
|
3703
3703
|
|
|
3704
|
-
`)}function
|
|
3704
|
+
`)}function Ue(){return ` count: async (args?: QueryCountArgs<TableName>) => {
|
|
3705
3705
|
const withValue = args?.with;
|
|
3706
3706
|
const pathSegments = args?.field
|
|
3707
3707
|
? splitAggregateFieldPath(String(args.field))
|
|
@@ -3872,7 +3872,7 @@ type TableInsertModel<TName extends TableName> = InferInsertModel<
|
|
|
3872
3872
|
},
|
|
3873
3873
|
}) as AppflareQueryDb;
|
|
3874
3874
|
}
|
|
3875
|
-
`}function
|
|
3875
|
+
`}function Qe(){return `export class AppflareHandledError extends Error {
|
|
3876
3876
|
public readonly status: number;
|
|
3877
3877
|
public readonly payload: unknown;
|
|
3878
3878
|
|
|
@@ -3882,7 +3882,7 @@ type TableInsertModel<TName extends TableName> = InferInsertModel<
|
|
|
3882
3882
|
this.payload = payload;
|
|
3883
3883
|
}
|
|
3884
3884
|
}
|
|
3885
|
-
`}function
|
|
3885
|
+
`}function _e(){return ` findMany: (args?: Record<string, unknown>) => {
|
|
3886
3886
|
const where = isRecord(args?.where)
|
|
3887
3887
|
? (args?.where as Record<string, unknown>)
|
|
3888
3888
|
: undefined;
|
|
@@ -4036,7 +4036,7 @@ type TableInsertModel<TName extends TableName> = InferInsertModel<
|
|
|
4036
4036
|
);
|
|
4037
4037
|
});
|
|
4038
4038
|
},
|
|
4039
|
-
`}function
|
|
4039
|
+
`}function Ke(){return `export function createQueryDb(
|
|
4040
4040
|
$db: AppflareDb,
|
|
4041
4041
|
options?: QueryDbOptions,
|
|
4042
4042
|
): AppflareQueryDb {
|
|
@@ -4078,7 +4078,7 @@ type TableInsertModel<TName extends TableName> = InferInsertModel<
|
|
|
4078
4078
|
};
|
|
4079
4079
|
|
|
4080
4080
|
const tableApi = {
|
|
4081
|
-
`}function
|
|
4081
|
+
`}function Je(){return ` insert: async <TArgs extends QueryInsertArgs<TableName>>(args: TArgs) => {
|
|
4082
4082
|
const transaction = ($db as any).transaction;
|
|
4083
4083
|
|
|
4084
4084
|
const valuesArray = Array.isArray(args.values)
|
|
@@ -4772,17 +4772,17 @@ type TableInsertModel<TName extends TableName> = InferInsertModel<
|
|
|
4772
4772
|
);
|
|
4773
4773
|
return rows;
|
|
4774
4774
|
},
|
|
4775
|
-
`}function
|
|
4775
|
+
`}function Ge(){return [Ke(),_e(),Je(),Ue(),Qe()].join(`
|
|
4776
4776
|
|
|
4777
|
-
`)}function
|
|
4777
|
+
`)}function Ze(e=[],n=[]){let t=n.map(i=>` ${i.name}?: ${i.tsType} | null;`).join(`
|
|
4778
4778
|
`),a=[e.length>0?[" role: UserRole;"," banned: boolean | null;"," banReason?: string | null | undefined;"," banExpires?: Date | null | undefined;"].join(`
|
|
4779
|
-
`):"",
|
|
4779
|
+
`):"",t].filter(Boolean).join(`
|
|
4780
4780
|
`);return `type AuthSession = typeof auth.$Infer.Session;
|
|
4781
4781
|
type AuthAdapter = Awaited<typeof auth.$context>["internalAdapter"];
|
|
4782
4782
|
${e.length>0?`export type UserRole = ${e.map(i=>`"${i}"`).join(" | ")};
|
|
4783
4783
|
type User = import("better-auth").User & {
|
|
4784
4784
|
${a}
|
|
4785
|
-
};`:
|
|
4785
|
+
};`:n.length>0?`type User = import("better-auth").User & {
|
|
4786
4786
|
${a}
|
|
4787
4787
|
};`:'type User = import("better-auth").User;'}
|
|
4788
4788
|
type Session = AuthSession['session']
|
|
@@ -4871,7 +4871,7 @@ export type AppflareContext = {
|
|
|
4871
4871
|
storage: AppflareStorage;
|
|
4872
4872
|
error: (status: number, message: string, details?: unknown) => never;
|
|
4873
4873
|
};
|
|
4874
|
-
`}function
|
|
4874
|
+
`}function Xe(){return `type InferOperationArgs<TShape extends ZodRawShape> = z.output<z.ZodObject<TShape>>;
|
|
4875
4875
|
|
|
4876
4876
|
export type SchedulerEnqueueOptions = {
|
|
4877
4877
|
delaySeconds?: number;
|
|
@@ -5003,40 +5003,40 @@ export function cron(definition: CronDefinition): RegisteredCron {
|
|
|
5003
5003
|
definition,
|
|
5004
5004
|
};
|
|
5005
5005
|
}
|
|
5006
|
-
`}function
|
|
5006
|
+
`}function Ye(e=[],n=[]){return [Ve(),ze(),Ge(),Ze(e,n),Xe()].join(`
|
|
5007
5007
|
|
|
5008
|
-
`)}function
|
|
5008
|
+
`)}function et(e,n=[],t=[]){return `import type { Context } from "hono";
|
|
5009
5009
|
import type { D1Database } from "@cloudflare/workers-types";
|
|
5010
5010
|
import { drizzle } from "drizzle-orm/d1";
|
|
5011
5011
|
import { z, type ZodRawShape } from "zod";
|
|
5012
5012
|
import * as authSchema from "./auth.schema";
|
|
5013
5013
|
import * as schema from "${e}";
|
|
5014
5014
|
|
|
5015
|
-
${
|
|
5016
|
-
`}function
|
|
5017
|
-
`)}function
|
|
5018
|
-
`)}function
|
|
5019
|
-
`)}function
|
|
5015
|
+
${Ye(n,t)}
|
|
5016
|
+
`}function sr(e){let n=e.replace(/[^A-Za-z0-9_]/g,"_");return /^[0-9]/.test(n)?`_${n}`:n}function lr(e,n){let t=e.routePath.replace(/^\//,"").replace(/\//g,"_");return sr(`op_${n}_${t}`)}function ur(e){return e.map((n,t)=>({operation:n,index:t,alias:lr(n,t)}))}function cr(e){return e.map(({operation:n,alias:t})=>`import { ${n.exportName} as ${t} } from "${n.importPath}";`).join(`
|
|
5017
|
+
`)}function dr(e){return e.filter(({operation:n})=>n.kind==="query"||n.kind==="mutation").map(({alias:n})=>`const ${`${n}Schema`} = z.object(${n}.definition.args);`).join(`
|
|
5018
|
+
`)}function pr(e){return e.filter(({operation:n})=>n.kind==="scheduler").map(({alias:n})=>`const ${`${n}SchedulerSchema`} = ${n}.definition.args ? z.object(${n}.definition.args) : z.undefined();`).join(`
|
|
5019
|
+
`)}function mr(e){return e.filter(({operation:n})=>n.kind==="query").map(({operation:n,alias:t})=>{let r=`${t}Schema`;return `
|
|
5020
5020
|
app.get(
|
|
5021
|
-
"${
|
|
5021
|
+
"${n.routePath}",
|
|
5022
5022
|
sValidator("query", ${r}),
|
|
5023
5023
|
async (c) => {
|
|
5024
5024
|
const ctx = await createExecutionContext(c, options);
|
|
5025
5025
|
try {
|
|
5026
|
-
return await executeOperation(c, ${
|
|
5026
|
+
return await executeOperation(c, ${t}, c.req.valid("query"), ctx);
|
|
5027
5027
|
} catch (error) {
|
|
5028
5028
|
return handleOperationError(c, error, "Invalid query arguments");
|
|
5029
5029
|
}
|
|
5030
5030
|
},
|
|
5031
5031
|
);`}).join(`
|
|
5032
|
-
`)}function
|
|
5032
|
+
`)}function fr(e){return e.filter(({operation:n})=>n.kind==="mutation").map(({operation:n,alias:t})=>{let r=`${t}Schema`;return `
|
|
5033
5033
|
app.post(
|
|
5034
|
-
"${
|
|
5034
|
+
"${n.routePath}",
|
|
5035
5035
|
sValidator("json", ${r}),
|
|
5036
5036
|
async (c) => {
|
|
5037
5037
|
const ctx = await createExecutionContext(c, options);
|
|
5038
5038
|
try {
|
|
5039
|
-
const response = await executeOperation(c, ${
|
|
5039
|
+
const response = await executeOperation(c, ${t}, c.req.valid("json"), ctx);
|
|
5040
5040
|
await publishMutationEvents(c, options, ctx.mutationEvents);
|
|
5041
5041
|
return response;
|
|
5042
5042
|
} catch (error) {
|
|
@@ -5044,26 +5044,26 @@ import * as schema from "${e}";
|
|
|
5044
5044
|
}
|
|
5045
5045
|
},
|
|
5046
5046
|
);`}).join(`
|
|
5047
|
-
`)}function
|
|
5047
|
+
`)}function gr(e){return e.filter(({operation:n})=>n.kind==="query").map(({operation:n,alias:t})=>{let r=`${t}Schema`,a=n.handlerName??n.routePath;return `
|
|
5048
5048
|
${JSON.stringify(a)}: {
|
|
5049
|
-
definition: ${
|
|
5049
|
+
definition: ${t}.definition,
|
|
5050
5050
|
schema: ${r},
|
|
5051
5051
|
},`}).join(`
|
|
5052
|
-
`)}function
|
|
5052
|
+
`)}function hr(e){return e.filter(({operation:n})=>n.kind==="scheduler").map(({operation:n,alias:t})=>{let r=`${t}SchedulerSchema`,a=n.taskName??`${n.routePath}`;return `
|
|
5053
5053
|
${JSON.stringify(a)}: {
|
|
5054
|
-
definition: ${
|
|
5054
|
+
definition: ${t}.definition,
|
|
5055
5055
|
schema: ${r},
|
|
5056
5056
|
},`}).join(`
|
|
5057
|
-
`)}function
|
|
5058
|
-
`)}function
|
|
5057
|
+
`)}function yr(e){return e.filter(({operation:n})=>n.kind==="scheduler").map(({operation:n,alias:t})=>{let r=n.taskName??`${n.routePath}`;return ` ${JSON.stringify(r)}: Parameters<typeof ${t}.definition.handler>[1];`}).join(`
|
|
5058
|
+
`)}function br(e){return e.filter(({operation:n})=>n.kind==="cron").map(({operation:n,alias:t})=>{let r=n.taskName??`${n.routePath}`,a=n.cronTriggers??[];return `
|
|
5059
5059
|
{
|
|
5060
5060
|
taskName: ${JSON.stringify(r)},
|
|
5061
5061
|
cronTriggers: ${JSON.stringify(a)},
|
|
5062
|
-
definition: ${
|
|
5062
|
+
definition: ${t}.definition,
|
|
5063
5063
|
},`}).join(`
|
|
5064
|
-
`)}function
|
|
5065
|
-
${
|
|
5066
|
-
`)}function
|
|
5064
|
+
`)}function wr(e){return e.filter(({operation:n})=>n.kind==="storage").map(({alias:n})=>`
|
|
5065
|
+
${n}.definition.handler,`).join(`
|
|
5066
|
+
`)}function tt(e){let n=ur(e);return {imports:cr(n),operationSchemas:dr(n),schedulerSchemas:pr(n),queryRoutes:mr(n),mutationRoutes:fr(n),queryRegistryEntries:gr(n),schedulerEntries:hr(n),schedulerPayloadMapEntries:yr(n),cronEntries:br(n),storageHandlersEntries:wr(n)}}var nt=`
|
|
5067
5067
|
function getRealtimeStub(
|
|
5068
5068
|
env: Record<string, unknown>,
|
|
5069
5069
|
options: RegisterHandlersOptions,
|
|
@@ -5137,7 +5137,7 @@ function buildRealtimeWsUrl(requestUrl: string, websocketPath: string): string {
|
|
|
5137
5137
|
url.protocol = url.protocol === "https:" ? "wss:" : "ws:";
|
|
5138
5138
|
return url.toString();
|
|
5139
5139
|
}
|
|
5140
|
-
`;var
|
|
5140
|
+
`;var rt=`
|
|
5141
5141
|
export class AppflareRealtimeDurableObject {
|
|
5142
5142
|
private readonly subscriptions = new Map<string, RealtimeSubscription>();
|
|
5143
5143
|
private readonly sockets = new Map<string, WebSocket>();
|
|
@@ -5280,7 +5280,7 @@ export class AppflareRealtimeDurableObject {
|
|
|
5280
5280
|
return new Response("Not found", { status: 404 });
|
|
5281
5281
|
}
|
|
5282
5282
|
}
|
|
5283
|
-
`;var
|
|
5283
|
+
`;var at=`
|
|
5284
5284
|
async function publishMutationEvents(
|
|
5285
5285
|
c: { req: { raw: Request }; env: Record<string, unknown> },
|
|
5286
5286
|
options: RegisterHandlersOptions,
|
|
@@ -5381,7 +5381,7 @@ async function publishMutationEvents(
|
|
|
5381
5381
|
}
|
|
5382
5382
|
}
|
|
5383
5383
|
}
|
|
5384
|
-
`;var
|
|
5384
|
+
`;var ot=`
|
|
5385
5385
|
function registerRealtimeRoutes(
|
|
5386
5386
|
app: Hono<WorkerEnv>,
|
|
5387
5387
|
options: RegisterHandlersOptions,
|
|
@@ -5544,7 +5544,7 @@ function registerRealtimeRoutes(
|
|
|
5544
5544
|
return stub.fetch(c.req.raw);
|
|
5545
5545
|
});
|
|
5546
5546
|
}
|
|
5547
|
-
`;var
|
|
5547
|
+
`;var it=`
|
|
5548
5548
|
type RealtimeSubscription = {
|
|
5549
5549
|
token: string;
|
|
5550
5550
|
signature: string;
|
|
@@ -5573,7 +5573,7 @@ type RealtimeDurableObjectNamespace = {
|
|
|
5573
5573
|
type RealtimeQueryName = keyof typeof realtimeQueryHandlers extends never
|
|
5574
5574
|
? string
|
|
5575
5575
|
: Extract<keyof typeof realtimeQueryHandlers, string>;
|
|
5576
|
-
`;var
|
|
5576
|
+
`;var st=`
|
|
5577
5577
|
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
5578
5578
|
return typeof value === "object" && value !== null;
|
|
5579
5579
|
}
|
|
@@ -6082,9 +6082,9 @@ function doesSubscriptionMatchMutation(
|
|
|
6082
6082
|
|
|
6083
6083
|
return false;
|
|
6084
6084
|
}
|
|
6085
|
-
`;var
|
|
6085
|
+
`;var lt=[it,st,nt,at,ot,rt].join(`
|
|
6086
6086
|
|
|
6087
|
-
`);var
|
|
6087
|
+
`);var ut=`
|
|
6088
6088
|
function parseExpiresIn(value: string | undefined): number | undefined {
|
|
6089
6089
|
if (!value) {
|
|
6090
6090
|
return undefined;
|
|
@@ -6282,7 +6282,7 @@ export function registerGeneratedStorageRoutes(
|
|
|
6282
6282
|
}
|
|
6283
6283
|
});
|
|
6284
6284
|
}
|
|
6285
|
-
`;var
|
|
6285
|
+
`;var ct=`
|
|
6286
6286
|
type SchedulerTaskName = keyof typeof schedulerHandlers extends never
|
|
6287
6287
|
? string
|
|
6288
6288
|
: keyof typeof schedulerHandlers;
|
|
@@ -6337,7 +6337,7 @@ export async function executeScheduledBatch(
|
|
|
6337
6337
|
}
|
|
6338
6338
|
}
|
|
6339
6339
|
}
|
|
6340
|
-
`;var
|
|
6340
|
+
`;var dt=`
|
|
6341
6341
|
export async function executeCronTriggers(
|
|
6342
6342
|
controller: { cron: string },
|
|
6343
6343
|
env: Record<string, unknown>,
|
|
@@ -6362,7 +6362,7 @@ export async function executeCronTriggers(
|
|
|
6362
6362
|
}
|
|
6363
6363
|
}
|
|
6364
6364
|
}
|
|
6365
|
-
`;function
|
|
6365
|
+
`;function pt(e){let{imports:n,operationSchemas:t,schedulerSchemas:r,queryRoutes:a,mutationRoutes:o,queryRegistryEntries:i,schedulerEntries:s,schedulerPayloadMapEntries:u,cronEntries:l,storageHandlersEntries:c}=tt(e);return `import { sValidator } from "@hono/standard-validator";
|
|
6366
6366
|
import type { Hono } from "hono";
|
|
6367
6367
|
import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@cloudflare/workers-types";
|
|
6368
6368
|
import { ZodError, z } from "zod";
|
|
@@ -6379,10 +6379,10 @@ import {
|
|
|
6379
6379
|
} from "./handlers";
|
|
6380
6380
|
import { createExecutionContext, createSchedulerExecutionContext, resolveSession } from "./handlers.context";
|
|
6381
6381
|
import { executeOperation, handleOperationError } from "./handlers.execution";
|
|
6382
|
-
${
|
|
6383
|
-
${
|
|
6382
|
+
${n?`
|
|
6383
|
+
${n}`:""}
|
|
6384
6384
|
|
|
6385
|
-
${
|
|
6385
|
+
${t}
|
|
6386
6386
|
${r}
|
|
6387
6387
|
|
|
6388
6388
|
const realtimeQueryHandlers = {${i||`
|
|
@@ -6393,8 +6393,8 @@ const schedulerHandlers = {${s||`
|
|
|
6393
6393
|
`}
|
|
6394
6394
|
} as const;
|
|
6395
6395
|
|
|
6396
|
-
type GeneratedSchedulerPayloadMap = {${
|
|
6397
|
-
${
|
|
6396
|
+
type GeneratedSchedulerPayloadMap = {${u?`
|
|
6397
|
+
${u}
|
|
6398
6398
|
`:""}};
|
|
6399
6399
|
|
|
6400
6400
|
declare global {
|
|
@@ -6413,15 +6413,15 @@ const cronHandlers: readonly CronHandlerEntry[] = [${l||`
|
|
|
6413
6413
|
`}
|
|
6414
6414
|
];
|
|
6415
6415
|
|
|
6416
|
-
const storageHandlers = [${
|
|
6416
|
+
const storageHandlers = [${c||`
|
|
6417
6417
|
`}
|
|
6418
6418
|
] as const;
|
|
6419
6419
|
|
|
6420
6420
|
setStorageHandlers([...storageHandlers]);
|
|
6421
6421
|
|
|
6422
|
-
${
|
|
6422
|
+
${ct}
|
|
6423
6423
|
|
|
6424
|
-
${
|
|
6424
|
+
${lt}
|
|
6425
6425
|
|
|
6426
6426
|
export function registerGeneratedHandlers(
|
|
6427
6427
|
app: Hono<WorkerEnv>,
|
|
@@ -6434,20 +6434,20 @@ export function registerGeneratedHandlers(
|
|
|
6434
6434
|
`}
|
|
6435
6435
|
}
|
|
6436
6436
|
|
|
6437
|
-
${st}
|
|
6438
|
-
|
|
6439
6437
|
${ut}
|
|
6440
|
-
|
|
6441
|
-
|
|
6442
|
-
|
|
6443
|
-
|
|
6438
|
+
|
|
6439
|
+
${dt}
|
|
6440
|
+
`}function Z(e,n,t,r=[],a=[]){let o=et(e,r,a),i=Oe(t),s=De(),u=pt(n);return [{relativePath:"handlers.ts",source:o},{relativePath:"handlers.context.ts",source:i},{relativePath:"handlers.execution.ts",source:s},{relativePath:"handlers.routes.ts",source:u}]}function xr(e){return e?`,
|
|
6441
|
+
KV: c.env["${e}"] as KVNamespace`:""}function mt(e,n){return `{
|
|
6442
|
+
DATABASE: c.env["${e}"] as D1Database${xr(n)}
|
|
6443
|
+
}`}function ft(e,n,t){return `app.on(["GET", "POST"], "${e}/*", async (c) => {
|
|
6444
6444
|
const auth = createAuth(
|
|
6445
|
-
${
|
|
6445
|
+
${mt(n,t)},
|
|
6446
6446
|
c.req.raw.cf as IncomingRequestCfProperties | undefined,
|
|
6447
6447
|
);
|
|
6448
6448
|
return auth.handler(getSanitizedRequest(c.req.raw));
|
|
6449
6449
|
});
|
|
6450
|
-
`}function
|
|
6450
|
+
`}function Tr(){return `export const getHeaders = (headers: Headers) => {
|
|
6451
6451
|
const newHeaders = Object.fromEntries(headers as any);
|
|
6452
6452
|
const headerObject: Record<string, any> = {};
|
|
6453
6453
|
let hasCookie = false;
|
|
@@ -6477,15 +6477,15 @@ ${ut}
|
|
|
6477
6477
|
|
|
6478
6478
|
return headerObject as any as Headers;
|
|
6479
6479
|
};
|
|
6480
|
-
`}function
|
|
6480
|
+
`}function vr(){return `export const getSanitizedRequest = (req: Request) => {
|
|
6481
6481
|
const newRequest = new Request(req, {
|
|
6482
6482
|
headers: getHeaders(req.headers),
|
|
6483
6483
|
});
|
|
6484
6484
|
return newRequest;
|
|
6485
6485
|
};
|
|
6486
|
-
`}function
|
|
6487
|
-
`+
|
|
6488
|
-
`+
|
|
6486
|
+
`}function gt(){return Tr()+`
|
|
6487
|
+
`+vr()}function ht(e,n,t){return ft(e,n,t)+`
|
|
6488
|
+
`+gt()}function yt(){return `const app = new Hono<WorkerEnv>();
|
|
6489
6489
|
|
|
6490
6490
|
app.use('*', cors({
|
|
6491
6491
|
origin: (origin, c) => {
|
|
@@ -6501,7 +6501,7 @@ app.use('*', cors({
|
|
|
6501
6501
|
},
|
|
6502
6502
|
credentials: true
|
|
6503
6503
|
}));
|
|
6504
|
-
`}function
|
|
6504
|
+
`}function bt(){return `export { AppflareRealtimeDurableObject };
|
|
6505
6505
|
|
|
6506
6506
|
export default {
|
|
6507
6507
|
fetch: app.fetch,
|
|
@@ -6512,54 +6512,64 @@ export default {
|
|
|
6512
6512
|
await executeCronTriggers(controller, env, generatedHandlerOptions);
|
|
6513
6513
|
},
|
|
6514
6514
|
};
|
|
6515
|
-
`}function
|
|
6516
|
-
kvBinding: "${
|
|
6515
|
+
`}function wt(e,n,t="APPFLARE_SCHEDULER_QUEUE",r,a="APPFLARE_REALTIME",o="global",i="/realtime/subscribe",s="/realtime/ws",u="appflare.realtime.v1"){let l=n?`
|
|
6516
|
+
kvBinding: "${n}",`:"",c=r?`
|
|
6517
6517
|
r2Binding: "${r}",`:"",p=`
|
|
6518
6518
|
realtimeBinding: "${a}",
|
|
6519
6519
|
realtimeObjectName: "${o}",
|
|
6520
6520
|
realtimeSubscribePath: "${i}",
|
|
6521
6521
|
realtimeWebsocketPath: "${s}",
|
|
6522
|
-
realtimeProtocol: "${
|
|
6522
|
+
realtimeProtocol: "${u}",`;return `const generatedHandlerOptions = {
|
|
6523
6523
|
databaseBinding: "${e}",${l}
|
|
6524
|
-
schedulerBinding: "${
|
|
6524
|
+
schedulerBinding: "${t}",${c}${p}
|
|
6525
6525
|
};
|
|
6526
6526
|
registerGeneratedHandlers(app, generatedHandlerOptions);
|
|
6527
6527
|
registerGeneratedStorageRoutes(app, generatedHandlerOptions);
|
|
6528
6528
|
registerAdminDashboard(app, generatedHandlerOptions);
|
|
6529
|
-
`}function
|
|
6529
|
+
`}function xt(){return `import { createAuth } from "./auth.config";
|
|
6530
6530
|
import { AppflareRealtimeDurableObject, executeCronTriggers, executeScheduledBatch, registerGeneratedHandlers, registerGeneratedStorageRoutes } from "./handlers.routes";
|
|
6531
6531
|
import { registerAdminDashboard } from "./admin.routes";
|
|
6532
6532
|
import { Hono } from "hono";
|
|
6533
6533
|
import { cors } from "hono/cors";
|
|
6534
6534
|
import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@cloudflare/workers-types";
|
|
6535
|
-
`}function
|
|
6535
|
+
`}function Tt(){return `type WorkerEnv = {
|
|
6536
6536
|
Bindings: Record<string, unknown>;
|
|
6537
6537
|
};
|
|
6538
|
-
`}function
|
|
6538
|
+
`}function vt(e,n,t,r,a,o,i,s,u,l){return xt()+Tt()+yt()+wt(n,t,r,a,o,i,s,u,l)+ht(e,n,t)+bt()}function Rt(e){return !!e&&typeof e=="object"&&!Array.isArray(e)}function X(e,n){let t={...e};for(let[r,a]of Object.entries(n)){let o=t[r];if(Rt(o)&&Rt(a)){t[r]=X(o,a);continue}t[r]=a;}return t}function Rr(e){return Array.from(new Set(e.filter(n=>n.length>0)))}function kt(e,n){let t=n.filter(d=>d.kind==="scheduler"||d.kind==="cron"),r=Rr(n.filter(d=>d.kind==="cron").flatMap(d=>d.cronTriggers??[])),a=e.config.scheduler.enabled&&t.length>0,o=e.config.realtime.enabled,s=(typeof e.config.wranglerOverrides?.name=="string"?e.config.wranglerOverrides.name:void 0)??"appflare-worker",u=e.config.scheduler.queue??`${s}-scheduler`,l={name:s,main:"./src/index.ts",d1_databases:e.config.database.map(d=>({binding:d.binding,database_name:d.databaseName,database_id:d.databaseId,preview_database_id:d.previewDatabaseId??d.databaseId,...d.migrationsDir?{migrations_dir:d.migrationsDir}:{}})),kv_namespaces:e.config.kv.map(d=>({binding:d.binding,id:d.id,...d.previewId?{preview_id:d.previewId}:{}})),r2_buckets:e.config.r2.map(d=>({binding:d.binding,bucket_name:d.bucketName,...d.previewBucketName?{preview_bucket_name:d.previewBucketName}:{},...d.jurisdiction?{jurisdiction:d.jurisdiction}:{}})),...a?{queues:{producers:[{binding:e.config.scheduler.binding,queue:u}],consumers:[{queue:u}]}}:{},...r.length>0?{triggers:{crons:r}}:{},...o?{durable_objects:{bindings:[{name:e.config.realtime.binding,class_name:e.config.realtime.className}]},migrations:[{tag:"appflare-realtime-v1",new_sqlite_classes:[e.config.realtime.className]}]}:{}};if(!e.config.wranglerOverrides)return l;let{scheduler:c,...p}=e.config.wranglerOverrides;return X(l,p)}function Y(e){let n={children:[],handlers:[]};for(let t of e){let r=t.clientSegments??[t.exportName],a=n;for(let o=0;o<r.length-1;o++){let i=r[o],s=a.children.find(u=>u.name===i&&u.type==="folder");s||(s={name:i,type:"folder",children:[],handlers:[]},a.children.push(s)),a=s;}a.handlers.push(t);}return n.children}function St(e){return e.tables.map(n=>({exportName:n.exportName,tableName:n.tableName,columns:n.columns.map(t=>t.name)}))}function At(e){return `<li data-name="users">
|
|
6539
6539
|
<a href="/admin/users" hx-get="/admin/users" hx-target="#main-content" hx-push-url="true" hx-swap="outerHTML" class="sidebar-link flex items-center gap-2 px-3 py-2 text-sm rounded-lg w-full">
|
|
6540
6540
|
<iconify-icon icon="mdi:account-group" width="16" height="16" class="opacity-50 shrink-0"></iconify-icon>
|
|
6541
6541
|
<span class="truncate">users</span>
|
|
6542
6542
|
</a>
|
|
6543
6543
|
</li>
|
|
6544
|
-
${e.map(
|
|
6545
|
-
<a href="/admin/table/${
|
|
6544
|
+
${e.map(t=>`<li data-name="${t.tableName}">
|
|
6545
|
+
<a href="/admin/table/${t.exportName}" hx-get="/admin/table/${t.exportName}" hx-target="#main-content" hx-push-url="true" hx-swap="outerHTML" class="sidebar-link flex items-center gap-2 px-3 py-2 text-sm rounded-lg w-full">
|
|
6546
6546
|
<iconify-icon icon="mdi:table" width="16" height="16" class="opacity-50 shrink-0"></iconify-icon>
|
|
6547
|
-
<span class="truncate">${
|
|
6547
|
+
<span class="truncate">${t.tableName}</span>
|
|
6548
6548
|
</a>
|
|
6549
6549
|
</li>`).join(`
|
|
6550
|
-
`)}`}function
|
|
6551
|
-
|
|
6552
|
-
|
|
6553
|
-
|
|
6554
|
-
|
|
6555
|
-
|
|
6556
|
-
|
|
6557
|
-
|
|
6558
|
-
|
|
6559
|
-
|
|
6560
|
-
|
|
6561
|
-
|
|
6562
|
-
|
|
6550
|
+
`)}`}function ee(e,n){let t=" ".repeat(n),r=e.children.length>0,a=e.handlers.length>0,o=r||a,i="";if(o){`folder-${e.name.replace(/[^a-zA-Z0-9]/g,"-")}-${n}`;i+=`
|
|
6551
|
+
${t}<li data-name="${e.name}" class="folder-item">`,i+=`
|
|
6552
|
+
${t} <details class="group/folder" open>`,i+=`
|
|
6553
|
+
${t} <summary class="sidebar-link flex items-center gap-2 px-3 py-2 text-sm rounded-lg w-full cursor-pointer list-none">`,i+=`
|
|
6554
|
+
${t} <iconify-icon icon="solar:folder-bold-duotone" width="16" height="16" class="opacity-50 shrink-0 transition-transform group-open/folder:rotate-0"></iconify-icon>`,i+=`
|
|
6555
|
+
${t} <span class="truncate font-medium">${e.name}</span>`,i+=`
|
|
6556
|
+
${t} </summary>`,i+=`
|
|
6557
|
+
${t} <ul class="flex flex-col gap-0.5 ml-4 border-l border-base-200 pl-2">`;for(let u of e.children)i+=ee(u,n+2);for(let u of e.handlers){let l=u.kind==="query"?"solar:reorder-linear":"solar:bolt-linear";i+=`
|
|
6558
|
+
${t} <li data-name="${u.exportName}">`,i+=`
|
|
6559
|
+
${t} <a href="/admin/functions${u.routePath}" hx-get="/admin/functions${u.routePath}" hx-target="#main-content" hx-push-url="true" hx-swap="outerHTML" class="sidebar-link flex items-center gap-2 px-3 py-2 text-sm rounded-lg w-full">`,i+=`
|
|
6560
|
+
${t} <iconify-icon icon="${l}" width="16" height="16" class="opacity-50 shrink-0"></iconify-icon>`,i+=`
|
|
6561
|
+
${t} <span class="truncate">${u.exportName}</span>`,i+=`
|
|
6562
|
+
${t} </a>`,i+=`
|
|
6563
|
+
${t} </li>`;}i+=`
|
|
6564
|
+
${t} </ul>`,i+=`
|
|
6565
|
+
${t} </details>`,i+=`
|
|
6566
|
+
${t}</li>`;}else for(let s of e.handlers){let u=s.kind==="query"?"solar:reorder-linear":"solar:bolt-linear";i+=`
|
|
6567
|
+
${t}<li data-name="${s.exportName}">`,i+=`
|
|
6568
|
+
${t} <a href="/admin/functions${s.routePath}" hx-get="/admin/functions${s.routePath}" hx-target="#main-content" hx-push-url="true" hx-swap="outerHTML" class="sidebar-link flex items-center gap-2 px-3 py-2 text-sm rounded-lg w-full">`,i+=`
|
|
6569
|
+
${t} <iconify-icon icon="${u}" width="16" height="16" class="opacity-50 shrink-0"></iconify-icon>`,i+=`
|
|
6570
|
+
${t} <span class="truncate">${s.exportName}</span>`,i+=`
|
|
6571
|
+
${t} </a>`,i+=`
|
|
6572
|
+
${t}</li>`;}return i}function Nt(e){let n=e.filter(s=>s.kind==="query"),t=e.filter(s=>s.kind==="mutation"),r=Y(n),a=Y(t),o=r.map(s=>ee(s,0)).join(""),i=a.map(s=>ee(s,0)).join("");return `
|
|
6563
6573
|
<div id="pane-functions" class="flex flex-col h-full hidden">
|
|
6564
6574
|
<div class="px-3 pt-5 pb-3">
|
|
6565
6575
|
<p class="text-[10px] font-semibold uppercase tracking-widest opacity-35 mb-3 px-1">Functions</p>
|
|
@@ -6575,15 +6585,15 @@ import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@clou
|
|
|
6575
6585
|
</div>
|
|
6576
6586
|
</div>
|
|
6577
6587
|
<nav class="flex-1 overflow-y-auto px-2 pb-4">
|
|
6578
|
-
${
|
|
6579
|
-
<ul class="flex flex-col gap-0.5">${
|
|
6580
|
-
${
|
|
6581
|
-
<ul class="flex flex-col gap-0.5">${
|
|
6588
|
+
${n.length>0?`<p class="text-[9px] font-bold uppercase tracking-wider opacity-25 mt-4 mb-1 px-2">Queries</p>
|
|
6589
|
+
<ul class="flex flex-col gap-0.5">${o}</ul>`:""}
|
|
6590
|
+
${t.length>0?`<p class="text-[9px] font-bold uppercase tracking-wider opacity-25 mt-4 mb-1 px-2">Mutations</p>
|
|
6591
|
+
<ul class="flex flex-col gap-0.5">${i}</ul>`:""}
|
|
6582
6592
|
</nav>
|
|
6583
6593
|
</div>
|
|
6584
|
-
`}function
|
|
6594
|
+
`}function $t(e){return e.map(n=>`
|
|
6585
6595
|
<a
|
|
6586
|
-
href="/admin/table/${
|
|
6596
|
+
href="/admin/table/${n.exportName}"
|
|
6587
6597
|
class="card bg-base-100 border border-base-200 hover:border-primary/30 hover:shadow-md transition-all cursor-pointer group"
|
|
6588
6598
|
>
|
|
6589
6599
|
<div class="card-body p-5">
|
|
@@ -6592,42 +6602,42 @@ import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@clou
|
|
|
6592
6602
|
<iconify-icon icon="mdi:table" width="20" height="20" class="text-primary"></iconify-icon>
|
|
6593
6603
|
</div>
|
|
6594
6604
|
<div>
|
|
6595
|
-
<h2 class="font-semibold text-sm capitalize group-hover:text-primary transition-colors">${
|
|
6605
|
+
<h2 class="font-semibold text-sm capitalize group-hover:text-primary transition-colors">${n.tableName}</h2>
|
|
6596
6606
|
<p class="text-xs opacity-40 mt-0.5">Manage records</p>
|
|
6597
6607
|
</div>
|
|
6598
6608
|
</div>
|
|
6599
6609
|
</div>
|
|
6600
6610
|
</a>
|
|
6601
|
-
`.replace(/\n/g,"\\n")).join("")}function
|
|
6602
|
-
try { searchConditions.push(like(tableSchema.${
|
|
6603
|
-
`).join("")}function
|
|
6611
|
+
`.replace(/\n/g,"\\n")).join("")}function Ct(e){return e.columns.filter(n=>n.type==="string").map(n=>`
|
|
6612
|
+
try { searchConditions.push(like(tableSchema.${n.name}, \`%\${search}%\`)); } catch (e) {}
|
|
6613
|
+
`).join("")}function kr(e){switch(e){case "number":return "mdi:pound";case "boolean":return "mdi:toggle-switch-outline";case "date":return "mdi:calendar";default:return "mdi:format-text"}}function qt(e,n){return n.map(t=>{let r=e.columns.find(o=>o.name===t),a=r?kr(r.type):"mdi:format-text";return `
|
|
6604
6614
|
<th>
|
|
6605
6615
|
<a href="#"
|
|
6606
|
-
hx-get="/admin/table/${e.exportName}?page=\${page}&search=\${search}&sort=${
|
|
6616
|
+
hx-get="/admin/table/${e.exportName}?page=\${page}&search=\${search}&sort=${t}&order=\${sort === '${t}' && order === 'asc' ? 'desc' : 'asc'}"
|
|
6607
6617
|
hx-target="#main-content"
|
|
6608
6618
|
hx-push-url="true"
|
|
6609
6619
|
class="hover:text-primary flex items-center gap-1.5 transition-colors whitespace-nowrap">
|
|
6610
6620
|
<iconify-icon icon="${a}" width="14" height="14" class="opacity-40"></iconify-icon>
|
|
6611
|
-
${
|
|
6612
|
-
<span class="text-[10px] opacity-30">\${sort === '${
|
|
6621
|
+
${t}
|
|
6622
|
+
<span class="text-[10px] opacity-30">\${sort === '${t}' ? (order === 'asc' ? '\u25B2' : '\u25BC') : ''}</span>
|
|
6613
6623
|
</a>
|
|
6614
6624
|
</th>
|
|
6615
|
-
`}).join("")}function
|
|
6625
|
+
`}).join("")}function Ft(e,n){return e.map(t=>n&&t===n?`<td><button type="button" class="truncate max-w-[200px] text-sm font-mono text-xs opacity-70 hover:opacity-100 cursor-copy text-left" title="Click to copy: \${String((row as any).${t} ?? '')}" data-copy-value="\${String((row as any).${t} ?? '')}" onclick="navigator.clipboard?.writeText(this.dataset.copyValue || '')">\${String((row as any).${t} ?? '')}</button></td>`:`<td><div class="truncate max-w-[200px] text-sm" title="\${String((row as any).${t} ?? '')}">\${String((row as any).${t} ?? '')}</div></td>`).join("")}function te(e,n,t){let r=e.columns.find(i=>i.name===n);if(!r)return "";let a=r.optional?"":" required",o=r.type==="number"?"number":r.type==="date"?"date":"text";if(r.type==="boolean")return t==="edit"?`
|
|
6616
6626
|
<div class="form-control">
|
|
6617
6627
|
<label class="label cursor-pointer justify-start gap-3">
|
|
6618
|
-
<input type="checkbox" name="${
|
|
6619
|
-
<span class="label-text text-sm">${
|
|
6628
|
+
<input type="checkbox" name="${n}" value="true" class="checkbox checkbox-sm checkbox-primary" \${(row as any).${n} ? 'checked' : ''} />
|
|
6629
|
+
<span class="label-text text-sm">${n}</span>
|
|
6620
6630
|
</label>
|
|
6621
6631
|
</div>
|
|
6622
6632
|
`:`
|
|
6623
6633
|
<div class="form-control">
|
|
6624
6634
|
<label class="label cursor-pointer justify-start gap-3">
|
|
6625
|
-
<input type="checkbox" name="${
|
|
6626
|
-
<span class="label-text text-sm">${
|
|
6635
|
+
<input type="checkbox" name="${n}" value="true" class="checkbox checkbox-sm checkbox-primary" />
|
|
6636
|
+
<span class="label-text text-sm">${n}</span>
|
|
6627
6637
|
</label>
|
|
6628
6638
|
</div>
|
|
6629
|
-
`;if(
|
|
6630
|
-
const value = (row as any).${
|
|
6639
|
+
`;if(t==="edit"){let i=r.type==="date"?`\${(() => {
|
|
6640
|
+
const value = (row as any).${n};
|
|
6631
6641
|
if (value == null || value === '') return '';
|
|
6632
6642
|
|
|
6633
6643
|
const date =
|
|
@@ -6640,62 +6650,62 @@ import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@clou
|
|
|
6640
6650
|
const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
6641
6651
|
const day = String(date.getDate()).padStart(2, '0');
|
|
6642
6652
|
return String(year) + '-' + month + '-' + day;
|
|
6643
|
-
})()}`:`\${String((row as any).${
|
|
6653
|
+
})()}`:`\${String((row as any).${n} ?? '')}`;return `
|
|
6644
6654
|
<div class="form-control">
|
|
6645
|
-
<label class="label"><span class="label-text text-sm font-medium">${
|
|
6646
|
-
<input type="${o}" name="${
|
|
6655
|
+
<label class="label"><span class="label-text text-sm font-medium">${n}</span></label>
|
|
6656
|
+
<input type="${o}" name="${n}" class="input input-bordered w-full text-sm" value="${i}"${a} />
|
|
6647
6657
|
</div>
|
|
6648
6658
|
`}return `
|
|
6649
6659
|
<div class="form-control">
|
|
6650
|
-
<label class="label"><span class="label-text text-sm font-medium">${
|
|
6651
|
-
<input type="${o}" name="${
|
|
6660
|
+
<label class="label"><span class="label-text text-sm font-medium">${n}</span></label>
|
|
6661
|
+
<input type="${o}" name="${n}" class="input input-bordered w-full text-sm"${a} />
|
|
6652
6662
|
</div>
|
|
6653
|
-
`}function
|
|
6654
|
-
if (raw_${
|
|
6655
|
-
return c.text('${
|
|
6663
|
+
`}function ne(e,n){return n.map(t=>{let r=e.columns.find(o=>o.name===t);if(!r)return "";let a=r.optional?"":`
|
|
6664
|
+
if (raw_${t} === '') {
|
|
6665
|
+
return c.text('${t} is required', 400);
|
|
6656
6666
|
}
|
|
6657
6667
|
`;return r.type==="number"?`
|
|
6658
|
-
const raw_${
|
|
6668
|
+
const raw_${t} = getValue(body['${t}']);
|
|
6659
6669
|
${a}
|
|
6660
|
-
if (raw_${
|
|
6661
|
-
const parsed_${
|
|
6662
|
-
if (Number.isNaN(parsed_${
|
|
6663
|
-
return c.text('${
|
|
6670
|
+
if (raw_${t} !== '') {
|
|
6671
|
+
const parsed_${t} = Number(raw_${t});
|
|
6672
|
+
if (Number.isNaN(parsed_${t})) {
|
|
6673
|
+
return c.text('${t} must be a valid number', 400);
|
|
6664
6674
|
}
|
|
6665
|
-
payload.${
|
|
6675
|
+
payload.${t} = parsed_${t};
|
|
6666
6676
|
}
|
|
6667
6677
|
`:r.type==="boolean"?`
|
|
6668
|
-
const raw_${
|
|
6669
|
-
payload.${
|
|
6678
|
+
const raw_${t} = getValue(body['${t}']);
|
|
6679
|
+
payload.${t} = raw_${t} === 'true' || raw_${t} === 'on' || raw_${t} === '1';
|
|
6670
6680
|
`:r.type==="date"?`
|
|
6671
|
-
const raw_${
|
|
6681
|
+
const raw_${t} = getValue(body['${t}']);
|
|
6672
6682
|
${a}
|
|
6673
|
-
if (raw_${
|
|
6674
|
-
if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(raw_${
|
|
6675
|
-
return c.text('${
|
|
6683
|
+
if (raw_${t} !== '') {
|
|
6684
|
+
if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(raw_${t})) {
|
|
6685
|
+
return c.text('${t} must be a valid date (YYYY-MM-DD)', 400);
|
|
6676
6686
|
}
|
|
6677
6687
|
|
|
6678
|
-
const [year_${
|
|
6679
|
-
const parsed_${
|
|
6688
|
+
const [year_${t}, month_${t}, day_${t}] = raw_${t}.split('-').map(Number);
|
|
6689
|
+
const parsed_${t} = new Date(year_${t}, month_${t} - 1, day_${t});
|
|
6680
6690
|
if (
|
|
6681
|
-
Number.isNaN(parsed_${
|
|
6682
|
-
parsed_${
|
|
6683
|
-
parsed_${
|
|
6684
|
-
parsed_${
|
|
6691
|
+
Number.isNaN(parsed_${t}.getTime()) ||
|
|
6692
|
+
parsed_${t}.getFullYear() !== year_${t} ||
|
|
6693
|
+
parsed_${t}.getMonth() !== month_${t} - 1 ||
|
|
6694
|
+
parsed_${t}.getDate() !== day_${t}
|
|
6685
6695
|
) {
|
|
6686
|
-
return c.text('${
|
|
6696
|
+
return c.text('${t} must be a valid date', 400);
|
|
6687
6697
|
}
|
|
6688
6698
|
|
|
6689
|
-
payload.${
|
|
6699
|
+
payload.${t} = parsed_${t};
|
|
6690
6700
|
}
|
|
6691
6701
|
`:`
|
|
6692
|
-
const raw_${
|
|
6702
|
+
const raw_${t} = getValue(body['${t}']);
|
|
6693
6703
|
${a}
|
|
6694
|
-
if (raw_${
|
|
6695
|
-
payload.${
|
|
6704
|
+
if (raw_${t} !== '') {
|
|
6705
|
+
payload.${t} = raw_${t};
|
|
6696
6706
|
}
|
|
6697
6707
|
`}).join(`
|
|
6698
|
-
`)}function
|
|
6708
|
+
`)}function Mt(e){return e.columns.find(n=>n.primaryKey)?.name||e.columns[0]?.name||""}function It(e,n){let t=e.columns.find(r=>r.name===n);return !(!t||t.autoIncrement||t.primaryKey)}function Et(e,n){let t=e.columns.find(r=>r.name===n);return !(!t||t.primaryKey||t.autoIncrement)}function Pt(e,n,t,r){return n?`<td class="text-right">
|
|
6699
6709
|
<div class="drawer drawer-end">
|
|
6700
6710
|
<input id="edit-drawer-${e.exportName}-\${rowIndex}" type="checkbox" class="drawer-toggle" />
|
|
6701
6711
|
<div class="drawer-content">
|
|
@@ -6716,7 +6726,7 @@ import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@clou
|
|
|
6716
6726
|
<button class="btn btn-ghost btn-sm">Cancel</button>
|
|
6717
6727
|
</form>
|
|
6718
6728
|
<form hx-post="/admin/table/${e.exportName}/delete" hx-target="#main-content" hx-swap="outerHTML" class="inline">
|
|
6719
|
-
<input type="hidden" name="${
|
|
6729
|
+
<input type="hidden" name="${t}" value="\${String((row as any).${t} ?? '')}" />
|
|
6720
6730
|
<input type="hidden" name="sort" value="\${sort}" />
|
|
6721
6731
|
<input type="hidden" name="order" value="\${order}" />
|
|
6722
6732
|
<input type="hidden" name="search" value="\${search}" />
|
|
@@ -6737,7 +6747,7 @@ import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@clou
|
|
|
6737
6747
|
</label>
|
|
6738
6748
|
</div>
|
|
6739
6749
|
<form hx-post="/admin/table/${e.exportName}/edit" hx-target="#main-content" hx-swap="outerHTML" class="flex flex-col gap-4">
|
|
6740
|
-
<input type="hidden" name="${
|
|
6750
|
+
<input type="hidden" name="${t}" value="\${String((row as any).${t} ?? '')}" />
|
|
6741
6751
|
<input type="hidden" name="sort" value="\${sort}" />
|
|
6742
6752
|
<input type="hidden" name="order" value="\${order}" />
|
|
6743
6753
|
<input type="hidden" name="search" value="\${search}" />
|
|
@@ -6770,18 +6780,18 @@ import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@clou
|
|
|
6770
6780
|
\` : html\`<button class="join-item btn btn-sm btn-ghost btn-disabled"><iconify-icon icon="mdi:chevron-right" width="16" height="16"></iconify-icon></button>\`}
|
|
6771
6781
|
</div>
|
|
6772
6782
|
\` : ''}
|
|
6773
|
-
</div>`}function W(e,
|
|
6783
|
+
</div>`}function W(e,n="Search term or filter..."){return `
|
|
6774
6784
|
<div class="form-control w-full md:w-auto relative">
|
|
6775
6785
|
<iconify-icon icon="mdi:magnify" width="18" height="18" class="absolute left-3 top-1/2 -translate-y-1/2 opacity-40"></iconify-icon>
|
|
6776
6786
|
<input type="text"
|
|
6777
6787
|
name="search"
|
|
6778
|
-
placeholder="${
|
|
6788
|
+
placeholder="${n}"
|
|
6779
6789
|
value="\${search}"
|
|
6780
6790
|
hx-get="${e}?sort=\${sort}&order=\${order}"
|
|
6781
6791
|
hx-trigger="keyup changed delay:500ms, search"
|
|
6782
6792
|
hx-target="#main-content"
|
|
6783
6793
|
class="input input-sm md:input-md input-bordered pl-9 w-full md:w-72 bg-base-200/50 border-base-200 focus:bg-base-100 focus:border-primary transition-all text-sm" />
|
|
6784
|
-
</div>`}function
|
|
6794
|
+
</div>`}function Ot(e,n,t,r,a,o,i,s,u,l){let c=B(`/admin/table/${e.exportName}`),p=W(`/admin/table/${e.exportName}`,"Search term or filter..."),d=r?`<th class="w-10"><input id="select-all-${e.exportName}" type="checkbox" class="checkbox checkbox-xs" /></th>`:'<th class="w-10"><input type="checkbox" class="checkbox checkbox-xs opacity-30" disabled /></th>',y=r?`<td><input type="checkbox" class="checkbox checkbox-xs row-select-checkbox" value="\${String((row as any).${t} ?? '')}" /></td>`:'<td><input type="checkbox" class="checkbox checkbox-xs opacity-30" disabled /></td>',v=r?`
|
|
6785
6795
|
<div id="bulk-delete-bar-${e.exportName}" class="fixed bottom-4 left-1/2 -translate-x-1/2 z-40 hidden">
|
|
6786
6796
|
<div class="bg-base-100 border border-base-200 rounded-xl shadow-lg px-3 py-2 flex items-center gap-3">
|
|
6787
6797
|
<div class="text-xs text-base-content/70">
|
|
@@ -6905,7 +6915,7 @@ import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@clou
|
|
|
6905
6915
|
const page = parseInt(c.req.query('page') || '1');
|
|
6906
6916
|
const limit = 20;
|
|
6907
6917
|
const offset = (page - 1) * limit;
|
|
6908
|
-
const sort = c.req.query('sort') || '${
|
|
6918
|
+
const sort = c.req.query('sort') || '${n}';
|
|
6909
6919
|
const order = c.req.query('order') || 'desc';
|
|
6910
6920
|
const search = c.req.query('search') || '';
|
|
6911
6921
|
|
|
@@ -6951,7 +6961,7 @@ import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@clou
|
|
|
6951
6961
|
<tr class="hover:bg-base-200/30 transition-colors">
|
|
6952
6962
|
${y}
|
|
6953
6963
|
${s}
|
|
6954
|
-
${
|
|
6964
|
+
${u}
|
|
6955
6965
|
</tr>
|
|
6956
6966
|
\`)}
|
|
6957
6967
|
\${data.length === 0 ? html\`
|
|
@@ -6971,7 +6981,7 @@ import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@clou
|
|
|
6971
6981
|
</tbody>
|
|
6972
6982
|
</table>
|
|
6973
6983
|
</div>
|
|
6974
|
-
${
|
|
6984
|
+
${c}
|
|
6975
6985
|
</div>
|
|
6976
6986
|
\`;
|
|
6977
6987
|
|
|
@@ -7033,11 +7043,11 @@ import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@clou
|
|
|
7033
7043
|
title: "${e.tableName} - Admin Dashboard",
|
|
7034
7044
|
children: content
|
|
7035
7045
|
}));
|
|
7036
|
-
});`}function
|
|
7046
|
+
});`}function jt(e,n,t,r,a,o,i,s){let u=r==="number"?`
|
|
7037
7047
|
const parsedId = Number(rawId);
|
|
7038
|
-
if (Number.isNaN(parsedId)) return c.text('${
|
|
7048
|
+
if (Number.isNaN(parsedId)) return c.text('${t} must be a valid number', 400);
|
|
7039
7049
|
idValue = parsedId;
|
|
7040
|
-
`:"",
|
|
7050
|
+
`:"",c=a?`
|
|
7041
7051
|
adminApp.post('/table/${e}/edit', async (c) => {
|
|
7042
7052
|
const db = drizzle(c.env[options.databaseBinding], { schema });
|
|
7043
7053
|
const tableSchema = (schema as any).${e};
|
|
@@ -7045,27 +7055,27 @@ import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@clou
|
|
|
7045
7055
|
|
|
7046
7056
|
const body = await c.req.parseBody();
|
|
7047
7057
|
const getValue = (value: unknown) => (typeof value === 'string' ? value : '');
|
|
7048
|
-
const rawId = getValue(body['${
|
|
7049
|
-
if (rawId === '') return c.text('${
|
|
7058
|
+
const rawId = getValue(body['${t}']);
|
|
7059
|
+
if (rawId === '') return c.text('${t} is required', 400);
|
|
7050
7060
|
|
|
7051
7061
|
const payload: Record<string, unknown> = {};
|
|
7052
7062
|
|
|
7053
7063
|
${s}
|
|
7054
7064
|
|
|
7055
7065
|
let idValue: unknown = rawId;
|
|
7056
|
-
${
|
|
7066
|
+
${u}
|
|
7057
7067
|
|
|
7058
7068
|
if (Object.keys(payload).length > 0) {
|
|
7059
7069
|
await db
|
|
7060
7070
|
.update(tableSchema)
|
|
7061
7071
|
.set(payload as any)
|
|
7062
|
-
.where(eq(tableSchema.${
|
|
7072
|
+
.where(eq(tableSchema.${t}, idValue as any))
|
|
7063
7073
|
.execute();
|
|
7064
7074
|
}
|
|
7065
7075
|
|
|
7066
7076
|
const query = new URLSearchParams({
|
|
7067
7077
|
page: getValue(body.page) || '1',
|
|
7068
|
-
sort: getValue(body.sort) || '${
|
|
7078
|
+
sort: getValue(body.sort) || '${n}',
|
|
7069
7079
|
order: getValue(body.order) || 'desc',
|
|
7070
7080
|
search: getValue(body.search) || '',
|
|
7071
7081
|
});
|
|
@@ -7079,20 +7089,20 @@ import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@clou
|
|
|
7079
7089
|
|
|
7080
7090
|
const body = await c.req.parseBody();
|
|
7081
7091
|
const getValue = (value: unknown) => (typeof value === 'string' ? value : '');
|
|
7082
|
-
const rawId = getValue(body['${
|
|
7083
|
-
if (rawId === '') return c.text('${
|
|
7092
|
+
const rawId = getValue(body['${t}']);
|
|
7093
|
+
if (rawId === '') return c.text('${t} is required', 400);
|
|
7084
7094
|
|
|
7085
7095
|
let idValue: unknown = rawId;
|
|
7086
|
-
${
|
|
7096
|
+
${u}
|
|
7087
7097
|
|
|
7088
7098
|
await db
|
|
7089
7099
|
.delete(tableSchema)
|
|
7090
|
-
.where(eq(tableSchema.${
|
|
7100
|
+
.where(eq(tableSchema.${t}, idValue as any))
|
|
7091
7101
|
.execute();
|
|
7092
7102
|
|
|
7093
7103
|
const query = new URLSearchParams({
|
|
7094
7104
|
page: getValue(body.page) || '1',
|
|
7095
|
-
sort: getValue(body.sort) || '${
|
|
7105
|
+
sort: getValue(body.sort) || '${n}',
|
|
7096
7106
|
order: getValue(body.order) || 'desc',
|
|
7097
7107
|
search: getValue(body.search) || '',
|
|
7098
7108
|
});
|
|
@@ -7132,13 +7142,13 @@ import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@clou
|
|
|
7132
7142
|
|
|
7133
7143
|
await db
|
|
7134
7144
|
.delete(tableSchema)
|
|
7135
|
-
.where(inArray(tableSchema.${
|
|
7145
|
+
.where(inArray(tableSchema.${t}, parsedIds as any))
|
|
7136
7146
|
.execute();
|
|
7137
7147
|
}
|
|
7138
7148
|
|
|
7139
7149
|
const query = new URLSearchParams({
|
|
7140
7150
|
page: getValue(body.page) || '1',
|
|
7141
|
-
sort: getValue(body.sort) || '${
|
|
7151
|
+
sort: getValue(body.sort) || '${n}',
|
|
7142
7152
|
order: getValue(body.order) || 'desc',
|
|
7143
7153
|
search: getValue(body.search) || '',
|
|
7144
7154
|
});
|
|
@@ -7159,22 +7169,22 @@ import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@clou
|
|
|
7159
7169
|
|
|
7160
7170
|
const query = new URLSearchParams({
|
|
7161
7171
|
page: getValue(body.page) || '1',
|
|
7162
|
-
sort: getValue(body.sort) || '${
|
|
7172
|
+
sort: getValue(body.sort) || '${n}',
|
|
7163
7173
|
order: getValue(body.order) || 'desc',
|
|
7164
7174
|
search: getValue(body.search) || '',
|
|
7165
7175
|
});
|
|
7166
7176
|
return c.redirect('/admin/table/${e}?' + query.toString());
|
|
7167
7177
|
});
|
|
7168
|
-
${
|
|
7169
|
-
`}function
|
|
7170
|
-
`+
|
|
7178
|
+
${c}
|
|
7179
|
+
`}function re(e){let n=Mt(e),t=!!n,r=e.columns.map(w=>w.name),a=r.filter(w=>It(e,w)),o=r.filter(w=>Et(e,w)),i=Ct(e),s=qt(e,r),u=Ft(r,n),l=a.map(w=>te(e,w,"create")).join(""),c=o.map(w=>te(e,w,"edit")).join(""),p=ne(e,a),d=ne(e,o),y=t?n:r[0]||"id",v=e.columns.find(w=>w.name===n)?.type,A=Pt(e,t,n,c);return Ot(e,y,n,t,r,i,s,u,A,l)+`
|
|
7180
|
+
`+jt(e.exportName,y,n,v,t,i,p,d)}function Dt(){return `
|
|
7171
7181
|
const buildUsersRedirect = (params: { page?: string; sort?: string; order?: string; search?: string }) => {
|
|
7172
7182
|
const page = params.page && params.page.trim() ? params.page : '1';
|
|
7173
7183
|
const sort = params.sort && params.sort.trim() ? params.sort : 'createdAt';
|
|
7174
7184
|
const order = params.order === 'asc' ? 'asc' : 'desc';
|
|
7175
7185
|
const search = params.search ? params.search : '';
|
|
7176
7186
|
return '/admin/users?page=' + encodeURIComponent(page) + '&sort=' + encodeURIComponent(sort) + '&order=' + encodeURIComponent(order) + '&search=' + encodeURIComponent(search);
|
|
7177
|
-
};`}function
|
|
7187
|
+
};`}function Vt(){return `
|
|
7178
7188
|
\${(row as any).id === currentUserId ? '' : html\`
|
|
7179
7189
|
<input type="checkbox" id="ban-user-modal-\${String((row as any).id)}" class="modal-toggle" />
|
|
7180
7190
|
<div class="modal">
|
|
@@ -7195,7 +7205,7 @@ ${u}
|
|
|
7195
7205
|
</div>
|
|
7196
7206
|
<label class="modal-backdrop" for="ban-user-modal-\${String((row as any).id)}">Close</label>
|
|
7197
7207
|
</div>
|
|
7198
|
-
\`}`}function
|
|
7208
|
+
\`}`}function Bt(){return `
|
|
7199
7209
|
\${(row as any).id === currentUserId ? '' : html\`
|
|
7200
7210
|
<input type="checkbox" id="delete-user-modal-\${String((row as any).id)}" class="modal-toggle" />
|
|
7201
7211
|
<div class="modal">
|
|
@@ -7216,8 +7226,8 @@ ${u}
|
|
|
7216
7226
|
</div>
|
|
7217
7227
|
<label class="modal-backdrop" for="delete-user-modal-\${String((row as any).id)}">Close</label>
|
|
7218
7228
|
</div>
|
|
7219
|
-
\`}`}var
|
|
7220
|
-
`),
|
|
7229
|
+
\`}`}var Sr=["id","name","email","role","createdAt","banned"],Ar={id:"mdi:pound",name:"mdi:format-text",email:"mdi:at",role:"mdi:shield-account-outline",createdAt:"mdi:calendar",banned:"mdi:toggle-switch-outline"};function Nr(e){let n=Ar[e]||"mdi:format-text";return `<th><a href="#" hx-get="/admin/users?page=\${page}&search=\${search}&sort=${e}&order=\${sort === '${e}' && order === 'asc' ? 'desc' : 'asc'}" hx-target="#main-content" hx-push-url="true" class="hover:text-primary flex items-center gap-1.5 transition-colors whitespace-nowrap"><iconify-icon icon="${n}" width="14" height="14" class="opacity-40"></iconify-icon>${e} <span class="text-[10px] opacity-30">\${sort === '${e}' ? (order === 'asc' ? '\u25B2' : '\u25BC') : ''}</span></a></th>`}function Wt(){let e=Sr.map(Nr).join(`
|
|
7230
|
+
`),n=B("/admin/users");return `
|
|
7221
7231
|
const tableHtml = html\`
|
|
7222
7232
|
<div class="bg-base-100 rounded-xl border border-base-200 overflow-hidden">
|
|
7223
7233
|
<div class="overflow-x-auto">
|
|
@@ -7285,8 +7295,8 @@ ${u}
|
|
|
7285
7295
|
</div>
|
|
7286
7296
|
</div>
|
|
7287
7297
|
</div>
|
|
7288
|
-
${
|
|
7289
|
-
${
|
|
7298
|
+
${Vt()}
|
|
7299
|
+
${Bt()}
|
|
7290
7300
|
</td>
|
|
7291
7301
|
</tr>
|
|
7292
7302
|
\`)}
|
|
@@ -7299,10 +7309,10 @@ ${Dt()}
|
|
|
7299
7309
|
</tbody>
|
|
7300
7310
|
</table>
|
|
7301
7311
|
</div>
|
|
7302
|
-
${
|
|
7312
|
+
${n}
|
|
7303
7313
|
</div>
|
|
7304
7314
|
\`;
|
|
7305
|
-
`}function
|
|
7315
|
+
`}function Ht(){return `
|
|
7306
7316
|
const content = html\`
|
|
7307
7317
|
<div id="main-content">
|
|
7308
7318
|
<div class="flex flex-col md:flex-row justify-between items-start md:items-center mb-5 gap-3">
|
|
@@ -7318,7 +7328,7 @@ ${Dt()}
|
|
|
7318
7328
|
</div>
|
|
7319
7329
|
\${tableHtml}
|
|
7320
7330
|
</div>
|
|
7321
|
-
\`;`}function
|
|
7331
|
+
\`;`}function Lt(){let e=Wt(),n=Ht();return `
|
|
7322
7332
|
adminApp.get('/users', async (c) => {
|
|
7323
7333
|
const db = drizzle(c.env[options.databaseBinding]);
|
|
7324
7334
|
const auth = createAuth({ DATABASE: c.env[options.databaseBinding] } as any, c.req.raw.cf as any);
|
|
@@ -7364,7 +7374,7 @@ ${Dt()}
|
|
|
7364
7374
|
|
|
7365
7375
|
${e}
|
|
7366
7376
|
|
|
7367
|
-
${
|
|
7377
|
+
${n}
|
|
7368
7378
|
|
|
7369
7379
|
if (c.req.header('hx-request')) {
|
|
7370
7380
|
return c.html(content);
|
|
@@ -7374,7 +7384,7 @@ ${Dt()}
|
|
|
7374
7384
|
title: "users - Admin Dashboard",
|
|
7375
7385
|
children: content,
|
|
7376
7386
|
}));
|
|
7377
|
-
});`}function
|
|
7387
|
+
});`}function zt(){return `
|
|
7378
7388
|
adminApp.post('/users/edit', async (c) => {
|
|
7379
7389
|
const session = await requireAdminSession(c);
|
|
7380
7390
|
if (!session) {
|
|
@@ -7517,8 +7527,8 @@ ${Dt()}
|
|
|
7517
7527
|
const resolvedPage = String(Math.min(nextPageCandidate, totalPages));
|
|
7518
7528
|
|
|
7519
7529
|
return c.redirect(buildUsersRedirect({ page: resolvedPage, search, sort, order }));
|
|
7520
|
-
});`}function
|
|
7521
|
-
${
|
|
7530
|
+
});`}function ae(){return `
|
|
7531
|
+
${Dt()}
|
|
7522
7532
|
|
|
7523
7533
|
const requireAdminSession = async (c: any) => {
|
|
7524
7534
|
const auth = createAuth({ DATABASE: c.env[options.databaseBinding] } as any, c.req.raw.cf as any);
|
|
@@ -7529,12 +7539,12 @@ ${Dt()}
|
|
|
7529
7539
|
return session;
|
|
7530
7540
|
};
|
|
7531
7541
|
|
|
7532
|
-
${
|
|
7542
|
+
${Lt()}
|
|
7533
7543
|
|
|
7534
|
-
${
|
|
7535
|
-
`}function
|
|
7544
|
+
${zt()}
|
|
7545
|
+
`}function Ut(e){return `${e.tables.map(n=>re(n)).join(`
|
|
7536
7546
|
`)}
|
|
7537
|
-
${
|
|
7547
|
+
${ae()}`}function Qt(e){return `
|
|
7538
7548
|
<div class="flex items-center justify-between">
|
|
7539
7549
|
<div class="flex items-center gap-3">
|
|
7540
7550
|
<div class="w-10 h-10 rounded-xl bg-primary/10 flex items-center justify-center">
|
|
@@ -7549,38 +7559,38 @@ ${ne()}`}function zt(e){return `
|
|
|
7549
7559
|
<span class="badge badge-sm badge-ghost font-mono opacity-50 px-2 py-3">/api${e.routePath}</span>
|
|
7550
7560
|
</div>
|
|
7551
7561
|
</div>
|
|
7552
|
-
`}function
|
|
7562
|
+
`}function $r(e){return e==="boolean"?"checkbox":e==="number"?"number":"text"}function Cr(e){let n=e.args??[];return n.length===0?`
|
|
7553
7563
|
<div class="text-[11px] opacity-30 italic py-2">No arguments defined for this ${e.kind}.</div>
|
|
7554
|
-
`:
|
|
7564
|
+
`:n.map(t=>{let r=$r(t.type),a=r==="checkbox",o=`${t.name}${t.optional?"":" *"}`,i=t.type!=="unknown"?`<span class="badge badge-xs badge-ghost font-mono opacity-40 ml-1">${t.type}</span>`:"";return a?`
|
|
7555
7565
|
<div class="flex items-center gap-3 py-1">
|
|
7556
7566
|
<input
|
|
7557
7567
|
type="checkbox"
|
|
7558
|
-
data-arg-key="${
|
|
7568
|
+
data-arg-key="${t.name}"
|
|
7559
7569
|
data-arg-type="boolean"
|
|
7560
7570
|
class="checkbox checkbox-sm checkbox-primary"
|
|
7561
|
-
${
|
|
7571
|
+
${t.defaultValue==="true"?"checked":""}
|
|
7562
7572
|
/>
|
|
7563
|
-
<span class="text-sm font-mono opacity-70">${
|
|
7564
|
-
${
|
|
7573
|
+
<span class="text-sm font-mono opacity-70">${t.name}${i}</span>
|
|
7574
|
+
${t.optional?'<span class="text-[10px] opacity-30 italic ml-auto">optional</span>':""}
|
|
7565
7575
|
</div>
|
|
7566
7576
|
`:`
|
|
7567
7577
|
<div class="form-control">
|
|
7568
7578
|
<label class="label py-0.5">
|
|
7569
7579
|
<span class="label-text text-[11px] font-mono font-semibold">${o}${i}</span>
|
|
7570
|
-
${
|
|
7580
|
+
${t.optional?'<span class="label-text-alt text-[10px] opacity-30 italic">optional</span>':""}
|
|
7571
7581
|
</label>
|
|
7572
7582
|
<input
|
|
7573
7583
|
type="${r}"
|
|
7574
|
-
placeholder="${
|
|
7575
|
-
data-arg-key="${
|
|
7576
|
-
data-arg-type="${
|
|
7577
|
-
value="${
|
|
7584
|
+
placeholder="${t.defaultValue??""}"
|
|
7585
|
+
data-arg-key="${t.name}"
|
|
7586
|
+
data-arg-type="${t.type}"
|
|
7587
|
+
value="${t.defaultValue??""}"
|
|
7578
7588
|
class="input input-sm input-bordered font-mono w-full bg-base-200/30 focus:bg-base-100 focus:border-primary transition-all rounded-xl border-base-200"
|
|
7579
|
-
${
|
|
7589
|
+
${t.optional?"":"required"}
|
|
7580
7590
|
/>
|
|
7581
7591
|
</div>
|
|
7582
7592
|
`}).join(`
|
|
7583
|
-
`)}function
|
|
7593
|
+
`)}function qr(e){return `
|
|
7584
7594
|
<div class="space-y-4">
|
|
7585
7595
|
<div class="flex items-center justify-between">
|
|
7586
7596
|
<div class="flex flex-col">
|
|
@@ -7593,11 +7603,11 @@ ${ne()}`}function zt(e){return `
|
|
|
7593
7603
|
</label>
|
|
7594
7604
|
</div>
|
|
7595
7605
|
<div id="args-rows" class="flex flex-col gap-3">
|
|
7596
|
-
${
|
|
7606
|
+
${Cr(e)}
|
|
7597
7607
|
</div>
|
|
7598
7608
|
<p class="text-[11px] opacity-30 mt-2 italic">Values are sent as ${e.kind==="query"?"query string params":"JSON request body"}.</p>
|
|
7599
7609
|
</div>
|
|
7600
|
-
`}function
|
|
7610
|
+
`}function Fr(){return `
|
|
7601
7611
|
<div class="space-y-4">
|
|
7602
7612
|
<label class="text-[11px] font-bold uppercase tracking-wider opacity-40 block">Bearer Token <span class="font-normal normal-case">(optional)</span></label>
|
|
7603
7613
|
<div class="relative group">
|
|
@@ -7614,7 +7624,7 @@ ${ne()}`}function zt(e){return `
|
|
|
7614
7624
|
</div>
|
|
7615
7625
|
<p class="text-[10px] opacity-30 italic">Token will be included in the Authorization header.</p>
|
|
7616
7626
|
</div>
|
|
7617
|
-
`}function
|
|
7627
|
+
`}function Mr(){return `
|
|
7618
7628
|
<div class="space-y-4">
|
|
7619
7629
|
<div class="flex items-center justify-between">
|
|
7620
7630
|
<span class="text-[11px] font-bold uppercase tracking-wider opacity-40">Custom Headers</span>
|
|
@@ -7628,7 +7638,7 @@ ${ne()}`}function zt(e){return `
|
|
|
7628
7638
|
</div>
|
|
7629
7639
|
<p id="headers-error" class="text-[11px] text-error mt-1.5 hidden"></p>
|
|
7630
7640
|
</div>
|
|
7631
|
-
`}function
|
|
7641
|
+
`}function _t(e){return `
|
|
7632
7642
|
<div class="card bg-base-100 border border-base-200 shadow-sm overflow-hidden flex flex-col h-full">
|
|
7633
7643
|
<div class="px-5 py-3 border-b border-base-200 bg-base-200/20 flex items-center justify-between flex-none">
|
|
7634
7644
|
<h3 class="text-xs font-bold uppercase tracking-widest opacity-40">Request</h3>
|
|
@@ -7649,13 +7659,13 @@ ${ne()}`}function zt(e){return `
|
|
|
7649
7659
|
<!-- Tab Content -->
|
|
7650
7660
|
<div class="flex-1 overflow-y-auto">
|
|
7651
7661
|
<div id="request-tab-args" class="p-5">
|
|
7652
|
-
${
|
|
7662
|
+
${qr(e)}
|
|
7653
7663
|
</div>
|
|
7654
7664
|
<div id="request-tab-auth" class="p-5 hidden">
|
|
7655
|
-
${
|
|
7665
|
+
${Fr()}
|
|
7656
7666
|
</div>
|
|
7657
7667
|
<div id="request-tab-headers" class="p-5 hidden">
|
|
7658
|
-
${
|
|
7668
|
+
${Mr()}
|
|
7659
7669
|
</div>
|
|
7660
7670
|
</div>
|
|
7661
7671
|
|
|
@@ -7673,7 +7683,7 @@ ${ne()}`}function zt(e){return `
|
|
|
7673
7683
|
</form>
|
|
7674
7684
|
</div>
|
|
7675
7685
|
</div>
|
|
7676
|
-
`}function
|
|
7686
|
+
`}function Kt(){return `
|
|
7677
7687
|
<div class="card bg-base-100 border border-base-200 shadow-sm overflow-hidden flex flex-col">
|
|
7678
7688
|
<!-- Panel Header -->
|
|
7679
7689
|
<div class="px-5 py-3 border-b border-base-200 bg-base-200/20 flex items-center justify-between">
|
|
@@ -7755,7 +7765,7 @@ ${ne()}`}function zt(e){return `
|
|
|
7755
7765
|
|
|
7756
7766
|
</div>
|
|
7757
7767
|
</div>
|
|
7758
|
-
`}function
|
|
7768
|
+
`}function Jt(e){let n=e.kind==="query",t=e.routePath,r=e.handlerName??e.routePath;return `
|
|
7759
7769
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/atom-one-dark.min.css">
|
|
7760
7770
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
|
|
7761
7771
|
|
|
@@ -7981,9 +7991,9 @@ ${ne()}`}function zt(e){return `
|
|
|
7981
7991
|
if (indicator) indicator.classList.remove('opacity-0');
|
|
7982
7992
|
showBodyLoading();
|
|
7983
7993
|
|
|
7984
|
-
var isQuery = ${
|
|
7994
|
+
var isQuery = ${n};
|
|
7985
7995
|
var method = isQuery ? 'GET' : 'POST';
|
|
7986
|
-
var pathWithQuery = '${
|
|
7996
|
+
var pathWithQuery = '${t}';
|
|
7987
7997
|
|
|
7988
7998
|
if (isQuery && Object.keys(args).length > 0) {
|
|
7989
7999
|
var params = new URLSearchParams();
|
|
@@ -8053,7 +8063,7 @@ ${ne()}`}function zt(e){return `
|
|
|
8053
8063
|
var _rtToken = null;
|
|
8054
8064
|
var _rtEnabled = false;
|
|
8055
8065
|
var _rtEventCount = 0;
|
|
8056
|
-
var _isRealtimeSupported = ${
|
|
8066
|
+
var _isRealtimeSupported = ${n};
|
|
8057
8067
|
var _realtimeQueryName = '${r}';
|
|
8058
8068
|
var _rtPingInterval = null;
|
|
8059
8069
|
|
|
@@ -8297,21 +8307,21 @@ ${ne()}`}function zt(e){return `
|
|
|
8297
8307
|
_rtEnabled = false;
|
|
8298
8308
|
});
|
|
8299
8309
|
</script>
|
|
8300
|
-
`}function
|
|
8310
|
+
`}function Gt(e){return `
|
|
8301
8311
|
const content = html\`
|
|
8302
8312
|
<div class="flex flex-col gap-6 max-w-5xl mx-auto" id="main-content">
|
|
8303
|
-
${
|
|
8313
|
+
${Qt(e)}
|
|
8304
8314
|
|
|
8305
8315
|
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
|
8306
8316
|
<!-- Request Panel -->
|
|
8307
|
-
${
|
|
8317
|
+
${_t(e)}
|
|
8308
8318
|
|
|
8309
8319
|
<!-- Result Panel -->
|
|
8310
|
-
${
|
|
8320
|
+
${Kt()}
|
|
8311
8321
|
</div>
|
|
8312
8322
|
</div>
|
|
8313
8323
|
|
|
8314
|
-
${
|
|
8324
|
+
${Jt(e)}
|
|
8315
8325
|
\`;
|
|
8316
8326
|
|
|
8317
8327
|
if (c.req.header('hx-request')) {
|
|
@@ -8321,11 +8331,11 @@ ${ne()}`}function zt(e){return `
|
|
|
8321
8331
|
return c.html(Layout({
|
|
8322
8332
|
title: "${e.exportName} - Functions",
|
|
8323
8333
|
children: content
|
|
8324
|
-
}));`}function
|
|
8325
|
-
adminApp.get('/functions${
|
|
8326
|
-
${
|
|
8334
|
+
}));`}function Zt(e){return e.map(t=>t.kind!=="query"&&t.kind!=="mutation"?"":`
|
|
8335
|
+
adminApp.get('/functions${t.routePath}', (c) => {
|
|
8336
|
+
${Gt(t)}
|
|
8327
8337
|
});`).join(`
|
|
8328
|
-
`)}function
|
|
8338
|
+
`)}function Xt(){return `
|
|
8329
8339
|
const getStorageBucket = (c: any): R2Bucket | null => {
|
|
8330
8340
|
const r2Binding = (options as any).r2Binding;
|
|
8331
8341
|
if (!r2Binding || !c.env[r2Binding]) return null;
|
|
@@ -8394,7 +8404,7 @@ ${ne()}`}function zt(e){return `
|
|
|
8394
8404
|
const parts = prefix.split('/').filter(Boolean);
|
|
8395
8405
|
return parts.slice(0, -1).join('/') + (parts.length > 1 ? '/' : '');
|
|
8396
8406
|
};
|
|
8397
|
-
`}function
|
|
8407
|
+
`}function Yt(){return `
|
|
8398
8408
|
const buildStorageListingContent = (listed: any, prefix: string) => {
|
|
8399
8409
|
const parts = prefix.split('/').filter(Boolean);
|
|
8400
8410
|
const breadcrumbs: any[] = [];
|
|
@@ -8521,7 +8531,7 @@ ${ne()}`}function zt(e){return `
|
|
|
8521
8531
|
</div>
|
|
8522
8532
|
\`;
|
|
8523
8533
|
};
|
|
8524
|
-
`}function
|
|
8534
|
+
`}function en(){return `
|
|
8525
8535
|
const handleStorageListRoute = async (c: any) => {
|
|
8526
8536
|
const bucket = getStorageBucket(c);
|
|
8527
8537
|
if (!bucket) {
|
|
@@ -8543,7 +8553,7 @@ ${ne()}`}function zt(e){return `
|
|
|
8543
8553
|
|
|
8544
8554
|
adminApp.get('/storage', handleStorageListRoute);
|
|
8545
8555
|
adminApp.get('/storage/*', handleStorageListRoute);
|
|
8546
|
-
`}function
|
|
8556
|
+
`}function tn(){return `
|
|
8547
8557
|
adminApp.post('/storage/upload', async (c) => {
|
|
8548
8558
|
const bucket = getStorageBucket(c);
|
|
8549
8559
|
if (!bucket) return c.text("Storage not configured", 400);
|
|
@@ -8561,7 +8571,7 @@ ${ne()}`}function zt(e){return `
|
|
|
8561
8571
|
|
|
8562
8572
|
return c.redirect(prefixToStoragePath(prefix));
|
|
8563
8573
|
});
|
|
8564
|
-
`}function
|
|
8574
|
+
`}function nn(){return `
|
|
8565
8575
|
adminApp.delete('/storage/delete', async (c) => {
|
|
8566
8576
|
const bucket = getStorageBucket(c);
|
|
8567
8577
|
if (!bucket) return c.text("Storage not configured", 400);
|
|
@@ -8576,7 +8586,7 @@ ${ne()}`}function zt(e){return `
|
|
|
8576
8586
|
c.header('HX-Redirect', prefixToStoragePath(prefix));
|
|
8577
8587
|
return c.html('');
|
|
8578
8588
|
});
|
|
8579
|
-
`}function
|
|
8589
|
+
`}function rn(){return `
|
|
8580
8590
|
adminApp.post('/storage/directory', async (c) => {
|
|
8581
8591
|
const bucket = getStorageBucket(c);
|
|
8582
8592
|
if (!bucket) return c.text("Storage not configured", 400);
|
|
@@ -8602,7 +8612,7 @@ ${ne()}`}function zt(e){return `
|
|
|
8602
8612
|
|
|
8603
8613
|
return c.redirect(prefixToStoragePath(prefix));
|
|
8604
8614
|
});
|
|
8605
|
-
`}function
|
|
8615
|
+
`}function an(){return `
|
|
8606
8616
|
adminApp.get('/storage/download', async (c) => {
|
|
8607
8617
|
const bucket = getStorageBucket(c);
|
|
8608
8618
|
if (!bucket) return c.text("Storage not configured", 400);
|
|
@@ -8622,7 +8632,7 @@ ${ne()}`}function zt(e){return `
|
|
|
8622
8632
|
|
|
8623
8633
|
return new Response(object.body, { headers });
|
|
8624
8634
|
});
|
|
8625
|
-
`}function
|
|
8635
|
+
`}function on(){return `
|
|
8626
8636
|
adminApp.get('/storage/preview', async (c) => {
|
|
8627
8637
|
const bucket = getStorageBucket(c);
|
|
8628
8638
|
if (!bucket) return c.text("Storage not configured", 400);
|
|
@@ -8640,25 +8650,25 @@ ${ne()}`}function zt(e){return `
|
|
|
8640
8650
|
|
|
8641
8651
|
return new Response(object.body, { headers });
|
|
8642
8652
|
});
|
|
8643
|
-
`}function
|
|
8644
|
-
${
|
|
8653
|
+
`}function sn(){return `
|
|
8654
|
+
${an()}
|
|
8645
8655
|
|
|
8646
|
-
${
|
|
8656
|
+
${on()}
|
|
8647
8657
|
|
|
8648
|
-
${
|
|
8658
|
+
${tn()}
|
|
8649
8659
|
|
|
8650
|
-
${
|
|
8660
|
+
${nn()}
|
|
8651
8661
|
|
|
8652
|
-
${
|
|
8662
|
+
${rn()}
|
|
8653
8663
|
|
|
8664
|
+
${en()}
|
|
8665
|
+
`}function ln(){return `
|
|
8654
8666
|
${Xt()}
|
|
8655
|
-
`}function on(){return `
|
|
8656
|
-
${Gt()}
|
|
8657
8667
|
|
|
8658
|
-
${
|
|
8668
|
+
${Yt()}
|
|
8659
8669
|
|
|
8660
|
-
${
|
|
8661
|
-
`}function
|
|
8670
|
+
${sn()}
|
|
8671
|
+
`}function un(e,n){let t=Nt(n);return `
|
|
8662
8672
|
function Layout(props: { children: any; title: string; hideSidebar?: boolean }) {
|
|
8663
8673
|
return html\`<!DOCTYPE html>
|
|
8664
8674
|
<html lang="en" data-theme="light">
|
|
@@ -8761,6 +8771,23 @@ function Layout(props: { children: any; title: string; hideSidebar?: boolean })
|
|
|
8761
8771
|
}
|
|
8762
8772
|
.sidebar-link:hover iconify-icon { opacity: 0.7; }
|
|
8763
8773
|
|
|
8774
|
+
.folder-item { list-style: none; }
|
|
8775
|
+
.folder-item > details > summary { list-style: none; }
|
|
8776
|
+
.folder-item > details > summary::-webkit-details-marker { display: none; }
|
|
8777
|
+
.folder-item > details > summary::before {
|
|
8778
|
+
content: '';
|
|
8779
|
+
display: inline-block;
|
|
8780
|
+
width: 16px;
|
|
8781
|
+
height: 16px;
|
|
8782
|
+
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='currentColor'%3E%3Cpath d='M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6z'/%3E%3C/svg%3E");
|
|
8783
|
+
background-size: contain;
|
|
8784
|
+
transition: transform 0.15s ease;
|
|
8785
|
+
opacity: 0.45;
|
|
8786
|
+
}
|
|
8787
|
+
.folder-item > details[open] > summary::before {
|
|
8788
|
+
transform: rotate(90deg);
|
|
8789
|
+
}
|
|
8790
|
+
|
|
8764
8791
|
.table th {
|
|
8765
8792
|
font-weight: 500;
|
|
8766
8793
|
font-size: 0.78rem;
|
|
@@ -8862,7 +8889,7 @@ function Layout(props: { children: any; title: string; hideSidebar?: boolean })
|
|
|
8862
8889
|
</nav>
|
|
8863
8890
|
</div>
|
|
8864
8891
|
|
|
8865
|
-
${
|
|
8892
|
+
${t}
|
|
8866
8893
|
</div>
|
|
8867
8894
|
</div>
|
|
8868
8895
|
\`) : ""}
|
|
@@ -8940,9 +8967,24 @@ function Layout(props: { children: any; title: string; hideSidebar?: boolean })
|
|
|
8940
8967
|
|
|
8941
8968
|
function filterFunctions(query) {
|
|
8942
8969
|
var q = query.toLowerCase();
|
|
8970
|
+
document.querySelectorAll('#pane-functions details').forEach(function(details) {
|
|
8971
|
+
details.open = true;
|
|
8972
|
+
});
|
|
8943
8973
|
document.querySelectorAll('#pane-functions li').forEach(function(li) {
|
|
8944
8974
|
var name = (li.getAttribute('data-name') || li.textContent).toLowerCase();
|
|
8945
|
-
|
|
8975
|
+
var matches = name.includes(q);
|
|
8976
|
+
li.style.display = matches ? '' : 'none';
|
|
8977
|
+
if (!matches && li.classList.contains('folder-item')) {
|
|
8978
|
+
var childItems = li.querySelectorAll('li');
|
|
8979
|
+
childItems.forEach(function(child) {
|
|
8980
|
+
var childName = (child.getAttribute('data-name') || child.textContent).toLowerCase();
|
|
8981
|
+
if (childName.includes(q)) {
|
|
8982
|
+
li.style.display = '';
|
|
8983
|
+
var parentDetails = li.closest('details');
|
|
8984
|
+
if (parentDetails) parentDetails.open = true;
|
|
8985
|
+
}
|
|
8986
|
+
});
|
|
8987
|
+
}
|
|
8946
8988
|
});
|
|
8947
8989
|
}
|
|
8948
8990
|
|
|
@@ -9033,7 +9075,7 @@ function Layout(props: { children: any; title: string; hideSidebar?: boolean })
|
|
|
9033
9075
|
</body>
|
|
9034
9076
|
</html>\`;
|
|
9035
9077
|
}
|
|
9036
|
-
`}function
|
|
9078
|
+
`}function cn(){return `
|
|
9037
9079
|
// Auth Middleware
|
|
9038
9080
|
adminApp.use('*', async (c, next) => {
|
|
9039
9081
|
const auth = createAuth({ DATABASE: c.env[options.databaseBinding] } as any, c.req.raw.cf as any);
|
|
@@ -9092,7 +9134,7 @@ function Layout(props: { children: any; title: string; hideSidebar?: boolean })
|
|
|
9092
9134
|
}
|
|
9093
9135
|
await next();
|
|
9094
9136
|
});
|
|
9095
|
-
`}function
|
|
9137
|
+
`}function dn(e){return `
|
|
9096
9138
|
adminApp.get('/', (c) => {
|
|
9097
9139
|
return c.html(Layout({
|
|
9098
9140
|
title: "Admin Dashboard",
|
|
@@ -9109,7 +9151,7 @@ function Layout(props: { children: any; title: string; hideSidebar?: boolean })
|
|
|
9109
9151
|
\`
|
|
9110
9152
|
}));
|
|
9111
9153
|
});
|
|
9112
|
-
`}function
|
|
9154
|
+
`}function pn(e,n,t){let r=St(n),a=At(r),o=$t(r),i=Ut(n),s=Zt(t),u=ln(),l=un(a,t),c=cn(),p=dn(o);return `import { Hono } from "hono";
|
|
9113
9155
|
import { html, raw } from "hono/html";
|
|
9114
9156
|
import { drizzle } from "drizzle-orm/d1";
|
|
9115
9157
|
import { eq, desc, asc, sql, like, or, inArray } from "drizzle-orm";
|
|
@@ -9122,7 +9164,7 @@ ${l}
|
|
|
9122
9164
|
export function registerAdminDashboard(app: Hono<any>, options: { databaseBinding: string, r2Binding?: string }) {
|
|
9123
9165
|
const adminApp = new Hono<any>();
|
|
9124
9166
|
|
|
9125
|
-
${
|
|
9167
|
+
${c}
|
|
9126
9168
|
|
|
9127
9169
|
${p}
|
|
9128
9170
|
|
|
@@ -9133,61 +9175,61 @@ ${p}
|
|
|
9133
9175
|
${s}
|
|
9134
9176
|
|
|
9135
9177
|
// Generate storage routes
|
|
9136
|
-
${
|
|
9178
|
+
${u}
|
|
9137
9179
|
|
|
9138
9180
|
app.route('/admin', adminApp);
|
|
9139
9181
|
app.get('/admin/', (c) => c.redirect('/admin'));
|
|
9140
9182
|
}
|
|
9141
|
-
`}function
|
|
9142
|
-
`}function
|
|
9183
|
+
`}function oe(e){if(typeof e!="object"||e===null)return false;let n=e;return n.kind==="schema"&&typeof n.tables=="object"&&(typeof n.enums=="object"||n.enums===void 0)}function O(e){return e.replace(/([a-z0-9])([A-Z])/g,"$1_$2").replace(/[\s-]+/g,"_").toLowerCase()}function F(e){return e.replace(/[_-]+/g," ").replace(/\s+(.)/g,(n,t)=>t.toUpperCase()).replace(/\s/g,"").replace(/^(.)/,(n,t)=>t.toUpperCase())}function le(e){return e.endsWith("ies")?`${e.slice(0,-3)}y`:e.endsWith("ses")?e.slice(0,-2):e.endsWith("s")&&e.length>1?e.slice(0,-1):e}function f(e){return JSON.stringify(e)}function Er(e){if(typeof e=="string")return f(e);if(typeof e=="number"||typeof e=="boolean")return String(e);if(e===null)return "null";if(e instanceof Date)return f(e.toISOString());throw new Error(`Unsupported SQL default value '${String(e)}'. Use string, number, boolean, null, or Date.`)}function Pr(e){return {kind:"schema",tables:Object.fromEntries(Object.entries(e.tables).map(([n,t])=>[n,{kind:"table",sqlName:t.sqlName,columns:Object.fromEntries(Object.entries(t.columns).map(([r,a])=>[r,{...a}])),relations:Object.fromEntries(Object.entries(t.relations).map(([r,a])=>[r,{...a}]))}])),enums:Object.fromEntries(Object.entries(e.enums??{}).map(([n,t])=>[n,{...t}]))}}function H(e,n,t){let r=e.tables[n];return r?r.columns[t]?.type:void 0}function mn(e,n,t,r,a,o,i){let s=n.columns[t];if(s){if(s.references&&(s.references.table!==r||s.references.column!==a))throw new Error(`Inferred relation '${e}.${t}' conflicts with explicit references(${s.references.table}.${s.references.column}).`);n.columns[t]={...s,notNull:s.notNull??(s.nullable===true?false:o.notNull),nullable:s.nullable??(o.notNull===false?true:void 0),references:{table:r,column:a,onDelete:s.references?.onDelete??o.onDelete,onUpdate:s.references?.onUpdate??o.onUpdate}};return}n.columns[t]={kind:"column",type:o.fkType??i,sqlName:o.sqlName,notNull:o.notNull??true,nullable:o.notNull===false?true:void 0,references:{table:r,column:a,onDelete:o.onDelete,onUpdate:o.onUpdate}};}function fn(e,n,t){if(n.notNull===true&&n.nullable===true)throw new Error(`Invalid nullable configuration on '${e}': cannot set both notNull and nullable to true.`);return n.notNull===true?true:n.nullable===true||n.notNull===false?false:t}function gn(e,n){return `${e}:${n}`}function Or(e,n,t,r){let a=gn(e,n),o=gn(t,r);return a<=o?{key:`${a}|${o}`,leftTable:e,leftReferenceField:n,rightTable:t,rightReferenceField:r,sourceIsLeft:true}:{key:`${o}|${a}`,leftTable:t,leftReferenceField:r,rightTable:e,rightReferenceField:n,sourceIsLeft:false}}function jr(e,n){return `${e}${F(n)}Links`}function hn(e,n,t){let r=le(e),a=le(n);return r===a?`${t}${F(r)}Id`:`${r}Id`}function Dr(e,n,t){if(e.junctionTable!==n.junctionTable)throw new Error(`manyToMany pair '${t}' has conflicting junctionTable values ('${e.junctionTable}' vs '${n.junctionTable}').`);if(e.leftField!==n.leftField)throw new Error(`manyToMany pair '${t}' has conflicting left field values ('${e.leftField}' vs '${n.leftField}').`);if(e.rightField!==n.rightField)throw new Error(`manyToMany pair '${t}' has conflicting right field values ('${e.rightField}' vs '${n.rightField}').`);if(e.leftSqlName!==n.leftSqlName)throw new Error(`manyToMany pair '${t}' has conflicting left sql name values ('${e.leftSqlName}' vs '${n.leftSqlName}').`);if(e.rightSqlName!==n.rightSqlName)throw new Error(`manyToMany pair '${t}' has conflicting right sql name values ('${e.rightSqlName}' vs '${n.rightSqlName}').`);if(e.onDelete!==n.onDelete)throw new Error(`manyToMany pair '${t}' has conflicting onDelete values ('${e.onDelete}' vs '${n.onDelete}').`);if(e.onUpdate!==n.onUpdate)throw new Error(`manyToMany pair '${t}' has conflicting onUpdate values ('${e.onUpdate}' vs '${n.onUpdate}').`);return e}function Vr(e){let n=new Map;for(let[t,r]of Object.entries(e.tables))for(let a of Object.values(r.relations)){if(a.relation!=="manyToMany")continue;let o=a.referenceField??"id",i=a.targetReferenceField??"id",s=Or(t,o,a.targetTable,i),u=hn(s.leftTable,s.rightTable,"source"),l=hn(s.rightTable,s.leftTable,"target"),c={leftTable:s.leftTable,leftReferenceField:s.leftReferenceField,rightTable:s.rightTable,rightReferenceField:s.rightReferenceField,junctionTable:a.junctionTable??jr(s.leftTable,s.rightTable),leftField:s.sourceIsLeft?a.sourceField??u:a.targetField??u,rightField:s.sourceIsLeft?a.targetField??l:a.sourceField??l,leftSqlName:s.sourceIsLeft?a.sourceSqlName:a.targetSqlName,rightSqlName:s.sourceIsLeft?a.targetSqlName:a.sourceSqlName,onDelete:a.onDelete,onUpdate:a.onUpdate};if(c.leftField===c.rightField)throw new Error(`manyToMany pair '${s.key}' resolves to duplicate junction fields '${c.leftField}'. Set sourceField/targetField explicitly.`);let p=n.get(s.key);p?Dr(p,c,s.key):n.set(s.key,c),a.referenceField=o,a.targetReferenceField=i,a.junctionTable=c.junctionTable,a.sourceField=s.sourceIsLeft?c.leftField:c.rightField,a.targetField=s.sourceIsLeft?c.rightField:c.leftField,a.sourceSqlName=s.sourceIsLeft?c.leftSqlName:c.rightSqlName,a.targetSqlName=s.sourceIsLeft?c.rightSqlName:c.leftSqlName;}for(let t of n.values()){if(t.junctionTable in e.tables)throw new Error(`manyToMany auto junction table '${t.junctionTable}' conflicts with an existing table. Set a different junctionTable name.`);let r=H(e,t.leftTable,t.leftReferenceField)??"string",a=H(e,t.rightTable,t.rightReferenceField)??"string";e.tables[t.junctionTable]={kind:"table",columns:{[t.leftField]:{kind:"column",type:r,sqlName:t.leftSqlName,notNull:true,nullable:false,references:{table:t.leftTable,column:t.leftReferenceField,onDelete:t.onDelete,onUpdate:t.onUpdate},index:true},[t.rightField]:{kind:"column",type:a,sqlName:t.rightSqlName,notNull:true,nullable:false,references:{table:t.rightTable,column:t.rightReferenceField,onDelete:t.onDelete,onUpdate:t.onUpdate},index:true}},relations:{[t.leftTable]:{kind:"relation",relation:"one",targetTable:t.leftTable,field:t.leftField,referenceField:t.leftReferenceField},[t.rightTable]:{kind:"relation",relation:"one",targetTable:t.rightTable,field:t.rightField,referenceField:t.rightReferenceField}}};}}function Br(e){for(let[n,t]of Object.entries(e.tables)){for(let[r,a]of Object.entries(t.columns))if(a.notNull===true&&a.nullable===true)throw new Error(`Invalid nullable configuration on '${n}.${r}': cannot set both notNull and nullable to true.`);for(let[r,a]of Object.entries(t.relations))if(a.relation!=="manyToMany"&&a.notNull===true&&a.nullable===true)throw new Error(`Invalid nullable configuration on '${n}.${r}': cannot set both notNull and nullable to true.`)}}function Wr(e){Br(e);let n=Pr(e);for(let[t,r]of Object.entries(n.tables))for(let[a,o]of Object.entries(r.relations)){if(o.relation!=="one")continue;let i=o.referenceField??"id",s=o.field??`${a}Id`;o.field=s;let u=H(n,o.targetTable,i)??o.fkType??"string";mn(t,r,s,o.targetTable,i,{fkType:o.fkType,sqlName:o.sqlName,notNull:fn(`${t}.${a}`,o,true),onDelete:o.onDelete,onUpdate:o.onUpdate},u);}for(let[t,r]of Object.entries(n.tables))for(let a of Object.values(r.relations)){if(a.relation!=="many")continue;let o=n.tables[a.targetTable];if(!o)continue;let i=a.referenceField??"id",s=a.field??`${le(t)}Id`;a.field=s;let u=H(n,t,i)??a.fkType??"string";mn(a.targetTable,o,s,t,i,{fkType:a.fkType,sqlName:a.sqlName,notNull:fn(`${t}.${a.targetTable}`,a,true),onDelete:a.onDelete,onUpdate:a.onUpdate},u);}return Vr(n),n}function bn(e){return e.primaryKey===true||e.notNull!==true||e.autoIncrement===true||e.sqlDefault!==void 0||e.runtimeDefaultFn!==void 0}function j(e){return e.notNull!==true}function Hr(e,n,t){let r=n.sqlName??O(e),a=r!==e;if(n.type==="int")return a?`t.int(${f(r)})`:"t.int()";if(n.type==="string")return n.length!==void 0?a?`t.text(${f(r)}, { length: ${n.length} })`:`t.text({ length: ${n.length} })`:a?`t.text(${f(r)})`:"t.text()";if(n.type==="boolean")return a?`t.int(${f(r)}, { mode: "boolean" })`:'t.int({ mode: "boolean" })';if(n.type==="date")return a?`t.int(${f(r)}, { mode: "timestamp_ms" })`:'t.int({ mode: "timestamp_ms" })';if(n.type==="enum"&&n.enumValues&&n.enumValues.length>0)return n.isArray?a?`t.text(${f(r)}).array()`:"t.text().array()":a?`t.text(${f(r)})`:"t.text()";if(n.type==="json"&&n.jsonShape){let o=L(n.jsonShape);return `${a?`t.text(${f(r)}, { mode: "json" })`:'t.text({ mode: "json" })'}.$type<${o}>()`}return t==="camelToSnake"&&a?`t.text(${f(r)})`:"t.text()"}function Lr(e,n,t){let r=t.field,a=t.referenceField??"id";if(!r)throw new Error(`Relation on '${e}' targeting '${t.targetTable}' is missing a local field.`);if(!(r in n.columns))throw new Error(`Relation '${e}.${r}' references missing local field '${r}'.`);return {sourceField:r,targetField:a}}function zr(e){return e.size===0?"":`import { ${Array.from(e).sort().join(", ")} } from "./auth.schema";
|
|
9184
|
+
`}function Ur(e){return Object.values(e.relations).filter(n=>n.relation==="one").map(n=>n.targetTable)}function Qr(e,n,t){if(n.references)return {tableName:n.references.table,fieldName:n.references.column};let r=Object.values(t.relations).find(a=>a.relation==="one"&&a.field===e);if(r)return {tableName:r.targetTable,fieldName:r.referenceField??"id"}}function _r(e){let n=[];for(let[t,r]of Object.entries(e.tables)){let a=[];for(let[o,i]of Object.entries(r.columns)){if(i.type!=="json"||!i.jsonShape)continue;let s=ue(i.jsonShape);a.push(`${f(o)}: { shape: ${s} },`);}a.length!==0&&n.push(`${f(t)}: {
|
|
9143
9185
|
${a.map(o=>` ${o}`).join(`
|
|
9144
9186
|
`)}
|
|
9145
|
-
},`);}return
|
|
9187
|
+
},`);}return n.length===0?`export const __appflareJsonColumns = {} as const;
|
|
9146
9188
|
`:`export const __appflareJsonColumns = {
|
|
9147
|
-
${
|
|
9189
|
+
${n.map(t=>` ${t}`).join(`
|
|
9148
9190
|
`)}
|
|
9149
9191
|
} as const;
|
|
9150
|
-
`}function
|
|
9151
|
-
targetTable: ${
|
|
9152
|
-
junctionTable: ${
|
|
9153
|
-
sourceField: ${
|
|
9154
|
-
targetField: ${
|
|
9155
|
-
},`);a.length!==0&&
|
|
9192
|
+
`}function ue(e){return e.kind==="array"?`{ kind: "array", element: ${ue(e.element)} }`:e.kind==="object"?`{ kind: "object", shape: { ${Object.entries(e.shape).map(([t,r])=>`${f(t)}: ${ue(r)}`).join(", ")} } }`:`{ kind: ${f(e.kind)} }`}function Kr(e){let n=[];for(let[t,r]of Object.entries(e.tables)){let a=[];for(let[o,i]of Object.entries(r.relations))i.relation==="manyToMany"&&i.junctionTable&&a.push(`${f(o)}: {
|
|
9193
|
+
targetTable: ${f(i.targetTable)},
|
|
9194
|
+
junctionTable: ${f(i.junctionTable)},
|
|
9195
|
+
sourceField: ${f(i.sourceField??"")},
|
|
9196
|
+
targetField: ${f(i.targetField??"")},
|
|
9197
|
+
},`);a.length!==0&&n.push(`${f(t)}: {
|
|
9156
9198
|
${a.map(o=>` ${o}`).join(`
|
|
9157
9199
|
`)}
|
|
9158
|
-
},`);}return
|
|
9200
|
+
},`);}return n.length===0?`export const __appflareManyToMany = {} as const;
|
|
9159
9201
|
`:`export const __appflareManyToMany = {
|
|
9160
|
-
${
|
|
9202
|
+
${n.map(t=>` ${t}`).join(`
|
|
9161
9203
|
`)}
|
|
9162
9204
|
} as const;
|
|
9163
|
-
`}function
|
|
9205
|
+
`}function Jr(e){let n=[];for(let[t,r]of Object.entries(e.tables)){let a=[];for(let[o,i]of Object.entries(r.relations)){if(i.relation==="one"){a.push(`${f(o)}: {
|
|
9164
9206
|
kind: "one",
|
|
9165
|
-
targetTable: ${
|
|
9166
|
-
sourceField: ${
|
|
9167
|
-
referenceField: ${
|
|
9168
|
-
},`);continue}if(i.relation==="many"){a.push(`${
|
|
9207
|
+
targetTable: ${f(i.targetTable)},
|
|
9208
|
+
sourceField: ${f(i.field??"")},
|
|
9209
|
+
referenceField: ${f(i.referenceField??"id")},
|
|
9210
|
+
},`);continue}if(i.relation==="many"){a.push(`${f(o)}: {
|
|
9169
9211
|
kind: "many",
|
|
9170
|
-
targetTable: ${
|
|
9171
|
-
sourceField: ${
|
|
9172
|
-
referenceField: ${
|
|
9173
|
-
},`);continue}a.push(`${
|
|
9212
|
+
targetTable: ${f(i.targetTable)},
|
|
9213
|
+
sourceField: ${f(i.field??"")},
|
|
9214
|
+
referenceField: ${f(i.referenceField??"id")},
|
|
9215
|
+
},`);continue}a.push(`${f(o)}: {
|
|
9174
9216
|
kind: "manyToMany",
|
|
9175
|
-
targetTable: ${
|
|
9176
|
-
junctionTable: ${
|
|
9177
|
-
sourceField: ${
|
|
9178
|
-
targetField: ${
|
|
9179
|
-
referenceField: ${
|
|
9180
|
-
targetReferenceField: ${
|
|
9181
|
-
},`);}a.length!==0&&
|
|
9217
|
+
targetTable: ${f(i.targetTable)},
|
|
9218
|
+
junctionTable: ${f(i.junctionTable??"")},
|
|
9219
|
+
sourceField: ${f(i.sourceField??"")},
|
|
9220
|
+
targetField: ${f(i.targetField??"")},
|
|
9221
|
+
referenceField: ${f(i.referenceField??"id")},
|
|
9222
|
+
targetReferenceField: ${f(i.targetReferenceField??"id")},
|
|
9223
|
+
},`);}a.length!==0&&n.push(`${f(t)}: {
|
|
9182
9224
|
${a.map(o=>` ${o}`).join(`
|
|
9183
9225
|
`)}
|
|
9184
|
-
},`);}return
|
|
9226
|
+
},`);}return n.length===0?`export const __appflareRelations = {} as const;
|
|
9185
9227
|
`:`export const __appflareRelations = {
|
|
9186
|
-
${
|
|
9228
|
+
${n.map(t=>` ${t}`).join(`
|
|
9187
9229
|
`)}
|
|
9188
9230
|
} as const;
|
|
9189
|
-
`}function
|
|
9190
|
-
${
|
|
9231
|
+
`}function Gr(e,n){let t=new Set(Object.keys(e.tables)),r=new Set;for(let l of Object.values(e.tables)){for(let c of Ur(l))t.has(c)||r.add(c);for(let c of Object.values(l.columns))c.references&&!t.has(c.references.table)&&r.add(c.references.table);}let a=new Map;for(let l of Object.values(e.tables))for(let[c,p]of Object.entries(l.columns))if(p.type==="enum"&&p.enumValues&&p.enumValues.length>0){let d=p.enumRef??`${c}`;a.has(d)||a.set(d,p);}let o=[],i=[];for(let[l,c]of a.entries()){let p=F(l),d=c.enumValues.map(y=>`"${y}"`).join(" | ");o.push(`export type ${p} = ${d};`),i.push(`export const ${p}Column = t.customType<{ data: ${p}; dataNotNull: ${p} }>({ dataType: () => "text" });`);}let s=[],u=[];for(let[l,c]of Object.entries(e.tables)){let p=c.sqlName??O(l),d=[],y=[];for(let[b,h]of Object.entries(c.columns)){let T;if(h.type==="enum"&&h.enumValues&&h.enumValues.length>0){let R=h.enumRef??b,E=F(R),V=h.sqlName??O(b);T=V!==b?`${E}Column(${f(V)})`:`${E}Column()`,h.isArray&&(T+=".array()");}else T=Hr(b,h,n);h.uuidPrimaryKey&&(T+=".$defaultFn(() => crypto.randomUUID())"),h.primaryKey&&(T+=h.autoIncrement?".primaryKey({ autoIncrement: true })":".primaryKey()"),h.notNull&&(T+=".notNull()"),h.sqlDefault!==void 0&&(T+=`.default(${Er(h.sqlDefault)})`);let C=Qr(b,h,c);if(C)if(h.references?.onDelete||h.references?.onUpdate){let R=[];h.references.onDelete&&R.push(`onDelete: ${f(h.references.onDelete)}`),h.references.onUpdate&&R.push(`onUpdate: ${f(h.references.onUpdate)}`),T+=`.references(() => ${C.tableName}.${C.fieldName}, { ${R.join(", ")} })`;}else T+=`.references(() => ${C.tableName}.${C.fieldName})`;if(h.unique){let R=typeof h.unique=="object"&&h.unique.name?h.unique.name:`${p}_${O(b)}_unique_idx`;y.push(` t.uniqueIndex(${f(R)}).on(table.${b})`);}if(h.index){let R=typeof h.index=="object"&&h.index.name?h.index.name:`${p}_${O(b)}_idx`;y.push(` t.index(${f(R)}).on(table.${b})`);}d.push(` ${b}: ${T},`);}y.length>0?s.push(`export const ${l} = table(
|
|
9232
|
+
${f(p)},
|
|
9191
9233
|
{
|
|
9192
9234
|
${d.join(`
|
|
9193
9235
|
`)}
|
|
@@ -9196,19 +9238,19 @@ ${d.join(`
|
|
|
9196
9238
|
${y.join(`,
|
|
9197
9239
|
`)}
|
|
9198
9240
|
],
|
|
9199
|
-
);`):s.push(`export const ${l} = table(${
|
|
9241
|
+
);`):s.push(`export const ${l} = table(${f(p)}, {
|
|
9200
9242
|
${d.join(`
|
|
9201
9243
|
`)}
|
|
9202
|
-
});`);let v=Object.entries(
|
|
9244
|
+
});`);let v=Object.entries(c.relations).filter(([,b])=>b.relation==="one"),A=Object.entries(c.relations).filter(([,b])=>b.relation==="many"),w=Object.entries(c.relations).filter(([,b])=>b.relation==="manyToMany");if(v.length===0&&A.length===0&&w.length===0)continue;let I=[];for(let[b,h]of v){let T=Lr(l,c,h);I.push(` ${b}: one(${h.targetTable}, {
|
|
9203
9245
|
fields: [${l}.${T.sourceField}],
|
|
9204
9246
|
references: [${h.targetTable}.${T.targetField}],
|
|
9205
|
-
}),`);}for(let[b,h]of A)I.push(` ${b}: many(${h.targetTable}),`);for(let[b,h]of w){if(!h.junctionTable)throw new Error(`manyToMany relation '${l}.${b}' is missing junctionTable after normalization.`);I.push(` ${b}: many(${h.junctionTable}),`);}
|
|
9247
|
+
}),`);}for(let[b,h]of A)I.push(` ${b}: many(${h.targetTable}),`);for(let[b,h]of w){if(!h.junctionTable)throw new Error(`manyToMany relation '${l}.${b}' is missing junctionTable after normalization.`);I.push(` ${b}: many(${h.junctionTable}),`);}u.push(`export const ${l}Relations = relations(${l}, ({ one, many }) => ({
|
|
9206
9248
|
${I.join(`
|
|
9207
9249
|
`)}
|
|
9208
9250
|
}));`);}return `import * as t from "drizzle-orm/sqlite-core";
|
|
9209
9251
|
import { sqliteTable as table } from "drizzle-orm/sqlite-core";
|
|
9210
9252
|
import { relations } from "drizzle-orm";
|
|
9211
|
-
${
|
|
9253
|
+
${zr(r)}
|
|
9212
9254
|
${o.join(`
|
|
9213
9255
|
`)}
|
|
9214
9256
|
${i.join(`
|
|
@@ -9218,30 +9260,30 @@ ${s.join(`
|
|
|
9218
9260
|
|
|
9219
9261
|
`)}
|
|
9220
9262
|
|
|
9221
|
-
${
|
|
9263
|
+
${u.join(`
|
|
9222
9264
|
|
|
9223
9265
|
`)}
|
|
9224
9266
|
|
|
9225
|
-
${
|
|
9267
|
+
${_r(e)}
|
|
9226
9268
|
|
|
9227
|
-
${
|
|
9269
|
+
${Kr(e)}
|
|
9228
9270
|
|
|
9229
|
-
${
|
|
9230
|
-
`}function
|
|
9271
|
+
${Jr(e)}
|
|
9272
|
+
`}function ce(e){return e.kind==="array"?`z.array(${ce(e.element)})`:e.kind==="object"?`z.object({ ${Object.entries(e.shape).map(([t,r])=>`${f(t)}: ${ce(r)}`).join(", ")} })`:e.kind==="string"?"z.string()":e.kind==="number"?"z.number()":e.kind==="boolean"?"z.boolean()":e.kind==="date"?"z.date()":"z.unknown()"}function yn(e,n,t){let r="z.unknown()";if(e.type==="int")r="z.number().int()";else if(e.type==="string")r="z.string()",e.length!==void 0&&(r+=`.max(${e.length})`);else if(e.type==="boolean")r="z.boolean()";else if(e.type==="date")r="z.date()";else if(e.type==="enum"&&e.enumValues&&e.enumValues.length>0){let o=`z.enum([${e.enumValues.map(i=>`"${i}"`).join(", ")}])`;r=e.isArray?`z.array(${o})`:o;}else e.type==="json"&&e.jsonShape&&(r=ce(e.jsonShape));return n&&(r+=".optional()"),t&&(r+=".nullable()"),r}function Zr(e){let n=[];for(let[t,r]of Object.entries(e.tables)){let a=F(t),o=[],i=[];for(let[s,u]of Object.entries(r.columns))o.push(` ${s}: ${yn(u,bn(u),j(u))},`),i.push(` ${s}: ${yn(u,j(u),j(u))},`);n.push(`export const ${t}InsertSchema = z.object({
|
|
9231
9273
|
${o.join(`
|
|
9232
9274
|
`)}
|
|
9233
9275
|
});
|
|
9234
|
-
export const ${
|
|
9276
|
+
export const ${t}SelectSchema = z.object({
|
|
9235
9277
|
${i.join(`
|
|
9236
9278
|
`)}
|
|
9237
9279
|
});
|
|
9238
9280
|
|
|
9239
|
-
export type ${a}Insert = z.infer<typeof ${
|
|
9240
|
-
export type ${a}Select = z.infer<typeof ${
|
|
9281
|
+
export type ${a}Insert = z.infer<typeof ${t}InsertSchema>;
|
|
9282
|
+
export type ${a}Select = z.infer<typeof ${t}SelectSchema>;
|
|
9241
9283
|
`);}return `import { z } from "zod";
|
|
9242
9284
|
|
|
9243
|
-
${
|
|
9244
|
-
`)}`}function L(e){return e.kind==="array"?`Array<${L(e.element)}>`:e.kind==="object"?`{ ${Object.entries(e.shape).map(([
|
|
9285
|
+
${n.join(`
|
|
9286
|
+
`)}`}function L(e){return e.kind==="array"?`Array<${L(e.element)}>`:e.kind==="object"?`{ ${Object.entries(e.shape).map(([t,r])=>`${t}: ${L(r)}`).join("; ")} }`:e.kind==="string"?"string":e.kind==="number"?"number":e.kind==="boolean"?"boolean":e.kind==="date"?"Date":"unknown"}function Xr(e){if(e.type==="int")return "number";if(e.type==="string")return "string";if(e.type==="boolean")return "boolean";if(e.type==="date")return "Date";if(e.type==="enum"&&e.enumValues&&e.enumValues.length>0){let n=e.enumValues.map(t=>`"${t}"`).join(" | ");return e.isArray?`Array<${n}>`:n}return e.type==="json"&&e.jsonShape?L(e.jsonShape):"unknown"}function Yr(e){let n=[];for(let[r,a]of Object.entries(e.enums??{})){let o=F(r),i=a.values.map(s=>`"${s}"`).join(" | ");n.push(`export type ${o} = ${i};`);}let t=[];for(let[r,a]of Object.entries(e.tables)){let o=F(r),i=[],s=[];for(let[u,l]of Object.entries(a.columns)){let c=Xr(l),p=j(l)?" | null":"";i.push(` ${u}${j(l)?"?":""}: ${c}${p};`),s.push(` ${u}${bn(l)?"?":""}: ${c}${p};`);}t.push(`export type ${o} = {
|
|
9245
9287
|
${i.join(`
|
|
9246
9288
|
`)}
|
|
9247
9289
|
};
|
|
@@ -9249,30 +9291,30 @@ ${i.join(`
|
|
|
9249
9291
|
export type New${o} = {
|
|
9250
9292
|
${s.join(`
|
|
9251
9293
|
`)}
|
|
9252
|
-
};`);}return `${
|
|
9294
|
+
};`);}return `${n.join(`
|
|
9253
9295
|
`)}
|
|
9254
|
-
${
|
|
9296
|
+
${t.join(`
|
|
9255
9297
|
|
|
9256
9298
|
`)}
|
|
9257
|
-
`}function
|
|
9258
|
-
import { customType } from "drizzle-orm/sqlite-core"`).replace(/role:\s*text\(["']role["']\)/,`role: customType<{ data: ${r}; dataNotNull: ${r} }>({ dataType: () => "text" })("role")`);await Bun.write(e,a);}function
|
|
9259
|
-
`);let
|
|
9260
|
-
`);let
|
|
9261
|
-
`),...
|
|
9262
|
-
`),Bun.write(
|
|
9263
|
-
`);let _=relative(o,A).replace(/\\/g,"/"),
|
|
9264
|
-
`),
|
|
9265
|
-
`));function
|
|
9299
|
+
`}function ea(e,n){if(n){let t=e[n];if(!oe(t))throw new Error(`schemaDsl.exportName '${n}' does not point to a schema() export.`);return t}for(let t of Object.values(e))if(oe(t))return t;throw new Error("No schema() export found in schemaDsl entry module. Set schemaDsl.exportName to the correct export.")}async function wn(e){let n=e.config.schemaDsl;if(!n)return;let t=n.namingStrategy??"camelToSnake",r=resolve(e.configDir,n.entry),a=resolve(e.configDir,n.outFile??resolve(e.outDirAbs,"schema.compiled.ts")),o=resolve(e.configDir,n.typesOutFile??resolve(e.outDirAbs,"schema.types.ts")),i=resolve(e.configDir,n.zodOutFile??resolve(e.outDirAbs,"schema.zod.ts")),u=await import(`${pathToFileURL(r).href}?t=${Date.now()}`),l=ea(u,n.exportName),c=Wr(l);await Promise.all([mkdir(dirname(a),{recursive:true}),mkdir(dirname(o),{recursive:true}),mkdir(dirname(i),{recursive:true})]);let p=Gr(c,t),d=Yr(c),y=Zr(c);return await Promise.all([Bun.write(a,p),Bun.write(o,d),Bun.write(i,y)]),{schemaPath:a,typesPath:o,zodPath:i,tableNames:Object.keys(c.tables)}}function na(e){return e.replaceAll("\\","/")}function M(e,n){let t=na(relative(e,n)).replace(/\.tsx?$/,"");return t.startsWith(".")?t:`./${t}`}var ia=new Set([".ts",".tsx",".mts",".cts"]);async function Rn(e){let n=await readdir(e,{withFileTypes:true}),t=[];for(let r of n){if(r.name.startsWith(".")||r.name==="node_modules"||r.name==="_generated")continue;let a=resolve(e,r.name);if(r.isDirectory()){t.push(...await Rn(a));continue}r.isFile()&&ia.has(extname(r.name))&&t.push(a);}return t}function de(e){return e.replace(/\.[cm]?tsx?$/,"")}function sa(e,n){let t=e,r=false,a,o="unknown";for(;g.isCallExpression(t);){let i=t.expression;if(!g.isPropertyAccessExpression(i))break;let s=i.name.text;if(s==="optional"||s==="nullable")r=true,t=i.expression;else if(s==="default"){r=true;let u=t.arguments[0];u&&(g.isStringLiteral(u)||g.isNumericLiteral(u)?a=u.text:u.kind===g.SyntaxKind.TrueKeyword?a="true":u.kind===g.SyntaxKind.FalseKeyword&&(a="false")),t=i.expression;}else if(s==="string"||s==="uuid"||s==="email"||s==="url"){o="string";break}else if(s==="number"||s==="int"||s==="float"){o="number";break}else if(s==="boolean"){o="boolean";break}else t=i.expression;}return {name:n,type:o,optional:r,defaultValue:a}}function la(e){if(!e||!g.isObjectLiteralExpression(e))return [];let n=e.properties.find(r=>g.isPropertyAssignment(r)&&g.isIdentifier(r.name)&&r.name.text==="args");if(!n||!g.isObjectLiteralExpression(n.initializer))return [];let t=[];for(let r of n.initializer.properties)!g.isPropertyAssignment(r)||!g.isIdentifier(r.name)||t.push(sa(r.initializer,r.name.text));return t}function ua(e){return g.isVariableStatement(e)?e.modifiers?.some(n=>n.kind===g.SyntaxKind.ExportKeyword)??false:false}function kn(e){return g.isIdentifier(e)?e.text:g.isParenthesizedExpression(e)?kn(e.expression):null}function ca(e){if(!e||!g.isObjectLiteralExpression(e))return [];let n=e.properties.find(r=>!g.isPropertyAssignment(r)||!g.isIdentifier(r.name)?false:r.name.text==="cronTrigger");if(!n||!g.isPropertyAssignment(n))return [];let t=n.initializer;return g.isStringLiteral(t)||g.isNoSubstitutionTemplateLiteral(t)?[t.text.trim()].filter(r=>r.length>0):g.isArrayLiteralExpression(t)?t.elements.map(r=>g.isStringLiteral(r)||g.isNoSubstitutionTemplateLiteral(r)?r.text.trim():"").filter(r=>r.length>0):[]}function da(e,n){let t=g.createSourceFile(n,e,g.ScriptTarget.Latest,true,g.ScriptKind.TS),r=[];for(let a of t.statements)if(ua(a))for(let o of a.declarationList.declarations){if(!g.isIdentifier(o.name)||!o.initializer||!g.isCallExpression(o.initializer))continue;let i=kn(o.initializer.expression);i!=="query"&&i!=="mutation"&&i!=="scheduler"&&i!=="cron"&&i!=="storageManager"||r.push({exportName:o.name.text,kind:i==="storageManager"?"storage":i,cronTriggers:i==="cron"?ca(o.initializer.arguments[0]):[],args:i==="query"||i==="mutation"?la(o.initializer.arguments[0]):[]});}return r}function xn(e,n,t){let r=n.replace(/\\/g,"/"),o=de(r).split("/").filter(Boolean);return `/${[e,...o,t].filter(Boolean).map(s=>s.trim()).filter(s=>s.length>0).join("/")}`}function pa(e,n){let t=e.replace(/\\/g,"/"),r=`${n}/`,a=t.indexOf(r);return a>=0?t.slice(a+r.length):t===n?"index.ts":t}function Tn(e,n){let t=e.replace(/\\/g,"/"),a=de(t).split("/").filter(Boolean),o=a[a.length-1]??"index";return [a.length>1?a[a.length-2]:"root",o,n].map(s=>s.trim()).filter(s=>s.length>0).join("/")}async function Sn(e){let n=[],t=await Rn(e.scanDirAbs).catch(()=>[]);for(let a of t){let o=Bun.file(a);if(!await o.exists())continue;let i=await o.text(),s=relative(e.scanDirAbs,a),u=da(i,a),l=[{kind:"query",kindDirectory:"queries",exports:u.filter(c=>c.kind==="query")},{kind:"mutation",kindDirectory:"mutations",exports:u.filter(c=>c.kind==="mutation")},{kind:"scheduler",kindDirectory:"schedulers",exports:u.filter(c=>c.kind==="scheduler")},{kind:"cron",kindDirectory:"crons",exports:u.filter(c=>c.kind==="cron")},{kind:"storage",kindDirectory:"queries",exports:u.filter(c=>c.kind==="storage")}];for(let c of l){if(c.exports.length===0)continue;let p=pa(s,c.kindDirectory);for(let d of c.exports){let y=c.kind==="query"||c.kind==="mutation"?Tn(p,d.exportName):void 0,v=c.kind==="scheduler"||c.kind==="cron"?Tn(p,d.exportName):void 0,A=c.kind==="query"||c.kind==="mutation"?[...de(p).split("/").filter(Boolean),d.exportName]:void 0,w=c.kind==="query"?xn("queries",p,d.exportName):c.kind==="mutation"?xn("mutations",p,d.exportName):c.kind==="storage"?`/storage/managers/${d.exportName}`:`/${c.kindDirectory}/${v}`;n.push({kind:c.kind,exportName:d.exportName,filePath:a,importPath:M(e.outDirAbs,a),clientImportPath:M(resolve(e.outDirAbs,"client"),a),routePath:w,handlerName:y,clientSegments:A,taskName:v,cronTriggers:d.cronTriggers,args:d.args});}}}n.sort((a,o)=>a.routePath.localeCompare(o.routePath));let r=new Map;for(let a of n){let o=a.taskName?`task:${a.taskName}`:`route:${a.routePath}`,i=r.get(o);if(i)throw new Error(`Duplicate handler operation discovered: ${a.taskName??a.routePath} (${i} and ${a.filePath}#${a.exportName}).`);r.set(o,`${a.filePath}#${a.exportName}`);}return n}function fa(e){let n=[],t="",r=0,a=0,o=0,i=false,s=false,u=false,l=false;for(let p=0;p<e.length;p+=1){let d=e[p];if(l){t+=d,l=false;continue}if(d==="\\"){t+=d,l=true;continue}if(!s&&!u&&d==="'"){i=!i,t+=d;continue}if(!i&&!u&&d==='"'){s=!s,t+=d;continue}if(!i&&!s&&d==="`"){u=!u,t+=d;continue}if(i||s||u){t+=d;continue}if(d==="("?r+=1:d===")"?r-=1:d==="{"?a+=1:d==="}"?a-=1:d==="["?o+=1:d==="]"&&(o-=1),d===","&&r===0&&a===0&&o===0){let y=t.trim();y.length>0&&n.push(y),t="";continue}t+=d;}let c=t.trim();return c.length>0&&n.push(c),n}function ga(e){let n=0,t=0,r=0,a=false,o=false,i=false,s=false;for(let u=0;u<e.length;u+=1){let l=e[u];if(s){s=false;continue}if(l==="\\"){s=true;continue}if(!o&&!i&&l==="'"){a=!a;continue}if(!a&&!i&&l==='"'){o=!o;continue}if(!a&&!o&&l==="`"){i=!i;continue}if(!(a||o||i)){if(l==="("){n+=1;continue}if(l===")"){n-=1;continue}if(l==="{"){t+=1;continue}if(l==="}"){t-=1;continue}if(l==="["){r+=1;continue}if(l==="]"){r-=1;continue}if(l===":"&&n===0&&t===0&&r===0)return u}}return -1}function ha(e){let n=e.toLowerCase();return /mode\s*:\s*["'`](timestamp|timestamp_ms)["'`]/.test(n)?"date":/mode\s*:\s*["'`]boolean["'`]/.test(n)?"boolean":/\.(date|datetime|timestamp)\s*\(/.test(n)?"date":/\.(int|integer|real|numeric|decimal|float|double)\s*\(/.test(n)?"number":/\.(text|varchar|char)\s*\(/.test(n)?"string":/\.(boolean|bool)\s*\(/.test(n)?"boolean":"unknown"}function ya(e){let n=fa(e),t=[];for(let r of n){let a=ga(r);if(a===-1)continue;let o=r.slice(0,a).trim().replace(/^['"]|['"]$/g,"");if(!o)continue;let i=r.slice(a+1).trim(),s=/\.primarykey\s*\(/i.test(i),u=/autoincrement\s*:\s*true/i.test(i),l=/\.default\s*\(/i.test(i),p=!/\.notnull\s*\(/i.test(i)||l||u||s;t.push({name:o,expression:i,type:ha(i),optional:p,primaryKey:s,autoIncrement:u});}return t}function ba(e){let n=/export\s+const\s+(\w+)\s*=\s*table\s*\(\s*["'`]([^"'`]+)["'`]/g,t=[],r=(o,i)=>{let s=0,u=false,l=false,c=false,p=false;for(let d=i;d<o.length;d+=1){let y=o[d];if(p){p=false;continue}if(y==="\\"){p=true;continue}if(!l&&!c&&y==="'"){u=!u;continue}if(!u&&!c&&y==='"'){l=!l;continue}if(!u&&!l&&y==="`"){c=!c;continue}if(!(u||l||c)){if(y==="{"){s+=1;continue}if(y==="}"&&(s-=1,s===0))return d}}return -1},a=n.exec(e);for(;a;){let o=a[1],i=a[2],s=e.indexOf("{",n.lastIndex);if(s===-1){a=n.exec(e);continue}let u=r(e,s);if(u===-1){a=n.exec(e);continue}let l=e.slice(s+1,u);t.push({exportName:o,tableName:i,columns:ya(l)}),a=n.exec(e);}return t}async function Nn(e){let n=await readdir(e,{withFileTypes:true}),t=[];for(let r of n){if(r.name.startsWith(".")||r.name==="node_modules"||r.name==="_generated")continue;let a=resolve(e,r.name);if(r.isDirectory()){t.push(...await Nn(a));continue}r.isFile()&&r.name==="schema.ts"&&t.push(a);}return t}async function $n(e,n=[]){let t=await Nn(e.scanDirAbs).catch(()=>[]),r=resolve(e.configDir,"schema.ts"),a=[...n,...t.length?t:[r]];for(let o of a){let i=Bun.file(o);if(!await i.exists())continue;let s=await i.text(),u=ba(s);if(u.length>0)return {schemaPath:o,tables:u}}throw new Error(`Unable to discover schema.ts under scanDir (${e.scanDirAbs}) or fallback (${r}).`)}function Ta(e){let n=e.auth.options.plugins;if(!Array.isArray(n))return [];for(let t of n)if(t&&typeof t=="object"){let r=t;if(r.id==="admin"&&"options"in r){let a=r.options;if(a&&typeof a=="object"&&"roles"in a){let o=a.roles;if(o&&typeof o=="object")return Object.keys(o)}}}return []}function va(e){let r=e.auth.options?.user?.additionalFields;if(!r||typeof r!="object")return [];let a={string:"string",number:"number",boolean:"boolean",date:"Date"};return Object.entries(r).filter(([,o])=>o&&typeof o=="object"&&"type"in o).map(([o,i])=>({name:o,tsType:a[i.type]||"unknown"}))}async function Ra(e,n){let t=await Bun.file(e).text(),r=n.map(o=>`"${o}"`).join(" | "),a=t.replace(/(import.*?from\s+["']drizzle-orm\/sqlite-core["'])/,`$1
|
|
9300
|
+
import { customType } from "drizzle-orm/sqlite-core"`).replace(/role:\s*text\(["']role["']\)/,`role: customType<{ data: ${r}; dataNotNull: ${r} }>({ dataType: () => "text" })("role")`);await Bun.write(e,a);}function ka(e,n){let t=relative(e,n).replace(/\\/g,"/");return t.startsWith(".")?t:`./${t}`}async function Fn(e){let{outDirAbs:n,wranglerOutDirAbs:t,config:r,configPath:a,configDir:o}=e,i=M(n,a),s=resolve(n,"client"),u=M(s,a),l=performance.now();await Promise.all([mkdir(n,{recursive:true}),mkdir(s,{recursive:true}),mkdir(t,{recursive:true})]),process.stdout.write(`\u{1F4C1} Directories (${(performance.now()-l).toFixed(0)}ms)
|
|
9301
|
+
`);let c=dirname(fileURLToPath(import.meta.url)),p=join(dirname(Bun.resolveSync("typescript/package.json",c)),"bin","tsc"),d=join(dirname(Bun.resolveSync("@better-auth/cli/package.json",c)),"dist","index.mjs"),y=resolve(n,"server.ts"),v=resolve(n,"client.ts"),A=resolve(n,"auth.config.ts"),w=resolve(n,"auth.schema.ts"),I=resolve(n,"drizzle.config.ts"),b=resolve(t,"wrangler.json"),h=await wn(e),T=await $n(e,h?[h.schemaPath]:[]),C=M(n,T.schemaPath),R=await Sn(e);process.stdout.write(`\u{1F50D} ${R.length} handler(s) (${(performance.now()-l).toFixed(0)}ms)
|
|
9302
|
+
`);let E=Ta(r),V=va(r),ge=vt(r.auth.basePath,r.database[0].binding,r.kv[0]?.binding,r.scheduler.binding,r.r2[0]?.binding,r.realtime.binding,r.realtime.objectName,r.realtime.subscribePath,r.realtime.websocketPath,r.realtime.protocol),Wn=Ne(u,R),Hn=Z(C,R,r.r2[0]?.binding,E,V),Ln=xe(i),zn=h?[ka(o,h.schemaPath),...r.schema.filter(x=>!/(^|\/)schema\.ts$/.test(x))]:r.schema,Un=$e(zn),Qn=kt(e,R),_n=pn(C,T,R),Kn=resolve(n,"admin.routes.ts"),Jn=Hn.map(x=>Bun.write(resolve(n,x.relativePath),x.source)),Gn=Wn.map(x=>Bun.write(resolve(n,x.relativePath),x.source));await Promise.all([Bun.write(y,ge),Bun.write(v,`export * from "./client/index";
|
|
9303
|
+
`),...Gn,...Jn,Bun.write(A,Ln),Bun.write(w,""),Bun.write(I,Un),Bun.write(b,`${JSON.stringify(Qn,null,2)}
|
|
9304
|
+
`),Bun.write(Kn,_n)]),process.stdout.write(`\u{1F4DD} Source artifacts (${(performance.now()-l).toFixed(0)}ms)
|
|
9305
|
+
`);let _=relative(o,A).replace(/\\/g,"/"),Zn=_.startsWith(".")?_:`./${_}`,K=relative(o,w).replace(/\\/g,"/"),Xn=K.startsWith(".")?K:`./${K}`,he=await Bun.spawn([process.execPath,d,"generate","--config",Zn,"--output",Xn,"--yes"],{cwd:o,stdout:"inherit",stderr:"inherit"}).exited;if(he!==0)throw new Error(`better-auth generation failed with exit code ${he}`);process.stdout.write(`\u{1F510} Auth schema (${(performance.now()-l).toFixed(0)}ms)
|
|
9306
|
+
`),E.length>0&&(await Ra(w,E),process.stdout.write(`\u{1F527} Patched role type (${(performance.now()-l).toFixed(0)}ms)
|
|
9307
|
+
`));function Yn(x={}){return {compilerOptions:{lib:["es2024"],types:["@types/node","@cloudflare/workers-types/2023-07-01"],module:"es2022",target:"es2024",moduleResolution:"bundler",strictNullChecks:true,skipLibCheck:true,declaration:true,emitDeclarationOnly:true,noCheck:true,jsx:"react-jsx",paths:{"_generated/*":["./*"]},...x},include:["./*.ts","./client/*.ts"]}}let ye=resolve(n,"tsconfig.js.json");await Promise.all([Bun.write(ye,`${JSON.stringify(Yn({declaration:true,emitDeclarationOnly:false}),null,2)}
|
|
9266
9308
|
`)]),process.stdout.write(`\u{1F4C4} TS configs (${(performance.now()-l).toFixed(0)}ms)
|
|
9267
|
-
`);async function
|
|
9268
|
-
`);let N=await Bun.spawn([process.execPath,p,"-p",x],{cwd:
|
|
9269
|
-
`);async function
|
|
9270
|
-
`);let
|
|
9271
|
-
`);let
|
|
9309
|
+
`);async function er(x,$){process.stdout.write(`\u2699\uFE0F ${$}... (${(performance.now()-l).toFixed(0)}ms)
|
|
9310
|
+
`);let N=await Bun.spawn([process.execPath,p,"-p",x],{cwd:n,stdout:"inherit",stderr:"inherit"}).exited;if(N!==0)throw new Error(`tsc ${$} failed with exit code ${N}`)}await er(ye,"JS files"),process.stdout.write(`\u2705 JS + declarations (${(performance.now()-l).toFixed(0)}ms)
|
|
9311
|
+
`);async function be(x){let $=await readdir(x,{withFileTypes:true});for(let k of $){let N=join(x,k.name);if(k.isDirectory()){if(k.name==="node_modules"||k.name.startsWith("."))continue;await be(N);}else k.name.endsWith(".ts")&&!k.name.endsWith(".d.ts")&&await rm(N);}}await be(n),process.stdout.write(`\u{1F4E6} Cleaned .ts files (${(performance.now()-l).toFixed(0)}ms)
|
|
9312
|
+
`);let tr=n+"/";async function we(x){let $=await readdir(x,{withFileTypes:true});for(let k of $){let N=join(x,k.name);if(k.isDirectory()){if(k.name==="node_modules"||k.name.startsWith(".")||N===n)continue;await we(N);}else !N.startsWith(tr)&&(k.name.endsWith(".d.ts")||k.name.endsWith(".js"))&&await rm(N);}}await we(o),process.stdout.write(`\u{1F9F9} Cleanup (${(performance.now()-l).toFixed(0)}ms)
|
|
9313
|
+
`);let nr=resolve(o,"tsconfig.json");if(e.config.build&&existsSync(nr)){process.stdout.write(`\u2699\uFE0F Building project... (${(performance.now()-l).toFixed(0)}ms)
|
|
9272
9314
|
`);let $=await Bun.spawn([process.execPath,p,"--build"],{cwd:o,stdout:"inherit",stderr:"inherit"}).exited;if($!==0)throw new Error(`TypeScript build failed with exit code ${$}`);process.stdout.write(`\u2705 Build complete (${(performance.now()-l).toFixed(0)}ms)
|
|
9273
|
-
`);}}var
|
|
9274
|
-
`);return}process.stdout.write(`\u2705 Generated server/client in ${
|
|
9275
|
-
`);}async function
|
|
9276
|
-
`);}finally{r=false,a&&(a=false,await o());}};
|
|
9277
|
-
`),await o();}),process.stdout.write(`\u{1F440} Watching ${
|
|
9278
|
-
`);}async function
|
|
9315
|
+
`);}}var Mn=z.object({binding:z.string().min(1),databaseName:z.string().min(1),databaseId:z.string().min(1),previewDatabaseId:z.string().min(1).optional(),migrationsDir:z.string().min(1).optional()}).strict(),In=z.object({binding:z.string().min(1),id:z.string().min(1),previewId:z.string().min(1).optional()}).strict(),En=z.object({binding:z.string().min(1),bucketName:z.string().min(1),previewBucketName:z.string().min(1).optional(),jurisdiction:z.string().min(1).optional()}).strict(),Pn=z.object({enabled:z.boolean().optional(),binding:z.string().min(1).optional(),queue:z.string().min(1).optional()}).strict(),$a=z.object({enabled:z.boolean().optional(),binding:z.string().min(1).optional(),className:z.string().min(1).optional(),objectName:z.string().min(1).optional(),subscribePath:z.string().min(1).optional(),websocketPath:z.string().min(1).optional(),protocol:z.string().min(1).optional()}).strict(),Ca=z.object({scanDir:z.string().min(1),outDir:z.string().min(1),wranglerOutDir:z.string().min(1).optional(),wranglerOutPath:z.string().min(1).optional(),schema:z.array(z.string()).min(1),schemaDsl:z.object({entry:z.string().min(1),exportName:z.string().min(1).optional(),outFile:z.string().min(1).optional(),typesOutFile:z.string().min(1).optional(),zodOutFile:z.string().min(1).optional(),namingStrategy:z.literal("camelToSnake").optional()}).strict().optional(),database:z.union([Mn,z.array(Mn).min(1)]),kv:z.union([In,z.array(In)]).optional(),r2:z.union([En,z.array(En)]).optional(),auth:z.object({enabled:z.boolean(),basePath:z.string().min(1),options:z.custom(e=>typeof e=="object"&&e!==null),clientOptions:z.custom(e=>typeof e=="object"&&e!==null)}).strict(),scheduler:Pn.optional(),realtime:$a.optional(),wranglerOverrides:z.record(z.string(),z.unknown()).optional(),build:z.boolean().optional()}).strict();function On(e){return typeof e=="object"&&e!==null}function qa(e){let n=On(e.wranglerOverrides)?e.wranglerOverrides.scheduler:void 0,t=Pn.safeParse(n);return t.success?t.data:{}}function Fa(e){if(!On(e)||!("scheduler"in e))return e;let{scheduler:n,...t}=e;return t}function Ma(e){let t={...qa(e)??{},...e.scheduler??{}},r=e.realtime??{};return {...e,database:Array.isArray(e.database)?e.database:[e.database],kv:e.kv?Array.isArray(e.kv)?e.kv:[e.kv]:[],r2:e.r2?Array.isArray(e.r2)?e.r2:[e.r2]:[],scheduler:{enabled:t.enabled??true,binding:t.binding??"APPFLARE_SCHEDULER_QUEUE",queue:t.queue},realtime:{enabled:r.enabled??true,binding:r.binding??"APPFLARE_REALTIME",className:r.className??"AppflareRealtimeDurableObject",objectName:r.objectName??"global",subscribePath:r.subscribePath??"/realtime/subscribe",websocketPath:r.websocketPath??"/realtime/ws",protocol:r.protocol??"appflare.realtime.v1"},wranglerOverrides:Fa(e.wranglerOverrides),wranglerOutDir:e.wranglerOutDir??e.wranglerOutPath??e.outDir,build:e.build??true}}async function D(e){let n=isAbsolute(e??"")?e:resolve(process.cwd(),e??"appflare.config.ts"),t=dirname(n),o=(await import(pathToFileURL(n).href)).default,i=Ca.parse(o),s=Ma(i);return {configPath:n,configDir:t,scanDirAbs:resolve(t,s.scanDir),outDirAbs:resolve(t,s.outDir),wranglerOutDirAbs:resolve(t,s.wranglerOutDir),config:s}}function Oa(e){let n=e;for(;;){if(existsSync(resolve(n,"package.json")))return n;let t=dirname(n);if(t===n)return e;n=t;}}async function Q(e,n={}){let t=await D(e);if(n.build!==void 0&&(t.config.build=n.build),await Fn(t),t.wranglerOutDirAbs===t.outDirAbs){process.stdout.write(`\u2705 Generated artifacts in ${t.outDirAbs}
|
|
9316
|
+
`);return}process.stdout.write(`\u2705 Generated server/client in ${t.outDirAbs} and wrangler.json in ${t.wranglerOutDirAbs}
|
|
9317
|
+
`);}async function Dn(e,n={}){if(await Q(e,{build:n.build}),!n.watch)return;let t=await D(e),r=false,a=false,o=async()=>{if(r){a=true;return}r=true;try{await Q(e,{build:n.build});}catch(s){process.stderr.write(`\u274C Build failed: ${s.message}
|
|
9318
|
+
`);}finally{r=false,a&&(a=false,await o());}};Ia.watch(t.scanDirAbs,{ignoreInitial:true,ignored:s=>s.includes("/_generated/")||s.includes("/dist/")||s.includes("/out/")||s.includes("/node_modules/")||s.endsWith(".d.ts")}).on("all",async(s,u)=>{process.stdout.write(`\u{1F504} Change detected: ${u}
|
|
9319
|
+
`),await o();}),process.stdout.write(`\u{1F440} Watching ${t.scanDirAbs}
|
|
9320
|
+
`);}async function Vn(e,n={}){let t=await D(e),r=Oa(process.cwd());if([!!n.local,!!n.remote,!!n.preview].filter(Boolean).length>1)throw new Error("Only one of --local, --remote, or --preview can be set.");let o=resolve(t.outDirAbs,"drizzle.config.js"),i=process.platform==="win32"?"npx.cmd":"npx",u=await Bun.spawn([i,"drizzle-kit","generate","--config",o],{cwd:r,stdin:"inherit",stdout:"inherit",stderr:"inherit"}).exited;if(u!==0)throw new Error(`drizzle-kit generate failed with exit code ${u}`);let l=t.config.database[0].databaseName,c=[i,"wrangler","d1","migrations","apply",l];n.local?c.push("--local"):n.remote?c.push("--remote"):n.preview&&c.push("--preview");let d=await Bun.spawn(c,{cwd:t.configDir,stdin:"inherit",stdout:"inherit",stderr:"inherit"}).exited;if(d!==0)throw new Error(`wrangler d1 migrations apply failed with exit code ${d}`)}async function Bn(e,n={name:"",email:"",password:""}){let t=await D(e);if([!!n.local,!!n.remote].filter(Boolean).length>1)throw new Error("Only one of --local or --remote can be set.");let{hashPassword:a}=await import('better-auth/crypto'),o=await a(n.password),i=crypto.randomUUID(),s=crypto.randomUUID(),u=Date.now(),l=n.name.replace(/'/g,"''"),c=n.email.replace(/'/g,"''"),p=["INSERT INTO users (id, name, email, email_verified, created_at, updated_at, role, banned)",`VALUES ('${i}', '${l}', '${c}', 1, ${u}, ${u}, 'admin', 0);`,"INSERT INTO accounts (id, account_id, provider_id, user_id, password, created_at, updated_at)",`VALUES ('${s}', '${c}', 'credential', '${i}', '${o}', ${u}, ${u});`].join(" "),d=t.config.database[0].databaseName,v=[process.platform==="win32"?"npx.cmd":"npx","wrangler","d1","execute",d,`--command=${p}`];n.local?v.push("--local"):n.remote&&v.push("--remote");let w=await Bun.spawn(v,{cwd:t.configDir,stdin:"inherit",stdout:"inherit",stderr:"inherit"}).exited;if(w!==0)throw new Error(`Failed to add admin user. wrangler d1 execute exited with code ${w}`);console.log("\u2705 Admin user "+n.email+" created successfully!");}var P=new Command;P.name("appflare").description("Appflare compiler/bundler for Cloudflare-native backends and SDK generation").version("0.0.28");P.command("build").description("Generate server.ts, client.ts, auth.config.js, drizzle.config.js, and wrangler.json artifacts").option("-c, --config <path>","Path to appflare.config.ts","appflare.config.ts").option("--no-build","Skip TypeScript build step").action(async e=>{await Q(e.config,{build:e.build});});P.command("dev").description("Run generator in development mode").option("-c, --config <path>","Path to appflare.config.ts","appflare.config.ts").option("-w, --watch","Watch scanDir and regenerate on changes",false).option("--no-build","Skip TypeScript build step").action(async e=>{await Dn(e.config,{watch:e.watch,build:e.build});});P.command("migrate").description("Generate drizzle migration files from outDir/auth.schema.ts and apply them to the configured D1 database").option("-c, --config <path>","Path to appflare.config.ts","appflare.config.ts").option("--local","Execute commands/files against a local DB for use with wrangler dev",false).option("--remote","Execute commands/files against a remote DB for use with wrangler dev --remote",false).option("--preview","Execute commands/files against a preview D1 DB",false).action(async e=>{await Vn(e.config,{local:e.local,remote:e.remote,preview:e.preview});});P.command("add-admin").description("Add an admin user to the database").requiredOption("-n, --name <name>","Admin's display name").requiredOption("-e, --email <email>","Admin's email address").requiredOption("-p, --password <password>","Admin's password").option("-c, --config <path>","Path to appflare.config.ts","appflare.config.ts").option("--local","Execute command against a local DB for use with wrangler dev",false).option("--remote","Execute command against a remote DB for use with wrangler dev --remote",false).action(async e=>{await Bn(e.config,{name:e.name,email:e.email,password:e.password,local:e.local,remote:e.remote});});(async()=>{process.versions.bun||(console.error("Appflare CLI must be run with Bun."),process.exit(1)),await P.parseAsync(process.argv);})().catch(e=>{console.error(e),process.exit(1);});
|