appflare 0.2.35 → 0.2.37
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Documentation.md +8 -8
- package/cli/commands/index.ts +1 -1
- package/cli/generate.ts +24 -0
- package/cli/index.ts +1 -1
- package/cli/schema-compiler.ts +180 -2
- package/cli/templates/core/README.md +1 -1
- package/cli/templates/core/client/handlers/index.ts +7 -0
- package/cli/templates/handlers/generators/handlers.ts +2 -2
- package/cli/templates/handlers/generators/registration/modules/realtime/utils.ts +4 -10
- package/cli/templates/handlers/generators/types/context.ts +8 -2
- package/cli/templates/handlers/generators/types/query-definitions/filter-and-where-types.ts +6 -16
- package/cli/templates/handlers/generators/types/query-definitions/query-helper-functions.ts +216 -17
- package/cli/templates/handlers/index.ts +2 -1
- package/cli/templates/handlers/types.ts +2 -2
- package/dist/cli/index.js +502 -301
- package/dist/cli/index.mjs +502 -301
- package/dist/index.d.mts +81 -2
- package/dist/index.d.ts +81 -2
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
- package/schema.ts +229 -3
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 $a 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 f from'typescript';import {z}from'zod';function be(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 we(){return `import { createAuthClient, type BetterAuthClientOptions } from "better-auth/client";
|
|
61
61
|
import type {
|
|
62
62
|
AppflareAuth,
|
|
63
63
|
AppflareAuthTokenResolver,
|
|
@@ -166,8 +166,8 @@ 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 er(e){let t=e.replace(/[^A-Za-z0-9_]/g,"_");return /^[0-9]/.test(t)?`_${t}`:t||"_route"}function xe(e){return e.split(/[^A-Za-z0-9]+/).filter(Boolean).map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join("")}function tr(e){return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(e)?e:JSON.stringify(e)}function Te(e){let t={children:new Map};for(let n of e){let r=t;for(let a of n.segments){let o=r.children.get(a);o||(o={children:new Map},r.children.set(a,o)),r=o;}r.operation=n;}return t}function J(e,t=1){let n=" ".repeat(t),r=" ".repeat(t+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}${tr(i)}: ${J(s,t+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(`${n}}`),o.join(`
|
|
170
|
+
`)}function nr(e,t){if(e.kind!=="query"&&e.kind!=="mutation")return null;let n=e.clientSegments&&e.clientSegments.length>0?e.clientSegments:e.routePath.replace(/^\//,"").split("/").filter(Boolean).slice(1);if(n.length>=2&&n[n.length-1]===n[n.length-2]&&n.pop(),n.length===0)return null;let r=er(`op_${t}_${e.kind}_${n.join("_")}`);return {kind:e.kind,routePath:e.routePath,queryName:e.handlerName??n.join("/"),segments:n,importPath:e.clientImportPath,exportName:e.exportName,alias:r,schemaConst:`${r}Schema`,typeBase:`${xe(e.kind)}${xe(n.join("_"))}`}}function rr(e){let t=`${e.typeBase}Input`,n=`${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
172
|
): AppflareQueryRouteClient<typeof ${e.schemaConst}, ${n}> => {
|
|
173
173
|
const run: AppflareQueryRouteClient<typeof ${e.schemaConst}, ${n}>["run"] = async (
|
|
@@ -353,15 +353,15 @@ export function createAppflare<Options extends BetterAuthClientOptions = Inferre
|
|
|
353
353
|
schema: ${r},
|
|
354
354
|
run,
|
|
355
355
|
};
|
|
356
|
-
};`}function
|
|
357
|
-
`),o=t.map(
|
|
358
|
-
export type ${u} = z.input<typeof ${
|
|
359
|
-
export type ${
|
|
360
|
-
export const ${d} = ${
|
|
356
|
+
};`}function G(e){let t=e.map((l,u)=>nr(l,u)).filter(l=>l!==null),n=t.filter(l=>l.kind==="query"),r=t.filter(l=>l.kind==="mutation"),a=t.map(l=>`import { ${l.exportName} as ${l.alias} } from "${l.importPath}";`).join(`
|
|
357
|
+
`),o=t.map(l=>{let u=`${l.typeBase}Input`,p=`${l.typeBase}Output`,d=`${l.typeBase}Schema`;return `const ${l.schemaConst} = z.object(${l.alias}.definition.args);
|
|
358
|
+
export type ${u} = z.input<typeof ${l.schemaConst}>;
|
|
359
|
+
export type ${p} = Awaited<ReturnType<typeof ${l.alias}.definition.handler>>;
|
|
360
|
+
export const ${d} = ${l.schemaConst};`}).join(`
|
|
361
361
|
|
|
362
|
-
`),
|
|
362
|
+
`),i=t.map(l=>rr(l)).join(`
|
|
363
363
|
|
|
364
|
-
`),
|
|
364
|
+
`),s=J(Te(n)),c=J(Te(r));return `import { z } from "zod";
|
|
365
365
|
import type {
|
|
366
366
|
AppflareErrorMode,
|
|
367
367
|
AppflareRequestError,
|
|
@@ -703,7 +703,7 @@ async function requestRoute<TOutput>(
|
|
|
703
703
|
return body as TOutput;
|
|
704
704
|
}
|
|
705
705
|
|
|
706
|
-
${
|
|
706
|
+
${i}
|
|
707
707
|
|
|
708
708
|
export function createQueriesClient(
|
|
709
709
|
endpoint: string,
|
|
@@ -718,7 +718,7 @@ export function createQueriesClient(
|
|
|
718
718
|
options,
|
|
719
719
|
};
|
|
720
720
|
|
|
721
|
-
return ${
|
|
721
|
+
return ${s} as const;
|
|
722
722
|
}
|
|
723
723
|
|
|
724
724
|
export function createMutationsClient(
|
|
@@ -732,16 +732,16 @@ export function createMutationsClient(
|
|
|
732
732
|
options,
|
|
733
733
|
};
|
|
734
734
|
|
|
735
|
-
return ${
|
|
735
|
+
return ${c} 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 ve(){return `export * from "./types";
|
|
741
741
|
export * from "./appflare";
|
|
742
742
|
export * from "./storage";
|
|
743
743
|
export * from "./handlers";
|
|
744
|
-
`}function
|
|
744
|
+
`}function Re(){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 ke(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 Se(e,t){return [{relativePath:"client/index.ts",source:ve()},{relativePath:"client/types.ts",source:ke(e)},{relativePath:"client/storage.ts",source:Re()},{relativePath:"client/handlers.ts",source:G(t)},{relativePath:"client/appflare.ts",source:we()}]}function Ae(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 Ne(){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 $e(){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 Ce(){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 qe(){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 Me(){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 Fe(){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 Ie(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 Pe(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
|
-
${
|
|
1483
|
+
${$e()}
|
|
1484
1484
|
|
|
1485
|
-
${
|
|
1485
|
+
${Ne()}
|
|
1486
1486
|
|
|
1487
|
-
${
|
|
1487
|
+
${Ce()}
|
|
1488
1488
|
|
|
1489
|
-
${
|
|
1489
|
+
${qe()}
|
|
1490
1490
|
|
|
1491
|
-
${
|
|
1491
|
+
${Me()}
|
|
1492
1492
|
|
|
1493
|
-
${
|
|
1493
|
+
${Fe()}
|
|
1494
1494
|
|
|
1495
|
-
${
|
|
1496
|
-
`}function
|
|
1495
|
+
${Ie(e)}
|
|
1496
|
+
`}function Oe(){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 Ee(){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
|
+
${Oe()}
|
|
1545
|
+
`}function De(){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 je(){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>>;
|
|
@@ -1665,16 +1665,12 @@ type GeoWithinOperand = {
|
|
|
1665
1665
|
$geometry: GeoPoint | GeoCoordinates;
|
|
1666
1666
|
latitudeField?: string;
|
|
1667
1667
|
longitudeField?: string;
|
|
1668
|
-
|
|
1669
|
-
|
|
1668
|
+
minDistance?: number;
|
|
1669
|
+
maxDistance?: number;
|
|
1670
1670
|
gt?: number;
|
|
1671
1671
|
gte?: number;
|
|
1672
1672
|
lt?: number;
|
|
1673
1673
|
lte?: number;
|
|
1674
|
-
$gt?: number;
|
|
1675
|
-
$gte?: number;
|
|
1676
|
-
$lt?: number;
|
|
1677
|
-
$lte?: number;
|
|
1678
1674
|
};
|
|
1679
1675
|
|
|
1680
1676
|
type GeoWithinOperandForField<TFieldKey extends string> = Omit<
|
|
@@ -1687,25 +1683,20 @@ type GeoWithinOperandForField<TFieldKey extends string> = Omit<
|
|
|
1687
1683
|
|
|
1688
1684
|
type FieldOperators<T, TFieldKey extends string = string> = {
|
|
1689
1685
|
eq?: Friendly<NonNil<T>>;
|
|
1690
|
-
$eq?: Friendly<NonNil<T>>;
|
|
1691
1686
|
ne?: Friendly<NonNil<T>>;
|
|
1692
|
-
$ne?: Friendly<NonNil<T>>;
|
|
1693
1687
|
in?: ReadonlyArray<Friendly<NonNil<T>>>;
|
|
1694
|
-
$in?: ReadonlyArray<Friendly<NonNil<T>>>;
|
|
1695
1688
|
nin?: ReadonlyArray<Friendly<NonNil<T>>>;
|
|
1696
|
-
$nin?: ReadonlyArray<Friendly<NonNil<T>>>;
|
|
1697
1689
|
gt?: Comparable<T>;
|
|
1698
|
-
$gt?: Comparable<T>;
|
|
1699
1690
|
gte?: Comparable<T>;
|
|
1700
|
-
$gte?: Comparable<T>;
|
|
1701
1691
|
lt?: Comparable<T>;
|
|
1702
|
-
$lt?: Comparable<T>;
|
|
1703
1692
|
lte?: Comparable<T>;
|
|
1704
|
-
$lte?: Comparable<T>;
|
|
1705
1693
|
exists?: boolean;
|
|
1706
1694
|
regex?: RegexOperand<T>;
|
|
1707
|
-
|
|
1695
|
+
options?: string;
|
|
1708
1696
|
geoWithin?: GeoWithinOperandForField<TFieldKey>;
|
|
1697
|
+
includes?: T extends ReadonlyArray<infer E> ? ReadonlyArray<E> : never;
|
|
1698
|
+
includesAny?: T extends ReadonlyArray<infer E> ? ReadonlyArray<E> : never;
|
|
1699
|
+
length?: T extends ReadonlyArray<unknown> ? number : never;
|
|
1709
1700
|
};
|
|
1710
1701
|
|
|
1711
1702
|
type WhereFieldValue<T, TFieldKey extends string> =
|
|
@@ -1718,7 +1709,6 @@ type RelationWhereInput<TModel extends Record<string, unknown>, TName extends Ta
|
|
|
1718
1709
|
| (TModel[K] extends Record<string, unknown> ? RelationWhereInput<TModel[K]> : never);
|
|
1719
1710
|
} & {
|
|
1720
1711
|
geoWithin?: GeoWithinOperandForField<Extract<keyof TModel, string>>;
|
|
1721
|
-
$geoWithin?: GeoWithinOperandForField<Extract<keyof TModel, string>>;
|
|
1722
1712
|
} & (TName extends TableName ? {
|
|
1723
1713
|
[TRelation in keyof NativeFindManyWith<TName>]?: NativeFindManyWith<TName>[TRelation] extends infer TRelationConfig
|
|
1724
1714
|
? TRelationConfig extends Record<string, unknown>
|
|
@@ -1923,7 +1913,7 @@ export type QueryDeleteArgs<TName extends TableName> = {
|
|
|
1923
1913
|
where?: WhereInput<TableModel<TName>, TName>;
|
|
1924
1914
|
limit?: number;
|
|
1925
1915
|
};
|
|
1926
|
-
`}function
|
|
1916
|
+
`}function Ve(){return `type AggregateWithInput<TName extends TableName> =
|
|
1927
1917
|
QueryWithInput<TName, NativeFindManyWith<TName>>;
|
|
1928
1918
|
|
|
1929
1919
|
type NumericFieldKey<TName extends TableName> = NumericModelFieldKey<
|
|
@@ -2055,16 +2045,210 @@ export type DbMutationEvent = {
|
|
|
2055
2045
|
export type QueryDbOptions = {
|
|
2056
2046
|
onMutation?: (event: DbMutationEvent) => void;
|
|
2057
2047
|
};
|
|
2058
|
-
`}function
|
|
2048
|
+
`}function Be(){return `function isRecord(value: unknown): value is Record<string, unknown> {
|
|
2059
2049
|
return typeof value === "object" && value !== null;
|
|
2060
2050
|
}
|
|
2061
2051
|
|
|
2062
2052
|
function readOperatorValue(record: Record<string, unknown>, key: string): unknown {
|
|
2063
|
-
|
|
2064
|
-
|
|
2053
|
+
return record[key];
|
|
2054
|
+
}
|
|
2055
|
+
|
|
2056
|
+
function getJsonColumnsMap(): Record<string, Record<string, { shape: unknown }>> {
|
|
2057
|
+
const rawValue = (mergedSchema as Record<string, unknown>)[
|
|
2058
|
+
"__appflareJsonColumns"
|
|
2059
|
+
];
|
|
2060
|
+
if (!isRecord(rawValue)) {
|
|
2061
|
+
return {};
|
|
2065
2062
|
}
|
|
2066
|
-
const
|
|
2067
|
-
|
|
2063
|
+
const map: Record<string, Record<string, { shape: unknown }>> = {};
|
|
2064
|
+
for (const [tableName, tableValue] of Object.entries(rawValue)) {
|
|
2065
|
+
if (isRecord(tableValue)) {
|
|
2066
|
+
map[tableName] = tableValue as Record<string, { shape: unknown }>;
|
|
2067
|
+
}
|
|
2068
|
+
}
|
|
2069
|
+
return map;
|
|
2070
|
+
}
|
|
2071
|
+
|
|
2072
|
+
const jsonColumnsMap = getJsonColumnsMap();
|
|
2073
|
+
|
|
2074
|
+
function getJsonColumnShape(
|
|
2075
|
+
tableName: string | undefined,
|
|
2076
|
+
fieldName: string,
|
|
2077
|
+
): { kind: string } | null {
|
|
2078
|
+
if (!tableName) return null;
|
|
2079
|
+
const tableCols = jsonColumnsMap[tableName];
|
|
2080
|
+
if (!tableCols) return null;
|
|
2081
|
+
const col = tableCols[fieldName];
|
|
2082
|
+
if (!col || !isRecord(col.shape)) return null;
|
|
2083
|
+
return col.shape as { kind: string };
|
|
2084
|
+
}
|
|
2085
|
+
|
|
2086
|
+
function buildJsonFieldFilter(
|
|
2087
|
+
fieldName: string,
|
|
2088
|
+
field: unknown,
|
|
2089
|
+
value: unknown,
|
|
2090
|
+
tableName: string | undefined,
|
|
2091
|
+
): SQL | undefined {
|
|
2092
|
+
const shape = getJsonColumnShape(tableName, fieldName);
|
|
2093
|
+
if (!shape) return undefined;
|
|
2094
|
+
|
|
2095
|
+
if (shape.kind === "array") {
|
|
2096
|
+
return buildJsonArrayFilter(fieldName, field, value);
|
|
2097
|
+
}
|
|
2098
|
+
if (shape.kind === "object") {
|
|
2099
|
+
return buildJsonObjectFilter(fieldName, field, value);
|
|
2100
|
+
}
|
|
2101
|
+
return undefined;
|
|
2102
|
+
}
|
|
2103
|
+
|
|
2104
|
+
function buildJsonArrayFilter(
|
|
2105
|
+
fieldName: string,
|
|
2106
|
+
field: unknown,
|
|
2107
|
+
value: unknown,
|
|
2108
|
+
): SQL | undefined {
|
|
2109
|
+
if (!isRecord(value) || value instanceof Date || Array.isArray(value)) {
|
|
2110
|
+
return sql\`json_extract(\${field as never}, '$') = json(\${JSON.stringify(value)})\`;
|
|
2111
|
+
}
|
|
2112
|
+
|
|
2113
|
+
const filters: SQL[] = [];
|
|
2114
|
+
|
|
2115
|
+
const includesValue = readOperatorValue(value, "includes");
|
|
2116
|
+
if (Array.isArray(includesValue) && includesValue.length > 0) {
|
|
2117
|
+
const conditions = includesValue.map((v) =>
|
|
2118
|
+
sql\`EXISTS (SELECT 1 FROM json_each(\${field as never}) j WHERE j.value = \${v})\`,
|
|
2119
|
+
);
|
|
2120
|
+
filters.push(and(...conditions));
|
|
2121
|
+
}
|
|
2122
|
+
|
|
2123
|
+
const includesAnyValue = readOperatorValue(value, "includesAny");
|
|
2124
|
+
if (Array.isArray(includesAnyValue) && includesAnyValue.length > 0) {
|
|
2125
|
+
const conditions = includesAnyValue.map((v) =>
|
|
2126
|
+
sql\`EXISTS (SELECT 1 FROM json_each(\${field as never}) j WHERE j.value = \${v})\`,
|
|
2127
|
+
);
|
|
2128
|
+
filters.push(sql\`(\${sql.join(conditions, sql\` OR \`)})\`);
|
|
2129
|
+
}
|
|
2130
|
+
|
|
2131
|
+
const lengthValue = readOperatorValue(value, "length");
|
|
2132
|
+
if (lengthValue !== undefined) {
|
|
2133
|
+
filters.push(sql\`json_array_length(\${field as never}) = \${lengthValue}\`);
|
|
2134
|
+
}
|
|
2135
|
+
|
|
2136
|
+
const eqValue = readOperatorValue(value, "eq");
|
|
2137
|
+
if (eqValue !== undefined) {
|
|
2138
|
+
filters.push(sql\`json_extract(\${field as never}, '$') = json(\${JSON.stringify(eqValue)})\`);
|
|
2139
|
+
}
|
|
2140
|
+
|
|
2141
|
+
const neValue = readOperatorValue(value, "ne");
|
|
2142
|
+
if (neValue !== undefined) {
|
|
2143
|
+
filters.push(sql\`json_extract(\${field as never}, '$') != json(\${JSON.stringify(neValue)})\`);
|
|
2144
|
+
}
|
|
2145
|
+
|
|
2146
|
+
if (filters.length === 0) {
|
|
2147
|
+
return undefined;
|
|
2148
|
+
}
|
|
2149
|
+
if (filters.length === 1) return filters[0];
|
|
2150
|
+
return and(...filters);
|
|
2151
|
+
}
|
|
2152
|
+
|
|
2153
|
+
function buildJsonObjectFilter(
|
|
2154
|
+
fieldName: string,
|
|
2155
|
+
field: unknown,
|
|
2156
|
+
value: unknown,
|
|
2157
|
+
): SQL | undefined {
|
|
2158
|
+
if (!isRecord(value) || value instanceof Date || Array.isArray(value)) {
|
|
2159
|
+
return sql\`json_extract(\${field as never}, '$') = json(\${JSON.stringify(value)})\`;
|
|
2160
|
+
}
|
|
2161
|
+
|
|
2162
|
+
const filters: SQL[] = [];
|
|
2163
|
+
|
|
2164
|
+
for (const [key, opValue] of Object.entries(value)) {
|
|
2165
|
+
if (key === "eq") {
|
|
2166
|
+
filters.push(sql\`json_extract(\${field as never}, '$') = json(\${JSON.stringify(opValue)})\`);
|
|
2167
|
+
continue;
|
|
2168
|
+
}
|
|
2169
|
+
if (key === "ne") {
|
|
2170
|
+
filters.push(sql\`json_extract(\${field as never}, '$') != json(\${JSON.stringify(opValue)})\`);
|
|
2171
|
+
continue;
|
|
2172
|
+
}
|
|
2173
|
+
if (key === "exists") {
|
|
2174
|
+
filters.push(
|
|
2175
|
+
opValue
|
|
2176
|
+
? sql\`json_extract(\${field as never}, '$') IS NOT NULL\`
|
|
2177
|
+
: sql\`json_extract(\${field as never}, '$') IS NULL\`,
|
|
2178
|
+
);
|
|
2179
|
+
continue;
|
|
2180
|
+
}
|
|
2181
|
+
|
|
2182
|
+
const nestedFilters = buildJsonObjectPathFilter(field, key, opValue);
|
|
2183
|
+
if (nestedFilters) {
|
|
2184
|
+
filters.push(nestedFilters);
|
|
2185
|
+
}
|
|
2186
|
+
}
|
|
2187
|
+
|
|
2188
|
+
if (filters.length === 0) return undefined;
|
|
2189
|
+
if (filters.length === 1) return filters[0];
|
|
2190
|
+
return and(...filters);
|
|
2191
|
+
}
|
|
2192
|
+
|
|
2193
|
+
function buildJsonObjectPathFilter(
|
|
2194
|
+
field: unknown,
|
|
2195
|
+
path: string,
|
|
2196
|
+
opValue: unknown,
|
|
2197
|
+
): SQL | undefined {
|
|
2198
|
+
const jsonPath = '$.' + path;
|
|
2199
|
+
if (!isRecord(opValue) || opValue instanceof Date || Array.isArray(opValue)) {
|
|
2200
|
+
return sql\`json_extract(\${field as never}, \${jsonPath}) = \${opValue}\`;
|
|
2201
|
+
}
|
|
2202
|
+
|
|
2203
|
+
const filters: SQL[] = [];
|
|
2204
|
+
|
|
2205
|
+
const eqVal = readOperatorValue(opValue, "eq");
|
|
2206
|
+
if (eqVal !== undefined) {
|
|
2207
|
+
filters.push(sql\`json_extract(\${field as never}, \${jsonPath}) = \${eqVal}\`);
|
|
2208
|
+
}
|
|
2209
|
+
|
|
2210
|
+
const neVal = readOperatorValue(opValue, "ne");
|
|
2211
|
+
if (neVal !== undefined) {
|
|
2212
|
+
filters.push(sql\`json_extract(\${field as never}, \${jsonPath}) != \${neVal}\`);
|
|
2213
|
+
}
|
|
2214
|
+
|
|
2215
|
+
const gtVal = readOperatorValue(opValue, "gt");
|
|
2216
|
+
if (gtVal !== undefined) {
|
|
2217
|
+
filters.push(sql\`json_extract(\${field as never}, \${jsonPath}) > \${gtVal}\`);
|
|
2218
|
+
}
|
|
2219
|
+
|
|
2220
|
+
const gteVal = readOperatorValue(opValue, "gte");
|
|
2221
|
+
if (gteVal !== undefined) {
|
|
2222
|
+
filters.push(sql\`json_extract(\${field as never}, \${jsonPath}) >= \${gteVal}\`);
|
|
2223
|
+
}
|
|
2224
|
+
|
|
2225
|
+
const ltVal = readOperatorValue(opValue, "lt");
|
|
2226
|
+
if (ltVal !== undefined) {
|
|
2227
|
+
filters.push(sql\`json_extract(\${field as never}, \${jsonPath}) < \${ltVal}\`);
|
|
2228
|
+
}
|
|
2229
|
+
|
|
2230
|
+
const lteVal = readOperatorValue(opValue, "lte");
|
|
2231
|
+
if (lteVal !== undefined) {
|
|
2232
|
+
filters.push(sql\`json_extract(\${field as never}, \${jsonPath}) <= \${lteVal}\`);
|
|
2233
|
+
}
|
|
2234
|
+
|
|
2235
|
+
const inVal = readOperatorValue(opValue, "in");
|
|
2236
|
+
if (Array.isArray(inVal) && inVal.length > 0) {
|
|
2237
|
+
filters.push(sql\`json_extract(\${field as never}, \${jsonPath}) IN (\${sql.join(inVal.map((v) => sql\`\${v}\`), sql\`, \`)})\`);
|
|
2238
|
+
}
|
|
2239
|
+
|
|
2240
|
+
const existsVal = readOperatorValue(opValue, "exists");
|
|
2241
|
+
if (typeof existsVal === "boolean") {
|
|
2242
|
+
filters.push(
|
|
2243
|
+
existsVal
|
|
2244
|
+
? sql\`json_extract(\${field as never}, \${jsonPath}) IS NOT NULL\`
|
|
2245
|
+
: sql\`json_extract(\${field as never}, \${jsonPath}) IS NULL\`,
|
|
2246
|
+
);
|
|
2247
|
+
}
|
|
2248
|
+
|
|
2249
|
+
if (filters.length === 0) return undefined;
|
|
2250
|
+
if (filters.length === 1) return filters[0];
|
|
2251
|
+
return and(...filters);
|
|
2068
2252
|
}
|
|
2069
2253
|
|
|
2070
2254
|
function normalizeGeoPoint(
|
|
@@ -2146,17 +2330,13 @@ function createGeoDistanceFilter(
|
|
|
2146
2330
|
)\`;
|
|
2147
2331
|
|
|
2148
2332
|
const minDistance =
|
|
2149
|
-
operand
|
|
2333
|
+
operand.minDistance ??
|
|
2150
2334
|
operand.gte ??
|
|
2151
|
-
operand
|
|
2152
|
-
operand.gt ??
|
|
2153
|
-
operand.$gt;
|
|
2335
|
+
operand.gt;
|
|
2154
2336
|
const maxDistance =
|
|
2155
|
-
operand
|
|
2337
|
+
operand.maxDistance ??
|
|
2156
2338
|
operand.lte ??
|
|
2157
|
-
operand
|
|
2158
|
-
operand.lt ??
|
|
2159
|
-
operand.$lt;
|
|
2339
|
+
operand.lt;
|
|
2160
2340
|
|
|
2161
2341
|
const filters: SQL[] = [];
|
|
2162
2342
|
if (typeof minDistance === "number") {
|
|
@@ -2182,7 +2362,18 @@ function buildFieldFilter(
|
|
|
2182
2362
|
field: unknown,
|
|
2183
2363
|
value: unknown,
|
|
2184
2364
|
fields: Record<string, unknown>,
|
|
2365
|
+
tableName?: string,
|
|
2185
2366
|
): SQL | undefined {
|
|
2367
|
+
const jsonFilter = buildJsonFieldFilter(fieldName, field, value, tableName);
|
|
2368
|
+
if (jsonFilter) return jsonFilter;
|
|
2369
|
+
|
|
2370
|
+
const isArrayColumn = isRecord(value) && !Array.isArray(value) && !(value instanceof Date) &&
|
|
2371
|
+
("includes" in value || "includesAny" in value || "length" in value);
|
|
2372
|
+
if (isArrayColumn) {
|
|
2373
|
+
const arrayFilter = buildJsonArrayFilter(fieldName, field, value);
|
|
2374
|
+
if (arrayFilter) return arrayFilter;
|
|
2375
|
+
}
|
|
2376
|
+
|
|
2186
2377
|
if (!isRecord(value) || value instanceof Date || Array.isArray(value)) {
|
|
2187
2378
|
return eq(field as never, value as never);
|
|
2188
2379
|
}
|
|
@@ -2293,9 +2484,7 @@ function buildWhereFilterFromFields(
|
|
|
2293
2484
|
|
|
2294
2485
|
const topLevelGeoWithin = isRecord(where.geoWithin)
|
|
2295
2486
|
? (where.geoWithin as GeoWithinOperand)
|
|
2296
|
-
:
|
|
2297
|
-
? (where.$geoWithin as GeoWithinOperand)
|
|
2298
|
-
: undefined;
|
|
2487
|
+
: undefined;
|
|
2299
2488
|
|
|
2300
2489
|
if (topLevelGeoWithin) {
|
|
2301
2490
|
const geoFilter = createGeoDistanceFilter(topLevelGeoWithin, fields, tableName);
|
|
@@ -2305,7 +2494,7 @@ function buildWhereFilterFromFields(
|
|
|
2305
2494
|
}
|
|
2306
2495
|
|
|
2307
2496
|
for (const [fieldName, fieldValue] of Object.entries(where)) {
|
|
2308
|
-
if (fieldName === "geoWithin"
|
|
2497
|
+
if (fieldName === "geoWithin") {
|
|
2309
2498
|
continue;
|
|
2310
2499
|
}
|
|
2311
2500
|
|
|
@@ -2333,7 +2522,7 @@ function buildWhereFilterFromFields(
|
|
|
2333
2522
|
continue;
|
|
2334
2523
|
}
|
|
2335
2524
|
|
|
2336
|
-
const filter = buildFieldFilter(fieldName, field, fieldValue, fields);
|
|
2525
|
+
const filter = buildFieldFilter(fieldName, field, fieldValue, fields, tableName);
|
|
2337
2526
|
if (filter) {
|
|
2338
2527
|
filters.push(filter);
|
|
2339
2528
|
}
|
|
@@ -3155,7 +3344,7 @@ function inferConflictTarget(table: unknown): string[] {
|
|
|
3155
3344
|
|
|
3156
3345
|
return [];
|
|
3157
3346
|
}
|
|
3158
|
-
`}function
|
|
3347
|
+
`}function We(){return `const mergedSchema = {
|
|
3159
3348
|
...authSchema,
|
|
3160
3349
|
...schema,
|
|
3161
3350
|
};
|
|
@@ -3430,9 +3619,9 @@ type TableFindFirstResult<
|
|
|
3430
3619
|
type TableInsertModel<TName extends TableName> = InferInsertModel<
|
|
3431
3620
|
(typeof mergedSchema)[TName]
|
|
3432
3621
|
>;
|
|
3433
|
-
`}function
|
|
3622
|
+
`}function He(){return [We(),je(),Ve(),Be()].join(`
|
|
3434
3623
|
|
|
3435
|
-
`)}function
|
|
3624
|
+
`)}function Le(){return ` count: async (args?: QueryCountArgs<TableName>) => {
|
|
3436
3625
|
const withValue = args?.with;
|
|
3437
3626
|
const pathSegments = args?.field
|
|
3438
3627
|
? splitAggregateFieldPath(String(args.field))
|
|
@@ -3603,7 +3792,7 @@ type TableInsertModel<TName extends TableName> = InferInsertModel<
|
|
|
3603
3792
|
},
|
|
3604
3793
|
}) as AppflareQueryDb;
|
|
3605
3794
|
}
|
|
3606
|
-
`}function
|
|
3795
|
+
`}function ze(){return `export class AppflareHandledError extends Error {
|
|
3607
3796
|
public readonly status: number;
|
|
3608
3797
|
public readonly payload: unknown;
|
|
3609
3798
|
|
|
@@ -3613,7 +3802,7 @@ type TableInsertModel<TName extends TableName> = InferInsertModel<
|
|
|
3613
3802
|
this.payload = payload;
|
|
3614
3803
|
}
|
|
3615
3804
|
}
|
|
3616
|
-
`}function
|
|
3805
|
+
`}function Ue(){return ` findMany: (args?: Record<string, unknown>) => {
|
|
3617
3806
|
const where = isRecord(args?.where)
|
|
3618
3807
|
? (args?.where as Record<string, unknown>)
|
|
3619
3808
|
: undefined;
|
|
@@ -3767,7 +3956,7 @@ type TableInsertModel<TName extends TableName> = InferInsertModel<
|
|
|
3767
3956
|
);
|
|
3768
3957
|
});
|
|
3769
3958
|
},
|
|
3770
|
-
`}function
|
|
3959
|
+
`}function Qe(){return `export function createQueryDb(
|
|
3771
3960
|
$db: AppflareDb,
|
|
3772
3961
|
options?: QueryDbOptions,
|
|
3773
3962
|
): AppflareQueryDb {
|
|
@@ -3809,7 +3998,7 @@ type TableInsertModel<TName extends TableName> = InferInsertModel<
|
|
|
3809
3998
|
};
|
|
3810
3999
|
|
|
3811
4000
|
const tableApi = {
|
|
3812
|
-
`}function
|
|
4001
|
+
`}function _e(){return ` insert: async <TArgs extends QueryInsertArgs<TableName>>(args: TArgs) => {
|
|
3813
4002
|
const transaction = ($db as any).transaction;
|
|
3814
4003
|
|
|
3815
4004
|
const valuesArray = Array.isArray(args.values)
|
|
@@ -4503,11 +4692,12 @@ type TableInsertModel<TName extends TableName> = InferInsertModel<
|
|
|
4503
4692
|
);
|
|
4504
4693
|
return rows;
|
|
4505
4694
|
},
|
|
4506
|
-
`}function
|
|
4695
|
+
`}function Ke(){return [Qe(),Ue(),_e(),Le(),ze()].join(`
|
|
4507
4696
|
|
|
4508
|
-
`)}function
|
|
4697
|
+
`)}function Je(e=[]){return `type AuthSession = typeof auth.$Infer.Session;
|
|
4509
4698
|
type AuthAdapter = Awaited<typeof auth.$context>["internalAdapter"];
|
|
4510
|
-
type
|
|
4699
|
+
${e.length>0?`type UserRole = ${e.map(n=>`"${n}"`).join(" | ")};
|
|
4700
|
+
type User = Omit<AuthSession['user'], 'role'> & { role: UserRole };`:"type User = AuthSession['user']"}
|
|
4511
4701
|
type Session = AuthSession['session']
|
|
4512
4702
|
|
|
4513
4703
|
export type StoragePutArgs = {
|
|
@@ -4594,7 +4784,7 @@ export type AppflareContext = {
|
|
|
4594
4784
|
storage: AppflareStorage;
|
|
4595
4785
|
error: (status: number, message: string, details?: unknown) => never;
|
|
4596
4786
|
};
|
|
4597
|
-
`}function
|
|
4787
|
+
`}function Ge(){return `type InferOperationArgs<TShape extends ZodRawShape> = z.output<z.ZodObject<TShape>>;
|
|
4598
4788
|
|
|
4599
4789
|
export type SchedulerEnqueueOptions = {
|
|
4600
4790
|
delaySeconds?: number;
|
|
@@ -4726,20 +4916,20 @@ export function cron(definition: CronDefinition): RegisteredCron {
|
|
|
4726
4916
|
definition,
|
|
4727
4917
|
};
|
|
4728
4918
|
}
|
|
4729
|
-
`}function
|
|
4919
|
+
`}function Ze(e=[]){return [De(),He(),Ke(),Je(e),Ge()].join(`
|
|
4730
4920
|
|
|
4731
|
-
`)}function
|
|
4921
|
+
`)}function Ye(e,t=[]){return `import type { Context } from "hono";
|
|
4732
4922
|
import type { D1Database } from "@cloudflare/workers-types";
|
|
4733
4923
|
import { drizzle } from "drizzle-orm/d1";
|
|
4734
4924
|
import { z, type ZodRawShape } from "zod";
|
|
4735
4925
|
import * as authSchema from "./auth.schema";
|
|
4736
4926
|
import * as schema from "${e}";
|
|
4737
4927
|
|
|
4738
|
-
${
|
|
4739
|
-
`}function
|
|
4740
|
-
`)}function
|
|
4741
|
-
`)}function
|
|
4742
|
-
`)}function
|
|
4928
|
+
${Ze(t)}
|
|
4929
|
+
`}function ar(e){let t=e.replace(/[^A-Za-z0-9_]/g,"_");return /^[0-9]/.test(t)?`_${t}`:t}function or(e,t){let n=e.routePath.replace(/^\//,"").replace(/\//g,"_");return ar(`op_${t}_${n}`)}function ir(e){return e.map((t,n)=>({operation:t,index:n,alias:or(t,n)}))}function sr(e){return e.map(({operation:t,alias:n})=>`import { ${t.exportName} as ${n} } from "${t.importPath}";`).join(`
|
|
4930
|
+
`)}function lr(e){return e.filter(({operation:t})=>t.kind==="query"||t.kind==="mutation").map(({alias:t})=>`const ${`${t}Schema`} = z.object(${t}.definition.args);`).join(`
|
|
4931
|
+
`)}function ur(e){return e.filter(({operation:t})=>t.kind==="scheduler").map(({alias:t})=>`const ${`${t}SchedulerSchema`} = ${t}.definition.args ? z.object(${t}.definition.args) : z.undefined();`).join(`
|
|
4932
|
+
`)}function cr(e){return e.filter(({operation:t})=>t.kind==="query").map(({operation:t,alias:n})=>{let r=`${n}Schema`;return `
|
|
4743
4933
|
app.get(
|
|
4744
4934
|
"${t.routePath}",
|
|
4745
4935
|
sValidator("query", ${r}),
|
|
@@ -4752,7 +4942,7 @@ ${Ue()}
|
|
|
4752
4942
|
}
|
|
4753
4943
|
},
|
|
4754
4944
|
);`}).join(`
|
|
4755
|
-
`)}function
|
|
4945
|
+
`)}function dr(e){return e.filter(({operation:t})=>t.kind==="mutation").map(({operation:t,alias:n})=>{let r=`${n}Schema`;return `
|
|
4756
4946
|
app.post(
|
|
4757
4947
|
"${t.routePath}",
|
|
4758
4948
|
sValidator("json", ${r}),
|
|
@@ -4767,26 +4957,26 @@ ${Ue()}
|
|
|
4767
4957
|
}
|
|
4768
4958
|
},
|
|
4769
4959
|
);`}).join(`
|
|
4770
|
-
`)}function
|
|
4960
|
+
`)}function pr(e){return e.filter(({operation:t})=>t.kind==="query").map(({operation:t,alias:n})=>{let r=`${n}Schema`,a=t.handlerName??t.routePath;return `
|
|
4771
4961
|
${JSON.stringify(a)}: {
|
|
4772
4962
|
definition: ${n}.definition,
|
|
4773
4963
|
schema: ${r},
|
|
4774
4964
|
},`}).join(`
|
|
4775
|
-
`)}function
|
|
4965
|
+
`)}function mr(e){return e.filter(({operation:t})=>t.kind==="scheduler").map(({operation:t,alias:n})=>{let r=`${n}SchedulerSchema`,a=t.taskName??`${t.routePath}`;return `
|
|
4776
4966
|
${JSON.stringify(a)}: {
|
|
4777
4967
|
definition: ${n}.definition,
|
|
4778
4968
|
schema: ${r},
|
|
4779
4969
|
},`}).join(`
|
|
4780
|
-
`)}function
|
|
4781
|
-
`)}function
|
|
4970
|
+
`)}function gr(e){return e.filter(({operation:t})=>t.kind==="scheduler").map(({operation:t,alias:n})=>{let r=t.taskName??`${t.routePath}`;return ` ${JSON.stringify(r)}: Parameters<typeof ${n}.definition.handler>[1];`}).join(`
|
|
4971
|
+
`)}function fr(e){return e.filter(({operation:t})=>t.kind==="cron").map(({operation:t,alias:n})=>{let r=t.taskName??`${t.routePath}`,a=t.cronTriggers??[];return `
|
|
4782
4972
|
{
|
|
4783
4973
|
taskName: ${JSON.stringify(r)},
|
|
4784
4974
|
cronTriggers: ${JSON.stringify(a)},
|
|
4785
4975
|
definition: ${n}.definition,
|
|
4786
4976
|
},`}).join(`
|
|
4787
|
-
`)}function
|
|
4977
|
+
`)}function hr(e){return e.filter(({operation:t})=>t.kind==="storage").map(({alias:t})=>`
|
|
4788
4978
|
${t}.definition.handler,`).join(`
|
|
4789
|
-
`)}function
|
|
4979
|
+
`)}function Xe(e){let t=ir(e);return {imports:sr(t),operationSchemas:lr(t),schedulerSchemas:ur(t),queryRoutes:cr(t),mutationRoutes:dr(t),queryRegistryEntries:pr(t),schedulerEntries:mr(t),schedulerPayloadMapEntries:gr(t),cronEntries:fr(t),storageHandlersEntries:hr(t)}}var et=`
|
|
4790
4980
|
function getRealtimeStub(
|
|
4791
4981
|
env: Record<string, unknown>,
|
|
4792
4982
|
options: RegisterHandlersOptions,
|
|
@@ -4860,7 +5050,7 @@ function buildRealtimeWsUrl(requestUrl: string, websocketPath: string): string {
|
|
|
4860
5050
|
url.protocol = url.protocol === "https:" ? "wss:" : "ws:";
|
|
4861
5051
|
return url.toString();
|
|
4862
5052
|
}
|
|
4863
|
-
`;var
|
|
5053
|
+
`;var tt=`
|
|
4864
5054
|
export class AppflareRealtimeDurableObject {
|
|
4865
5055
|
private readonly subscriptions = new Map<string, RealtimeSubscription>();
|
|
4866
5056
|
private readonly sockets = new Map<string, WebSocket>();
|
|
@@ -5003,7 +5193,7 @@ export class AppflareRealtimeDurableObject {
|
|
|
5003
5193
|
return new Response("Not found", { status: 404 });
|
|
5004
5194
|
}
|
|
5005
5195
|
}
|
|
5006
|
-
`;var
|
|
5196
|
+
`;var nt=`
|
|
5007
5197
|
async function publishMutationEvents(
|
|
5008
5198
|
c: { req: { raw: Request }; env: Record<string, unknown> },
|
|
5009
5199
|
options: RegisterHandlersOptions,
|
|
@@ -5104,7 +5294,7 @@ async function publishMutationEvents(
|
|
|
5104
5294
|
}
|
|
5105
5295
|
}
|
|
5106
5296
|
}
|
|
5107
|
-
`;var
|
|
5297
|
+
`;var rt=`
|
|
5108
5298
|
function registerRealtimeRoutes(
|
|
5109
5299
|
app: Hono<WorkerEnv>,
|
|
5110
5300
|
options: RegisterHandlersOptions,
|
|
@@ -5267,7 +5457,7 @@ function registerRealtimeRoutes(
|
|
|
5267
5457
|
return stub.fetch(c.req.raw);
|
|
5268
5458
|
});
|
|
5269
5459
|
}
|
|
5270
|
-
`;var
|
|
5460
|
+
`;var at=`
|
|
5271
5461
|
type RealtimeSubscription = {
|
|
5272
5462
|
token: string;
|
|
5273
5463
|
signature: string;
|
|
@@ -5296,7 +5486,7 @@ type RealtimeDurableObjectNamespace = {
|
|
|
5296
5486
|
type RealtimeQueryName = keyof typeof realtimeQueryHandlers extends never
|
|
5297
5487
|
? string
|
|
5298
5488
|
: Extract<keyof typeof realtimeQueryHandlers, string>;
|
|
5299
|
-
`;var
|
|
5489
|
+
`;var ot=`
|
|
5300
5490
|
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
5301
5491
|
return typeof value === "object" && value !== null;
|
|
5302
5492
|
}
|
|
@@ -5486,26 +5676,20 @@ function compareOrderValues(
|
|
|
5486
5676
|
function hasKnownOperator(condition: Record<string, unknown>): boolean {
|
|
5487
5677
|
return [
|
|
5488
5678
|
"eq",
|
|
5489
|
-
"$eq",
|
|
5490
5679
|
"ne",
|
|
5491
|
-
"$ne",
|
|
5492
5680
|
"in",
|
|
5493
|
-
"$in",
|
|
5494
5681
|
"nin",
|
|
5495
|
-
"$nin",
|
|
5496
5682
|
"gt",
|
|
5497
|
-
"$gt",
|
|
5498
5683
|
"gte",
|
|
5499
|
-
"$gte",
|
|
5500
5684
|
"lt",
|
|
5501
|
-
"$lt",
|
|
5502
5685
|
"lte",
|
|
5503
|
-
"$lte",
|
|
5504
5686
|
"exists",
|
|
5505
5687
|
"regex",
|
|
5506
|
-
"
|
|
5688
|
+
"options",
|
|
5507
5689
|
"geoWithin",
|
|
5508
|
-
"
|
|
5690
|
+
"includes",
|
|
5691
|
+
"includesAny",
|
|
5692
|
+
"length",
|
|
5509
5693
|
].some((key) => key in condition);
|
|
5510
5694
|
}
|
|
5511
5695
|
|
|
@@ -5811,9 +5995,9 @@ function doesSubscriptionMatchMutation(
|
|
|
5811
5995
|
|
|
5812
5996
|
return false;
|
|
5813
5997
|
}
|
|
5814
|
-
`;var
|
|
5998
|
+
`;var it=[at,ot,et,nt,rt,tt].join(`
|
|
5815
5999
|
|
|
5816
|
-
`);var
|
|
6000
|
+
`);var st=`
|
|
5817
6001
|
function parseExpiresIn(value: string | undefined): number | undefined {
|
|
5818
6002
|
if (!value) {
|
|
5819
6003
|
return undefined;
|
|
@@ -6011,7 +6195,7 @@ export function registerGeneratedStorageRoutes(
|
|
|
6011
6195
|
}
|
|
6012
6196
|
});
|
|
6013
6197
|
}
|
|
6014
|
-
`;var
|
|
6198
|
+
`;var lt=`
|
|
6015
6199
|
type SchedulerTaskName = keyof typeof schedulerHandlers extends never
|
|
6016
6200
|
? string
|
|
6017
6201
|
: keyof typeof schedulerHandlers;
|
|
@@ -6066,7 +6250,7 @@ export async function executeScheduledBatch(
|
|
|
6066
6250
|
}
|
|
6067
6251
|
}
|
|
6068
6252
|
}
|
|
6069
|
-
`;var
|
|
6253
|
+
`;var ut=`
|
|
6070
6254
|
export async function executeCronTriggers(
|
|
6071
6255
|
controller: { cron: string },
|
|
6072
6256
|
env: Record<string, unknown>,
|
|
@@ -6091,7 +6275,7 @@ export async function executeCronTriggers(
|
|
|
6091
6275
|
}
|
|
6092
6276
|
}
|
|
6093
6277
|
}
|
|
6094
|
-
`;function
|
|
6278
|
+
`;function ct(e){let{imports:t,operationSchemas:n,schedulerSchemas:r,queryRoutes:a,mutationRoutes:o,queryRegistryEntries:i,schedulerEntries:s,schedulerPayloadMapEntries:c,cronEntries:l,storageHandlersEntries:u}=Xe(e);return `import { sValidator } from "@hono/standard-validator";
|
|
6095
6279
|
import type { Hono } from "hono";
|
|
6096
6280
|
import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@cloudflare/workers-types";
|
|
6097
6281
|
import { ZodError, z } from "zod";
|
|
@@ -6114,16 +6298,16 @@ ${t}`:""}
|
|
|
6114
6298
|
${n}
|
|
6115
6299
|
${r}
|
|
6116
6300
|
|
|
6117
|
-
const realtimeQueryHandlers = {${
|
|
6301
|
+
const realtimeQueryHandlers = {${i||`
|
|
6118
6302
|
`}
|
|
6119
6303
|
} as const;
|
|
6120
6304
|
|
|
6121
|
-
const schedulerHandlers = {${
|
|
6305
|
+
const schedulerHandlers = {${s||`
|
|
6122
6306
|
`}
|
|
6123
6307
|
} as const;
|
|
6124
6308
|
|
|
6125
|
-
type GeneratedSchedulerPayloadMap = {${
|
|
6126
|
-
${
|
|
6309
|
+
type GeneratedSchedulerPayloadMap = {${c?`
|
|
6310
|
+
${c}
|
|
6127
6311
|
`:""}};
|
|
6128
6312
|
|
|
6129
6313
|
declare global {
|
|
@@ -6138,7 +6322,7 @@ type CronHandlerEntry = {
|
|
|
6138
6322
|
};
|
|
6139
6323
|
};
|
|
6140
6324
|
|
|
6141
|
-
const cronHandlers: readonly CronHandlerEntry[] = [${
|
|
6325
|
+
const cronHandlers: readonly CronHandlerEntry[] = [${l||`
|
|
6142
6326
|
`}
|
|
6143
6327
|
];
|
|
6144
6328
|
|
|
@@ -6148,9 +6332,9 @@ const storageHandlers = [${u||`
|
|
|
6148
6332
|
|
|
6149
6333
|
setStorageHandlers([...storageHandlers]);
|
|
6150
6334
|
|
|
6151
|
-
${
|
|
6335
|
+
${lt}
|
|
6152
6336
|
|
|
6153
|
-
${
|
|
6337
|
+
${it}
|
|
6154
6338
|
|
|
6155
6339
|
export function registerGeneratedHandlers(
|
|
6156
6340
|
app: Hono<WorkerEnv>,
|
|
@@ -6163,20 +6347,20 @@ export function registerGeneratedHandlers(
|
|
|
6163
6347
|
`}
|
|
6164
6348
|
}
|
|
6165
6349
|
|
|
6166
|
-
${
|
|
6350
|
+
${st}
|
|
6167
6351
|
|
|
6168
|
-
${
|
|
6169
|
-
`}function
|
|
6170
|
-
KV: c.env["${e}"] as KVNamespace`:""}function
|
|
6171
|
-
DATABASE: c.env["${e}"] as D1Database${
|
|
6172
|
-
}`}function
|
|
6352
|
+
${ut}
|
|
6353
|
+
`}function Z(e,t,n,r=[]){let a=Ye(e,r),o=Pe(n),i=Ee(),s=ct(t);return [{relativePath:"handlers.ts",source:a},{relativePath:"handlers.context.ts",source:o},{relativePath:"handlers.execution.ts",source:i},{relativePath:"handlers.routes.ts",source:s}]}function yr(e){return e?`,
|
|
6354
|
+
KV: c.env["${e}"] as KVNamespace`:""}function dt(e,t){return `{
|
|
6355
|
+
DATABASE: c.env["${e}"] as D1Database${yr(t)}
|
|
6356
|
+
}`}function pt(e,t,n){return `app.on(["GET", "POST"], "${e}/*", async (c) => {
|
|
6173
6357
|
const auth = createAuth(
|
|
6174
|
-
${
|
|
6358
|
+
${dt(t,n)},
|
|
6175
6359
|
c.req.raw.cf as IncomingRequestCfProperties | undefined,
|
|
6176
6360
|
);
|
|
6177
6361
|
return auth.handler(getSanitizedRequest(c.req.raw));
|
|
6178
6362
|
});
|
|
6179
|
-
`}function
|
|
6363
|
+
`}function br(){return `export const getHeaders = (headers: Headers) => {
|
|
6180
6364
|
const newHeaders = Object.fromEntries(headers as any);
|
|
6181
6365
|
const headerObject: Record<string, any> = {};
|
|
6182
6366
|
let hasCookie = false;
|
|
@@ -6206,15 +6390,15 @@ ${rt}
|
|
|
6206
6390
|
|
|
6207
6391
|
return headerObject as any as Headers;
|
|
6208
6392
|
};
|
|
6209
|
-
`}function
|
|
6393
|
+
`}function wr(){return `export const getSanitizedRequest = (req: Request) => {
|
|
6210
6394
|
const newRequest = new Request(req, {
|
|
6211
6395
|
headers: getHeaders(req.headers),
|
|
6212
6396
|
});
|
|
6213
6397
|
return newRequest;
|
|
6214
6398
|
};
|
|
6215
|
-
`}function
|
|
6216
|
-
`+
|
|
6217
|
-
`+
|
|
6399
|
+
`}function mt(){return br()+`
|
|
6400
|
+
`+wr()}function gt(e,t,n){return pt(e,t,n)+`
|
|
6401
|
+
`+mt()}function ft(){return `const app = new Hono<WorkerEnv>();
|
|
6218
6402
|
|
|
6219
6403
|
app.use('*', cors({
|
|
6220
6404
|
origin: (origin, c) => {
|
|
@@ -6230,7 +6414,7 @@ app.use('*', cors({
|
|
|
6230
6414
|
},
|
|
6231
6415
|
credentials: true
|
|
6232
6416
|
}));
|
|
6233
|
-
`}function
|
|
6417
|
+
`}function ht(){return `export { AppflareRealtimeDurableObject };
|
|
6234
6418
|
|
|
6235
6419
|
export default {
|
|
6236
6420
|
fetch: app.fetch,
|
|
@@ -6241,30 +6425,30 @@ export default {
|
|
|
6241
6425
|
await executeCronTriggers(controller, env, generatedHandlerOptions);
|
|
6242
6426
|
},
|
|
6243
6427
|
};
|
|
6244
|
-
`}function
|
|
6428
|
+
`}function yt(e,t,n="APPFLARE_SCHEDULER_QUEUE",r,a="APPFLARE_REALTIME",o="global",i="/realtime/subscribe",s="/realtime/ws",c="appflare.realtime.v1"){let l=t?`
|
|
6245
6429
|
kvBinding: "${t}",`:"",u=r?`
|
|
6246
|
-
r2Binding: "${r}",`:"",
|
|
6430
|
+
r2Binding: "${r}",`:"",p=`
|
|
6247
6431
|
realtimeBinding: "${a}",
|
|
6248
6432
|
realtimeObjectName: "${o}",
|
|
6249
|
-
realtimeSubscribePath: "${
|
|
6250
|
-
realtimeWebsocketPath: "${
|
|
6251
|
-
realtimeProtocol: "${
|
|
6252
|
-
databaseBinding: "${e}",${
|
|
6253
|
-
schedulerBinding: "${n}",${u}${
|
|
6433
|
+
realtimeSubscribePath: "${i}",
|
|
6434
|
+
realtimeWebsocketPath: "${s}",
|
|
6435
|
+
realtimeProtocol: "${c}",`;return `const generatedHandlerOptions = {
|
|
6436
|
+
databaseBinding: "${e}",${l}
|
|
6437
|
+
schedulerBinding: "${n}",${u}${p}
|
|
6254
6438
|
};
|
|
6255
6439
|
registerGeneratedHandlers(app, generatedHandlerOptions);
|
|
6256
6440
|
registerGeneratedStorageRoutes(app, generatedHandlerOptions);
|
|
6257
6441
|
registerAdminDashboard(app, generatedHandlerOptions);
|
|
6258
|
-
`}function
|
|
6442
|
+
`}function bt(){return `import { createAuth } from "./auth.config";
|
|
6259
6443
|
import { AppflareRealtimeDurableObject, executeCronTriggers, executeScheduledBatch, registerGeneratedHandlers, registerGeneratedStorageRoutes } from "./handlers.routes";
|
|
6260
6444
|
import { registerAdminDashboard } from "./admin.routes";
|
|
6261
6445
|
import { Hono } from "hono";
|
|
6262
6446
|
import { cors } from "hono/cors";
|
|
6263
6447
|
import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@cloudflare/workers-types";
|
|
6264
|
-
`}function
|
|
6448
|
+
`}function wt(){return `type WorkerEnv = {
|
|
6265
6449
|
Bindings: Record<string, unknown>;
|
|
6266
6450
|
};
|
|
6267
|
-
`}function
|
|
6451
|
+
`}function xt(e,t,n,r,a,o,i,s,c,l){return bt()+wt()+ft()+yt(t,n,r,a,o,i,s,c,l)+gt(e,t,n)+ht()}function Tt(e){return !!e&&typeof e=="object"&&!Array.isArray(e)}function Y(e,t){let n={...e};for(let[r,a]of Object.entries(t)){let o=n[r];if(Tt(o)&&Tt(a)){n[r]=Y(o,a);continue}n[r]=a;}return n}function xr(e){return Array.from(new Set(e.filter(t=>t.length>0)))}function vt(e,t){let n=t.filter(d=>d.kind==="scheduler"||d.kind==="cron"),r=xr(t.filter(d=>d.kind==="cron").flatMap(d=>d.cronTriggers??[])),a=e.config.scheduler.enabled&&n.length>0,o=e.config.realtime.enabled,s=(typeof e.config.wranglerOverrides?.name=="string"?e.config.wranglerOverrides.name:void 0)??"appflare-worker",c=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:c}],consumers:[{queue:c}]}}:{},...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:u,...p}=e.config.wranglerOverrides;return Y(l,p)}function Rt(e){return e.tables.map(t=>({exportName:t.exportName,tableName:t.tableName,columns:t.columns.map(n=>n.name)}))}function kt(e){return `<li data-name="users">
|
|
6268
6452
|
<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">
|
|
6269
6453
|
<iconify-icon icon="mdi:account-group" width="16" height="16" class="opacity-50 shrink-0"></iconify-icon>
|
|
6270
6454
|
<span class="truncate">users</span>
|
|
@@ -6276,7 +6460,7 @@ import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@clou
|
|
|
6276
6460
|
<span class="truncate">${n.tableName}</span>
|
|
6277
6461
|
</a>
|
|
6278
6462
|
</li>`).join(`
|
|
6279
|
-
`)}`}function
|
|
6463
|
+
`)}`}function St(e){let t=e.filter(o=>o.kind==="query"),n=e.filter(o=>o.kind==="mutation"),r=t.map(o=>`
|
|
6280
6464
|
<li data-name="${o.exportName}">
|
|
6281
6465
|
<a href="/admin/functions${o.routePath}" hx-get="/admin/functions${o.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">
|
|
6282
6466
|
<iconify-icon icon="solar:reorder-linear" width="16" height="16" class="opacity-50 shrink-0"></iconify-icon>
|
|
@@ -6310,7 +6494,7 @@ import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@clou
|
|
|
6310
6494
|
<ul class="flex flex-col gap-0.5">${a}</ul>`:""}
|
|
6311
6495
|
</nav>
|
|
6312
6496
|
</div>
|
|
6313
|
-
`}function
|
|
6497
|
+
`}function At(e){return e.map(t=>`
|
|
6314
6498
|
<a
|
|
6315
6499
|
href="/admin/table/${t.exportName}"
|
|
6316
6500
|
class="card bg-base-100 border border-base-200 hover:border-primary/30 hover:shadow-md transition-all cursor-pointer group"
|
|
@@ -6327,9 +6511,9 @@ import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@clou
|
|
|
6327
6511
|
</div>
|
|
6328
6512
|
</div>
|
|
6329
6513
|
</a>
|
|
6330
|
-
`.replace(/\n/g,"\\n")).join("")}function
|
|
6514
|
+
`.replace(/\n/g,"\\n")).join("")}function Nt(e){return e.columns.filter(t=>t.type==="string").map(t=>`
|
|
6331
6515
|
try { searchConditions.push(like(tableSchema.${t.name}, \`%\${search}%\`)); } catch (e) {}
|
|
6332
|
-
`).join("")}function
|
|
6516
|
+
`).join("")}function Tr(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 $t(e,t){return t.map(n=>{let r=e.columns.find(o=>o.name===n),a=r?Tr(r.type):"mdi:format-text";return `
|
|
6333
6517
|
<th>
|
|
6334
6518
|
<a href="#"
|
|
6335
6519
|
hx-get="/admin/table/${e.exportName}?page=\${page}&search=\${search}&sort=${n}&order=\${sort === '${n}' && order === 'asc' ? 'desc' : 'asc'}"
|
|
@@ -6341,7 +6525,7 @@ import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@clou
|
|
|
6341
6525
|
<span class="text-[10px] opacity-30">\${sort === '${n}' ? (order === 'asc' ? '\u25B2' : '\u25BC') : ''}</span>
|
|
6342
6526
|
</a>
|
|
6343
6527
|
</th>
|
|
6344
|
-
`}).join("")}function
|
|
6528
|
+
`}).join("")}function Ct(e,t){return e.map(n=>t&&n===t?`<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).${n} ?? '')}" data-copy-value="\${String((row as any).${n} ?? '')}" onclick="navigator.clipboard?.writeText(this.dataset.copyValue || '')">\${String((row as any).${n} ?? '')}</button></td>`:`<td><div class="truncate max-w-[200px] text-sm" title="\${String((row as any).${n} ?? '')}">\${String((row as any).${n} ?? '')}</div></td>`).join("")}function X(e,t,n){let r=e.columns.find(i=>i.name===t);if(!r)return "";let a=r.optional?"":" required",o=r.type==="number"?"number":r.type==="date"?"date":"text";if(r.type==="boolean")return n==="edit"?`
|
|
6345
6529
|
<div class="form-control">
|
|
6346
6530
|
<label class="label cursor-pointer justify-start gap-3">
|
|
6347
6531
|
<input type="checkbox" name="${t}" value="true" class="checkbox checkbox-sm checkbox-primary" \${(row as any).${t} ? 'checked' : ''} />
|
|
@@ -6355,7 +6539,7 @@ import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@clou
|
|
|
6355
6539
|
<span class="label-text text-sm">${t}</span>
|
|
6356
6540
|
</label>
|
|
6357
6541
|
</div>
|
|
6358
|
-
`;if(n==="edit"){let
|
|
6542
|
+
`;if(n==="edit"){let i=r.type==="date"?`\${(() => {
|
|
6359
6543
|
const value = (row as any).${t};
|
|
6360
6544
|
if (value == null || value === '') return '';
|
|
6361
6545
|
|
|
@@ -6372,14 +6556,14 @@ import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@clou
|
|
|
6372
6556
|
})()}`:`\${String((row as any).${t} ?? '')}`;return `
|
|
6373
6557
|
<div class="form-control">
|
|
6374
6558
|
<label class="label"><span class="label-text text-sm font-medium">${t}</span></label>
|
|
6375
|
-
<input type="${o}" name="${t}" class="input input-bordered w-full text-sm" value="${
|
|
6559
|
+
<input type="${o}" name="${t}" class="input input-bordered w-full text-sm" value="${i}"${a} />
|
|
6376
6560
|
</div>
|
|
6377
6561
|
`}return `
|
|
6378
6562
|
<div class="form-control">
|
|
6379
6563
|
<label class="label"><span class="label-text text-sm font-medium">${t}</span></label>
|
|
6380
6564
|
<input type="${o}" name="${t}" class="input input-bordered w-full text-sm"${a} />
|
|
6381
6565
|
</div>
|
|
6382
|
-
`}function
|
|
6566
|
+
`}function ee(e,t){return t.map(n=>{let r=e.columns.find(o=>o.name===n);if(!r)return "";let a=r.optional?"":`
|
|
6383
6567
|
if (raw_${n} === '') {
|
|
6384
6568
|
return c.text('${n} is required', 400);
|
|
6385
6569
|
}
|
|
@@ -6424,7 +6608,7 @@ import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@clou
|
|
|
6424
6608
|
payload.${n} = raw_${n};
|
|
6425
6609
|
}
|
|
6426
6610
|
`}).join(`
|
|
6427
|
-
`)}function
|
|
6611
|
+
`)}function qt(e){return e.columns.find(t=>t.primaryKey)?.name||e.columns[0]?.name||""}function Mt(e,t){let n=e.columns.find(r=>r.name===t);return !(!n||n.autoIncrement||n.primaryKey)}function Ft(e,t){let n=e.columns.find(r=>r.name===t);return !(!n||n.primaryKey||n.autoIncrement)}function It(e,t,n,r){return t?`<td class="text-right">
|
|
6428
6612
|
<div class="drawer drawer-end">
|
|
6429
6613
|
<input id="edit-drawer-${e.exportName}-\${rowIndex}" type="checkbox" class="drawer-toggle" />
|
|
6430
6614
|
<div class="drawer-content">
|
|
@@ -6477,7 +6661,7 @@ import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@clou
|
|
|
6477
6661
|
</div>
|
|
6478
6662
|
</div>
|
|
6479
6663
|
</div>
|
|
6480
|
-
</td>`:'<td class="text-right"><span class="text-xs opacity-30">No primary key</span></td>'}function
|
|
6664
|
+
</td>`:'<td class="text-right"><span class="text-xs opacity-30">No primary key</span></td>'}function B(e){return `
|
|
6481
6665
|
<div class="flex flex-col sm:flex-row justify-between items-center mt-4 gap-3 py-3 px-1">
|
|
6482
6666
|
<div class="text-xs text-base-content/40">
|
|
6483
6667
|
Total found: <span class="font-medium text-base-content/60">\${total}</span>
|
|
@@ -6499,7 +6683,7 @@ import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@clou
|
|
|
6499
6683
|
\` : 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>\`}
|
|
6500
6684
|
</div>
|
|
6501
6685
|
\` : ''}
|
|
6502
|
-
</div>`}function
|
|
6686
|
+
</div>`}function W(e,t="Search term or filter..."){return `
|
|
6503
6687
|
<div class="form-control w-full md:w-auto relative">
|
|
6504
6688
|
<iconify-icon icon="mdi:magnify" width="18" height="18" class="absolute left-3 top-1/2 -translate-y-1/2 opacity-40"></iconify-icon>
|
|
6505
6689
|
<input type="text"
|
|
@@ -6510,7 +6694,7 @@ import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@clou
|
|
|
6510
6694
|
hx-trigger="keyup changed delay:500ms, search"
|
|
6511
6695
|
hx-target="#main-content"
|
|
6512
6696
|
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" />
|
|
6513
|
-
</div>`}function
|
|
6697
|
+
</div>`}function Pt(e,t,n,r,a,o,i,s,c,l){let u=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).${n} ?? '')}" /></td>`:'<td><input type="checkbox" class="checkbox checkbox-xs opacity-30" disabled /></td>',v=r?`
|
|
6514
6698
|
<div id="bulk-delete-bar-${e.exportName}" class="fixed bottom-4 left-1/2 -translate-x-1/2 z-40 hidden">
|
|
6515
6699
|
<div class="bg-base-100 border border-base-200 rounded-xl shadow-lg px-3 py-2 flex items-center gap-3">
|
|
6516
6700
|
<div class="text-xs text-base-content/70">
|
|
@@ -6669,7 +6853,7 @@ import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@clou
|
|
|
6669
6853
|
<thead>
|
|
6670
6854
|
<tr class="border-b border-base-200">
|
|
6671
6855
|
${d}
|
|
6672
|
-
${
|
|
6856
|
+
${i}
|
|
6673
6857
|
<th class="w-[100px] text-right">
|
|
6674
6858
|
<iconify-icon icon="mdi:dots-horizontal" width="16" height="16" class="opacity-30"></iconify-icon>
|
|
6675
6859
|
</th>
|
|
@@ -6678,9 +6862,9 @@ import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@clou
|
|
|
6678
6862
|
<tbody>
|
|
6679
6863
|
\${data.map((row, rowIndex) => html\`
|
|
6680
6864
|
<tr class="hover:bg-base-200/30 transition-colors">
|
|
6681
|
-
${
|
|
6682
|
-
${
|
|
6683
|
-
${
|
|
6865
|
+
${y}
|
|
6866
|
+
${s}
|
|
6867
|
+
${c}
|
|
6684
6868
|
</tr>
|
|
6685
6869
|
\`)}
|
|
6686
6870
|
\${data.length === 0 ? html\`
|
|
@@ -6726,10 +6910,10 @@ import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@clou
|
|
|
6726
6910
|
</div>
|
|
6727
6911
|
</div>
|
|
6728
6912
|
<div class="mb-4">
|
|
6729
|
-
${
|
|
6913
|
+
${p}
|
|
6730
6914
|
</div>
|
|
6731
6915
|
\${tableHtml}
|
|
6732
|
-
${
|
|
6916
|
+
${v}
|
|
6733
6917
|
</div>
|
|
6734
6918
|
<div class="drawer-side z-50">
|
|
6735
6919
|
<label for="create-drawer-${e.exportName}" aria-label="close sidebar" class="drawer-overlay"></label>
|
|
@@ -6745,7 +6929,7 @@ import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@clou
|
|
|
6745
6929
|
<input type="hidden" name="order" value="\${order}" />
|
|
6746
6930
|
<input type="hidden" name="search" value="\${search}" />
|
|
6747
6931
|
<input type="hidden" name="page" value="\${page}" />
|
|
6748
|
-
${
|
|
6932
|
+
${l}
|
|
6749
6933
|
<button type="submit" class="btn btn-primary btn-sm mt-2">Create record</button>
|
|
6750
6934
|
</form>
|
|
6751
6935
|
</div>
|
|
@@ -6762,7 +6946,7 @@ import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@clou
|
|
|
6762
6946
|
title: "${e.tableName} - Admin Dashboard",
|
|
6763
6947
|
children: content
|
|
6764
6948
|
}));
|
|
6765
|
-
});`}function
|
|
6949
|
+
});`}function Ot(e,t,n,r,a,o,i,s){let c=r==="number"?`
|
|
6766
6950
|
const parsedId = Number(rawId);
|
|
6767
6951
|
if (Number.isNaN(parsedId)) return c.text('${n} must be a valid number', 400);
|
|
6768
6952
|
idValue = parsedId;
|
|
@@ -6779,10 +6963,10 @@ import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@clou
|
|
|
6779
6963
|
|
|
6780
6964
|
const payload: Record<string, unknown> = {};
|
|
6781
6965
|
|
|
6782
|
-
${
|
|
6966
|
+
${s}
|
|
6783
6967
|
|
|
6784
6968
|
let idValue: unknown = rawId;
|
|
6785
|
-
${
|
|
6969
|
+
${c}
|
|
6786
6970
|
|
|
6787
6971
|
if (Object.keys(payload).length > 0) {
|
|
6788
6972
|
await db
|
|
@@ -6812,7 +6996,7 @@ import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@clou
|
|
|
6812
6996
|
if (rawId === '') return c.text('${n} is required', 400);
|
|
6813
6997
|
|
|
6814
6998
|
let idValue: unknown = rawId;
|
|
6815
|
-
${
|
|
6999
|
+
${c}
|
|
6816
7000
|
|
|
6817
7001
|
await db
|
|
6818
7002
|
.delete(tableSchema)
|
|
@@ -6882,7 +7066,7 @@ import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@clou
|
|
|
6882
7066
|
const getValue = (value: unknown) => (typeof value === 'string' ? value : '');
|
|
6883
7067
|
const payload: Record<string, unknown> = {};
|
|
6884
7068
|
|
|
6885
|
-
${
|
|
7069
|
+
${i}
|
|
6886
7070
|
|
|
6887
7071
|
await db.insert(tableSchema).values(payload as any).execute();
|
|
6888
7072
|
|
|
@@ -6895,15 +7079,15 @@ import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@clou
|
|
|
6895
7079
|
return c.redirect('/admin/table/${e}?' + query.toString());
|
|
6896
7080
|
});
|
|
6897
7081
|
${u}
|
|
6898
|
-
`}function
|
|
6899
|
-
`+
|
|
7082
|
+
`}function te(e){let t=qt(e),n=!!t,r=e.columns.map(w=>w.name),a=r.filter(w=>Mt(e,w)),o=r.filter(w=>Ft(e,w)),i=Nt(e),s=$t(e,r),c=Ct(r,t),l=a.map(w=>X(e,w,"create")).join(""),u=o.map(w=>X(e,w,"edit")).join(""),p=ee(e,a),d=ee(e,o),y=n?t:r[0]||"id",v=e.columns.find(w=>w.name===t)?.type,A=It(e,n,t,u);return Pt(e,y,t,n,r,i,s,c,A,l)+`
|
|
7083
|
+
`+Ot(e.exportName,y,t,v,n,i,p,d)}function Et(){return `
|
|
6900
7084
|
const buildUsersRedirect = (params: { page?: string; sort?: string; order?: string; search?: string }) => {
|
|
6901
7085
|
const page = params.page && params.page.trim() ? params.page : '1';
|
|
6902
7086
|
const sort = params.sort && params.sort.trim() ? params.sort : 'createdAt';
|
|
6903
7087
|
const order = params.order === 'asc' ? 'asc' : 'desc';
|
|
6904
7088
|
const search = params.search ? params.search : '';
|
|
6905
7089
|
return '/admin/users?page=' + encodeURIComponent(page) + '&sort=' + encodeURIComponent(sort) + '&order=' + encodeURIComponent(order) + '&search=' + encodeURIComponent(search);
|
|
6906
|
-
};`}function
|
|
7090
|
+
};`}function Dt(){return `
|
|
6907
7091
|
\${(row as any).id === currentUserId ? '' : html\`
|
|
6908
7092
|
<input type="checkbox" id="ban-user-modal-\${String((row as any).id)}" class="modal-toggle" />
|
|
6909
7093
|
<div class="modal">
|
|
@@ -6924,7 +7108,7 @@ ${u}
|
|
|
6924
7108
|
</div>
|
|
6925
7109
|
<label class="modal-backdrop" for="ban-user-modal-\${String((row as any).id)}">Close</label>
|
|
6926
7110
|
</div>
|
|
6927
|
-
\`}`}function
|
|
7111
|
+
\`}`}function jt(){return `
|
|
6928
7112
|
\${(row as any).id === currentUserId ? '' : html\`
|
|
6929
7113
|
<input type="checkbox" id="delete-user-modal-\${String((row as any).id)}" class="modal-toggle" />
|
|
6930
7114
|
<div class="modal">
|
|
@@ -6945,8 +7129,8 @@ ${u}
|
|
|
6945
7129
|
</div>
|
|
6946
7130
|
<label class="modal-backdrop" for="delete-user-modal-\${String((row as any).id)}">Close</label>
|
|
6947
7131
|
</div>
|
|
6948
|
-
\`}`}var
|
|
6949
|
-
`),t=
|
|
7132
|
+
\`}`}var vr=["id","name","email","role","createdAt","banned"],Rr={id:"mdi:pound",name:"mdi:format-text",email:"mdi:at",role:"mdi:shield-account-outline",createdAt:"mdi:calendar",banned:"mdi:toggle-switch-outline"};function kr(e){let t=Rr[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="${t}" 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 Vt(){let e=vr.map(kr).join(`
|
|
7133
|
+
`),t=B("/admin/users");return `
|
|
6950
7134
|
const tableHtml = html\`
|
|
6951
7135
|
<div class="bg-base-100 rounded-xl border border-base-200 overflow-hidden">
|
|
6952
7136
|
<div class="overflow-x-auto">
|
|
@@ -7014,8 +7198,8 @@ ${u}
|
|
|
7014
7198
|
</div>
|
|
7015
7199
|
</div>
|
|
7016
7200
|
</div>
|
|
7017
|
-
${
|
|
7018
|
-
${
|
|
7201
|
+
${Dt()}
|
|
7202
|
+
${jt()}
|
|
7019
7203
|
</td>
|
|
7020
7204
|
</tr>
|
|
7021
7205
|
\`)}
|
|
@@ -7031,7 +7215,7 @@ ${It()}
|
|
|
7031
7215
|
${t}
|
|
7032
7216
|
</div>
|
|
7033
7217
|
\`;
|
|
7034
|
-
`}function
|
|
7218
|
+
`}function Bt(){return `
|
|
7035
7219
|
const content = html\`
|
|
7036
7220
|
<div id="main-content">
|
|
7037
7221
|
<div class="flex flex-col md:flex-row justify-between items-start md:items-center mb-5 gap-3">
|
|
@@ -7043,11 +7227,11 @@ ${It()}
|
|
|
7043
7227
|
<iconify-icon icon="mdi:refresh" width="14" height="14"></iconify-icon>
|
|
7044
7228
|
</button>
|
|
7045
7229
|
</div>
|
|
7046
|
-
${
|
|
7230
|
+
${W("/admin/users","Search users...")}
|
|
7047
7231
|
</div>
|
|
7048
7232
|
\${tableHtml}
|
|
7049
7233
|
</div>
|
|
7050
|
-
\`;`}function
|
|
7234
|
+
\`;`}function Wt(){let e=Vt(),t=Bt();return `
|
|
7051
7235
|
adminApp.get('/users', async (c) => {
|
|
7052
7236
|
const db = drizzle(c.env[options.databaseBinding]);
|
|
7053
7237
|
const auth = createAuth({ DATABASE: c.env[options.databaseBinding] } as any, c.req.raw.cf as any);
|
|
@@ -7103,7 +7287,7 @@ ${It()}
|
|
|
7103
7287
|
title: "users - Admin Dashboard",
|
|
7104
7288
|
children: content,
|
|
7105
7289
|
}));
|
|
7106
|
-
});`}function
|
|
7290
|
+
});`}function Ht(){return `
|
|
7107
7291
|
adminApp.post('/users/edit', async (c) => {
|
|
7108
7292
|
const session = await requireAdminSession(c);
|
|
7109
7293
|
if (!session) {
|
|
@@ -7246,8 +7430,8 @@ ${It()}
|
|
|
7246
7430
|
const resolvedPage = String(Math.min(nextPageCandidate, totalPages));
|
|
7247
7431
|
|
|
7248
7432
|
return c.redirect(buildUsersRedirect({ page: resolvedPage, search, sort, order }));
|
|
7249
|
-
});`}function
|
|
7250
|
-
${
|
|
7433
|
+
});`}function ne(){return `
|
|
7434
|
+
${Et()}
|
|
7251
7435
|
|
|
7252
7436
|
const requireAdminSession = async (c: any) => {
|
|
7253
7437
|
const auth = createAuth({ DATABASE: c.env[options.databaseBinding] } as any, c.req.raw.cf as any);
|
|
@@ -7258,12 +7442,12 @@ ${It()}
|
|
|
7258
7442
|
return session;
|
|
7259
7443
|
};
|
|
7260
7444
|
|
|
7261
|
-
${
|
|
7445
|
+
${Wt()}
|
|
7262
7446
|
|
|
7263
|
-
${
|
|
7264
|
-
`}function
|
|
7447
|
+
${Ht()}
|
|
7448
|
+
`}function Lt(e){return `${e.tables.map(t=>te(t)).join(`
|
|
7265
7449
|
`)}
|
|
7266
|
-
${
|
|
7450
|
+
${ne()}`}function zt(e){return `
|
|
7267
7451
|
<div class="flex items-center justify-between">
|
|
7268
7452
|
<div class="flex items-center gap-3">
|
|
7269
7453
|
<div class="w-10 h-10 rounded-xl bg-primary/10 flex items-center justify-center">
|
|
@@ -7278,9 +7462,9 @@ ${Z()}`}function jt(e){return `
|
|
|
7278
7462
|
<span class="badge badge-sm badge-ghost font-mono opacity-50 px-2 py-3">/api${e.routePath}</span>
|
|
7279
7463
|
</div>
|
|
7280
7464
|
</div>
|
|
7281
|
-
`}function
|
|
7465
|
+
`}function Sr(e){return e==="boolean"?"checkbox":e==="number"?"number":"text"}function Ar(e){let t=e.args??[];return t.length===0?`
|
|
7282
7466
|
<div class="text-[11px] opacity-30 italic py-2">No arguments defined for this ${e.kind}.</div>
|
|
7283
|
-
`:t.map(n=>{let r=
|
|
7467
|
+
`:t.map(n=>{let r=Sr(n.type),a=r==="checkbox",o=`${n.name}${n.optional?"":" *"}`,i=n.type!=="unknown"?`<span class="badge badge-xs badge-ghost font-mono opacity-40 ml-1">${n.type}</span>`:"";return a?`
|
|
7284
7468
|
<div class="flex items-center gap-3 py-1">
|
|
7285
7469
|
<input
|
|
7286
7470
|
type="checkbox"
|
|
@@ -7289,13 +7473,13 @@ ${Z()}`}function jt(e){return `
|
|
|
7289
7473
|
class="checkbox checkbox-sm checkbox-primary"
|
|
7290
7474
|
${n.defaultValue==="true"?"checked":""}
|
|
7291
7475
|
/>
|
|
7292
|
-
<span class="text-sm font-mono opacity-70">${n.name}${
|
|
7476
|
+
<span class="text-sm font-mono opacity-70">${n.name}${i}</span>
|
|
7293
7477
|
${n.optional?'<span class="text-[10px] opacity-30 italic ml-auto">optional</span>':""}
|
|
7294
7478
|
</div>
|
|
7295
7479
|
`:`
|
|
7296
7480
|
<div class="form-control">
|
|
7297
7481
|
<label class="label py-0.5">
|
|
7298
|
-
<span class="label-text text-[11px] font-mono font-semibold">${o}${
|
|
7482
|
+
<span class="label-text text-[11px] font-mono font-semibold">${o}${i}</span>
|
|
7299
7483
|
${n.optional?'<span class="label-text-alt text-[10px] opacity-30 italic">optional</span>':""}
|
|
7300
7484
|
</label>
|
|
7301
7485
|
<input
|
|
@@ -7309,7 +7493,7 @@ ${Z()}`}function jt(e){return `
|
|
|
7309
7493
|
/>
|
|
7310
7494
|
</div>
|
|
7311
7495
|
`}).join(`
|
|
7312
|
-
`)}function
|
|
7496
|
+
`)}function Nr(e){return `
|
|
7313
7497
|
<div class="space-y-4">
|
|
7314
7498
|
<div class="flex items-center justify-between">
|
|
7315
7499
|
<div class="flex flex-col">
|
|
@@ -7322,11 +7506,11 @@ ${Z()}`}function jt(e){return `
|
|
|
7322
7506
|
</label>
|
|
7323
7507
|
</div>
|
|
7324
7508
|
<div id="args-rows" class="flex flex-col gap-3">
|
|
7325
|
-
${
|
|
7509
|
+
${Ar(e)}
|
|
7326
7510
|
</div>
|
|
7327
7511
|
<p class="text-[11px] opacity-30 mt-2 italic">Values are sent as ${e.kind==="query"?"query string params":"JSON request body"}.</p>
|
|
7328
7512
|
</div>
|
|
7329
|
-
`}function
|
|
7513
|
+
`}function $r(){return `
|
|
7330
7514
|
<div class="space-y-4">
|
|
7331
7515
|
<label class="text-[11px] font-bold uppercase tracking-wider opacity-40 block">Bearer Token <span class="font-normal normal-case">(optional)</span></label>
|
|
7332
7516
|
<div class="relative group">
|
|
@@ -7343,7 +7527,7 @@ ${Z()}`}function jt(e){return `
|
|
|
7343
7527
|
</div>
|
|
7344
7528
|
<p class="text-[10px] opacity-30 italic">Token will be included in the Authorization header.</p>
|
|
7345
7529
|
</div>
|
|
7346
|
-
`}function
|
|
7530
|
+
`}function Cr(){return `
|
|
7347
7531
|
<div class="space-y-4">
|
|
7348
7532
|
<div class="flex items-center justify-between">
|
|
7349
7533
|
<span class="text-[11px] font-bold uppercase tracking-wider opacity-40">Custom Headers</span>
|
|
@@ -7357,7 +7541,7 @@ ${Z()}`}function jt(e){return `
|
|
|
7357
7541
|
</div>
|
|
7358
7542
|
<p id="headers-error" class="text-[11px] text-error mt-1.5 hidden"></p>
|
|
7359
7543
|
</div>
|
|
7360
|
-
`}function
|
|
7544
|
+
`}function Ut(e){return `
|
|
7361
7545
|
<div class="card bg-base-100 border border-base-200 shadow-sm overflow-hidden flex flex-col h-full">
|
|
7362
7546
|
<div class="px-5 py-3 border-b border-base-200 bg-base-200/20 flex items-center justify-between flex-none">
|
|
7363
7547
|
<h3 class="text-xs font-bold uppercase tracking-widest opacity-40">Request</h3>
|
|
@@ -7378,13 +7562,13 @@ ${Z()}`}function jt(e){return `
|
|
|
7378
7562
|
<!-- Tab Content -->
|
|
7379
7563
|
<div class="flex-1 overflow-y-auto">
|
|
7380
7564
|
<div id="request-tab-args" class="p-5">
|
|
7381
|
-
${
|
|
7565
|
+
${Nr(e)}
|
|
7382
7566
|
</div>
|
|
7383
7567
|
<div id="request-tab-auth" class="p-5 hidden">
|
|
7384
|
-
${
|
|
7568
|
+
${$r()}
|
|
7385
7569
|
</div>
|
|
7386
7570
|
<div id="request-tab-headers" class="p-5 hidden">
|
|
7387
|
-
${
|
|
7571
|
+
${Cr()}
|
|
7388
7572
|
</div>
|
|
7389
7573
|
</div>
|
|
7390
7574
|
|
|
@@ -7402,7 +7586,7 @@ ${Z()}`}function jt(e){return `
|
|
|
7402
7586
|
</form>
|
|
7403
7587
|
</div>
|
|
7404
7588
|
</div>
|
|
7405
|
-
`}function
|
|
7589
|
+
`}function Qt(){return `
|
|
7406
7590
|
<div class="card bg-base-100 border border-base-200 shadow-sm overflow-hidden flex flex-col">
|
|
7407
7591
|
<!-- Panel Header -->
|
|
7408
7592
|
<div class="px-5 py-3 border-b border-base-200 bg-base-200/20 flex items-center justify-between">
|
|
@@ -7484,7 +7668,7 @@ ${Z()}`}function jt(e){return `
|
|
|
7484
7668
|
|
|
7485
7669
|
</div>
|
|
7486
7670
|
</div>
|
|
7487
|
-
`}function
|
|
7671
|
+
`}function _t(e){let t=e.kind==="query",n=e.routePath,r=e.handlerName??e.routePath;return `
|
|
7488
7672
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/atom-one-dark.min.css">
|
|
7489
7673
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
|
|
7490
7674
|
|
|
@@ -8026,21 +8210,21 @@ ${Z()}`}function jt(e){return `
|
|
|
8026
8210
|
_rtEnabled = false;
|
|
8027
8211
|
});
|
|
8028
8212
|
</script>
|
|
8029
|
-
`}function
|
|
8213
|
+
`}function Kt(e){return `
|
|
8030
8214
|
const content = html\`
|
|
8031
8215
|
<div class="flex flex-col gap-6 max-w-5xl mx-auto" id="main-content">
|
|
8032
|
-
${
|
|
8216
|
+
${zt(e)}
|
|
8033
8217
|
|
|
8034
8218
|
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
|
8035
8219
|
<!-- Request Panel -->
|
|
8036
|
-
${
|
|
8220
|
+
${Ut(e)}
|
|
8037
8221
|
|
|
8038
8222
|
<!-- Result Panel -->
|
|
8039
|
-
${
|
|
8223
|
+
${Qt()}
|
|
8040
8224
|
</div>
|
|
8041
8225
|
</div>
|
|
8042
8226
|
|
|
8043
|
-
${
|
|
8227
|
+
${_t(e)}
|
|
8044
8228
|
\`;
|
|
8045
8229
|
|
|
8046
8230
|
if (c.req.header('hx-request')) {
|
|
@@ -8050,11 +8234,11 @@ ${Z()}`}function jt(e){return `
|
|
|
8050
8234
|
return c.html(Layout({
|
|
8051
8235
|
title: "${e.exportName} - Functions",
|
|
8052
8236
|
children: content
|
|
8053
|
-
}));`}function
|
|
8237
|
+
}));`}function Jt(e){return e.map(n=>n.kind!=="query"&&n.kind!=="mutation"?"":`
|
|
8054
8238
|
adminApp.get('/functions${n.routePath}', (c) => {
|
|
8055
|
-
${
|
|
8239
|
+
${Kt(n)}
|
|
8056
8240
|
});`).join(`
|
|
8057
|
-
`)}function
|
|
8241
|
+
`)}function Gt(){return `
|
|
8058
8242
|
const getStorageBucket = (c: any): R2Bucket | null => {
|
|
8059
8243
|
const r2Binding = (options as any).r2Binding;
|
|
8060
8244
|
if (!r2Binding || !c.env[r2Binding]) return null;
|
|
@@ -8123,7 +8307,7 @@ ${Z()}`}function jt(e){return `
|
|
|
8123
8307
|
const parts = prefix.split('/').filter(Boolean);
|
|
8124
8308
|
return parts.slice(0, -1).join('/') + (parts.length > 1 ? '/' : '');
|
|
8125
8309
|
};
|
|
8126
|
-
`}function
|
|
8310
|
+
`}function Zt(){return `
|
|
8127
8311
|
const buildStorageListingContent = (listed: any, prefix: string) => {
|
|
8128
8312
|
const parts = prefix.split('/').filter(Boolean);
|
|
8129
8313
|
const breadcrumbs: any[] = [];
|
|
@@ -8250,7 +8434,7 @@ ${Z()}`}function jt(e){return `
|
|
|
8250
8434
|
</div>
|
|
8251
8435
|
\`;
|
|
8252
8436
|
};
|
|
8253
|
-
`}function
|
|
8437
|
+
`}function Yt(){return `
|
|
8254
8438
|
const handleStorageListRoute = async (c: any) => {
|
|
8255
8439
|
const bucket = getStorageBucket(c);
|
|
8256
8440
|
if (!bucket) {
|
|
@@ -8272,7 +8456,7 @@ ${Z()}`}function jt(e){return `
|
|
|
8272
8456
|
|
|
8273
8457
|
adminApp.get('/storage', handleStorageListRoute);
|
|
8274
8458
|
adminApp.get('/storage/*', handleStorageListRoute);
|
|
8275
|
-
`}function
|
|
8459
|
+
`}function Xt(){return `
|
|
8276
8460
|
adminApp.post('/storage/upload', async (c) => {
|
|
8277
8461
|
const bucket = getStorageBucket(c);
|
|
8278
8462
|
if (!bucket) return c.text("Storage not configured", 400);
|
|
@@ -8290,7 +8474,7 @@ ${Z()}`}function jt(e){return `
|
|
|
8290
8474
|
|
|
8291
8475
|
return c.redirect(prefixToStoragePath(prefix));
|
|
8292
8476
|
});
|
|
8293
|
-
`}function
|
|
8477
|
+
`}function en(){return `
|
|
8294
8478
|
adminApp.delete('/storage/delete', async (c) => {
|
|
8295
8479
|
const bucket = getStorageBucket(c);
|
|
8296
8480
|
if (!bucket) return c.text("Storage not configured", 400);
|
|
@@ -8305,7 +8489,7 @@ ${Z()}`}function jt(e){return `
|
|
|
8305
8489
|
c.header('HX-Redirect', prefixToStoragePath(prefix));
|
|
8306
8490
|
return c.html('');
|
|
8307
8491
|
});
|
|
8308
|
-
`}function
|
|
8492
|
+
`}function tn(){return `
|
|
8309
8493
|
adminApp.post('/storage/directory', async (c) => {
|
|
8310
8494
|
const bucket = getStorageBucket(c);
|
|
8311
8495
|
if (!bucket) return c.text("Storage not configured", 400);
|
|
@@ -8331,7 +8515,7 @@ ${Z()}`}function jt(e){return `
|
|
|
8331
8515
|
|
|
8332
8516
|
return c.redirect(prefixToStoragePath(prefix));
|
|
8333
8517
|
});
|
|
8334
|
-
`}function
|
|
8518
|
+
`}function nn(){return `
|
|
8335
8519
|
adminApp.get('/storage/download', async (c) => {
|
|
8336
8520
|
const bucket = getStorageBucket(c);
|
|
8337
8521
|
if (!bucket) return c.text("Storage not configured", 400);
|
|
@@ -8351,7 +8535,7 @@ ${Z()}`}function jt(e){return `
|
|
|
8351
8535
|
|
|
8352
8536
|
return new Response(object.body, { headers });
|
|
8353
8537
|
});
|
|
8354
|
-
`}function
|
|
8538
|
+
`}function rn(){return `
|
|
8355
8539
|
adminApp.get('/storage/preview', async (c) => {
|
|
8356
8540
|
const bucket = getStorageBucket(c);
|
|
8357
8541
|
if (!bucket) return c.text("Storage not configured", 400);
|
|
@@ -8369,25 +8553,25 @@ ${Z()}`}function jt(e){return `
|
|
|
8369
8553
|
|
|
8370
8554
|
return new Response(object.body, { headers });
|
|
8371
8555
|
});
|
|
8372
|
-
`}function
|
|
8373
|
-
${
|
|
8556
|
+
`}function an(){return `
|
|
8557
|
+
${nn()}
|
|
8374
8558
|
|
|
8375
|
-
${
|
|
8559
|
+
${rn()}
|
|
8376
8560
|
|
|
8377
|
-
${
|
|
8561
|
+
${Xt()}
|
|
8378
8562
|
|
|
8379
|
-
${
|
|
8563
|
+
${en()}
|
|
8380
8564
|
|
|
8381
|
-
${
|
|
8565
|
+
${tn()}
|
|
8382
8566
|
|
|
8383
|
-
${
|
|
8384
|
-
`}function
|
|
8385
|
-
${
|
|
8567
|
+
${Yt()}
|
|
8568
|
+
`}function on(){return `
|
|
8569
|
+
${Gt()}
|
|
8386
8570
|
|
|
8387
|
-
${
|
|
8571
|
+
${Zt()}
|
|
8388
8572
|
|
|
8389
|
-
${
|
|
8390
|
-
`}function
|
|
8573
|
+
${an()}
|
|
8574
|
+
`}function sn(e,t){let n=St(t);return `
|
|
8391
8575
|
function Layout(props: { children: any; title: string; hideSidebar?: boolean }) {
|
|
8392
8576
|
return html\`<!DOCTYPE html>
|
|
8393
8577
|
<html lang="en" data-theme="light">
|
|
@@ -8762,7 +8946,7 @@ function Layout(props: { children: any; title: string; hideSidebar?: boolean })
|
|
|
8762
8946
|
</body>
|
|
8763
8947
|
</html>\`;
|
|
8764
8948
|
}
|
|
8765
|
-
`}function
|
|
8949
|
+
`}function ln(){return `
|
|
8766
8950
|
// Auth Middleware
|
|
8767
8951
|
adminApp.use('*', async (c, next) => {
|
|
8768
8952
|
const auth = createAuth({ DATABASE: c.env[options.databaseBinding] } as any, c.req.raw.cf as any);
|
|
@@ -8821,7 +9005,7 @@ function Layout(props: { children: any; title: string; hideSidebar?: boolean })
|
|
|
8821
9005
|
}
|
|
8822
9006
|
await next();
|
|
8823
9007
|
});
|
|
8824
|
-
`}function
|
|
9008
|
+
`}function un(e){return `
|
|
8825
9009
|
adminApp.get('/', (c) => {
|
|
8826
9010
|
return c.html(Layout({
|
|
8827
9011
|
title: "Admin Dashboard",
|
|
@@ -8838,7 +9022,7 @@ function Layout(props: { children: any; title: string; hideSidebar?: boolean })
|
|
|
8838
9022
|
\`
|
|
8839
9023
|
}));
|
|
8840
9024
|
});
|
|
8841
|
-
`}function
|
|
9025
|
+
`}function cn(e,t,n){let r=Rt(t),a=kt(r),o=At(r),i=Lt(t),s=Jt(n),c=on(),l=sn(a,n),u=ln(),p=un(o);return `import { Hono } from "hono";
|
|
8842
9026
|
import { html, raw } from "hono/html";
|
|
8843
9027
|
import { drizzle } from "drizzle-orm/d1";
|
|
8844
9028
|
import { eq, desc, asc, sql, like, or, inArray } from "drizzle-orm";
|
|
@@ -8846,34 +9030,42 @@ import { createAuth } from "./auth.config";
|
|
|
8846
9030
|
import * as schema from "${e}";
|
|
8847
9031
|
import { users } from "./auth.schema";
|
|
8848
9032
|
|
|
8849
|
-
${
|
|
9033
|
+
${l}
|
|
8850
9034
|
|
|
8851
9035
|
export function registerAdminDashboard(app: Hono<any>, options: { databaseBinding: string, r2Binding?: string }) {
|
|
8852
9036
|
const adminApp = new Hono<any>();
|
|
8853
9037
|
|
|
8854
9038
|
${u}
|
|
8855
9039
|
|
|
8856
|
-
${
|
|
9040
|
+
${p}
|
|
8857
9041
|
|
|
8858
9042
|
// Generate table routes
|
|
8859
|
-
${
|
|
9043
|
+
${i}
|
|
8860
9044
|
|
|
8861
9045
|
// Generate function routes
|
|
8862
|
-
${
|
|
9046
|
+
${s}
|
|
8863
9047
|
|
|
8864
9048
|
// Generate storage routes
|
|
8865
|
-
${
|
|
9049
|
+
${c}
|
|
8866
9050
|
|
|
8867
9051
|
app.route('/admin', adminApp);
|
|
8868
9052
|
app.get('/admin/', (c) => c.redirect('/admin'));
|
|
8869
9053
|
}
|
|
8870
|
-
`}function
|
|
8871
|
-
`}function
|
|
8872
|
-
|
|
8873
|
-
|
|
8874
|
-
|
|
8875
|
-
|
|
8876
|
-
|
|
9054
|
+
`}function re(e){if(typeof e!="object"||e===null)return false;let t=e;return t.kind==="schema"&&typeof t.tables=="object"&&(typeof t.enums=="object"||t.enums===void 0)}function O(e){return e.replace(/([a-z0-9])([A-Z])/g,"$1_$2").replace(/[\s-]+/g,"_").toLowerCase()}function M(e){return e.replace(/[_-]+/g," ").replace(/\s+(.)/g,(t,n)=>n.toUpperCase()).replace(/\s/g,"").replace(/^(.)/,(t,n)=>n.toUpperCase())}function ie(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 g(e){return JSON.stringify(e)}function Mr(e){if(typeof e=="string")return g(e);if(typeof e=="number"||typeof e=="boolean")return String(e);if(e===null)return "null";if(e instanceof Date)return g(e.toISOString());throw new Error(`Unsupported SQL default value '${String(e)}'. Use string, number, boolean, null, or Date.`)}function Fr(e){return {kind:"schema",tables:Object.fromEntries(Object.entries(e.tables).map(([t,n])=>[t,{kind:"table",sqlName:n.sqlName,columns:Object.fromEntries(Object.entries(n.columns).map(([r,a])=>[r,{...a}])),relations:Object.fromEntries(Object.entries(n.relations).map(([r,a])=>[r,{...a}]))}])),enums:Object.fromEntries(Object.entries(e.enums??{}).map(([t,n])=>[t,{...n}]))}}function H(e,t,n){let r=e.tables[t];return r?r.columns[n]?.type:void 0}function dn(e,t,n,r,a,o,i){let s=t.columns[n];if(s){if(s.references&&(s.references.table!==r||s.references.column!==a))throw new Error(`Inferred relation '${e}.${n}' conflicts with explicit references(${s.references.table}.${s.references.column}).`);t.columns[n]={...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}t.columns[n]={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 pn(e,t,n){if(t.notNull===true&&t.nullable===true)throw new Error(`Invalid nullable configuration on '${e}': cannot set both notNull and nullable to true.`);return t.notNull===true?true:t.nullable===true||t.notNull===false?false:n}function mn(e,t){return `${e}:${t}`}function Ir(e,t,n,r){let a=mn(e,t),o=mn(n,r);return a<=o?{key:`${a}|${o}`,leftTable:e,leftReferenceField:t,rightTable:n,rightReferenceField:r,sourceIsLeft:true}:{key:`${o}|${a}`,leftTable:n,leftReferenceField:r,rightTable:e,rightReferenceField:t,sourceIsLeft:false}}function Pr(e,t){return `${e}${M(t)}Links`}function gn(e,t,n){let r=ie(e),a=ie(t);return r===a?`${n}${M(r)}Id`:`${r}Id`}function Or(e,t,n){if(e.junctionTable!==t.junctionTable)throw new Error(`manyToMany pair '${n}' has conflicting junctionTable values ('${e.junctionTable}' vs '${t.junctionTable}').`);if(e.leftField!==t.leftField)throw new Error(`manyToMany pair '${n}' has conflicting left field values ('${e.leftField}' vs '${t.leftField}').`);if(e.rightField!==t.rightField)throw new Error(`manyToMany pair '${n}' has conflicting right field values ('${e.rightField}' vs '${t.rightField}').`);if(e.leftSqlName!==t.leftSqlName)throw new Error(`manyToMany pair '${n}' has conflicting left sql name values ('${e.leftSqlName}' vs '${t.leftSqlName}').`);if(e.rightSqlName!==t.rightSqlName)throw new Error(`manyToMany pair '${n}' has conflicting right sql name values ('${e.rightSqlName}' vs '${t.rightSqlName}').`);if(e.onDelete!==t.onDelete)throw new Error(`manyToMany pair '${n}' has conflicting onDelete values ('${e.onDelete}' vs '${t.onDelete}').`);if(e.onUpdate!==t.onUpdate)throw new Error(`manyToMany pair '${n}' has conflicting onUpdate values ('${e.onUpdate}' vs '${t.onUpdate}').`);return e}function Er(e){let t=new Map;for(let[n,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=Ir(n,o,a.targetTable,i),c=gn(s.leftTable,s.rightTable,"source"),l=gn(s.rightTable,s.leftTable,"target"),u={leftTable:s.leftTable,leftReferenceField:s.leftReferenceField,rightTable:s.rightTable,rightReferenceField:s.rightReferenceField,junctionTable:a.junctionTable??Pr(s.leftTable,s.rightTable),leftField:s.sourceIsLeft?a.sourceField??c:a.targetField??c,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(u.leftField===u.rightField)throw new Error(`manyToMany pair '${s.key}' resolves to duplicate junction fields '${u.leftField}'. Set sourceField/targetField explicitly.`);let p=t.get(s.key);p?Or(p,u,s.key):t.set(s.key,u),a.referenceField=o,a.targetReferenceField=i,a.junctionTable=u.junctionTable,a.sourceField=s.sourceIsLeft?u.leftField:u.rightField,a.targetField=s.sourceIsLeft?u.rightField:u.leftField,a.sourceSqlName=s.sourceIsLeft?u.leftSqlName:u.rightSqlName,a.targetSqlName=s.sourceIsLeft?u.rightSqlName:u.leftSqlName;}for(let n of t.values()){if(n.junctionTable in e.tables)throw new Error(`manyToMany auto junction table '${n.junctionTable}' conflicts with an existing table. Set a different junctionTable name.`);let r=H(e,n.leftTable,n.leftReferenceField)??"string",a=H(e,n.rightTable,n.rightReferenceField)??"string";e.tables[n.junctionTable]={kind:"table",columns:{[n.leftField]:{kind:"column",type:r,sqlName:n.leftSqlName,notNull:true,nullable:false,references:{table:n.leftTable,column:n.leftReferenceField,onDelete:n.onDelete,onUpdate:n.onUpdate},index:true},[n.rightField]:{kind:"column",type:a,sqlName:n.rightSqlName,notNull:true,nullable:false,references:{table:n.rightTable,column:n.rightReferenceField,onDelete:n.onDelete,onUpdate:n.onUpdate},index:true}},relations:{[n.leftTable]:{kind:"relation",relation:"one",targetTable:n.leftTable,field:n.leftField,referenceField:n.leftReferenceField},[n.rightTable]:{kind:"relation",relation:"one",targetTable:n.rightTable,field:n.rightField,referenceField:n.rightReferenceField}}};}}function Dr(e){for(let[t,n]of Object.entries(e.tables)){for(let[r,a]of Object.entries(n.columns))if(a.notNull===true&&a.nullable===true)throw new Error(`Invalid nullable configuration on '${t}.${r}': cannot set both notNull and nullable to true.`);for(let[r,a]of Object.entries(n.relations))if(a.relation!=="manyToMany"&&a.notNull===true&&a.nullable===true)throw new Error(`Invalid nullable configuration on '${t}.${r}': cannot set both notNull and nullable to true.`)}}function jr(e){Dr(e);let t=Fr(e);for(let[n,r]of Object.entries(t.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 c=H(t,o.targetTable,i)??o.fkType??"string";dn(n,r,s,o.targetTable,i,{fkType:o.fkType,sqlName:o.sqlName,notNull:pn(`${n}.${a}`,o,true),onDelete:o.onDelete,onUpdate:o.onUpdate},c);}for(let[n,r]of Object.entries(t.tables))for(let a of Object.values(r.relations)){if(a.relation!=="many")continue;let o=t.tables[a.targetTable];if(!o)continue;let i=a.referenceField??"id",s=a.field??`${ie(n)}Id`;a.field=s;let c=H(t,n,i)??a.fkType??"string";dn(a.targetTable,o,s,n,i,{fkType:a.fkType,sqlName:a.sqlName,notNull:pn(`${n}.${a.targetTable}`,a,true),onDelete:a.onDelete,onUpdate:a.onUpdate},c);}return Er(t),t}function hn(e){return e.primaryKey===true||e.notNull!==true||e.autoIncrement===true||e.sqlDefault!==void 0||e.runtimeDefaultFn!==void 0}function E(e){return e.notNull!==true}function Vr(e,t,n){let r=t.sqlName??O(e),a=r!==e;if(t.type==="int")return a?`t.int(${g(r)})`:"t.int()";if(t.type==="string")return t.length!==void 0?a?`t.text(${g(r)}, { length: ${t.length} })`:`t.text({ length: ${t.length} })`:a?`t.text(${g(r)})`:"t.text()";if(t.type==="boolean")return a?`t.int(${g(r)}, { mode: "boolean" })`:'t.int({ mode: "boolean" })';if(t.type==="date")return a?`t.int(${g(r)}, { mode: "timestamp_ms" })`:'t.int({ mode: "timestamp_ms" })';if(t.type==="enum"&&t.enumValues&&t.enumValues.length>0)return t.isArray?a?`t.text(${g(r)}).array()`:"t.text().array()":a?`t.text(${g(r)})`:"t.text()";if(t.type==="json"&&t.jsonShape){let o=L(t.jsonShape);return `${a?`t.text(${g(r)}, { mode: "json" })`:'t.text({ mode: "json" })'}.$type<${o}>()`}return n==="camelToSnake"&&a?`t.text(${g(r)})`:"t.text()"}function Br(e,t,n){let r=n.field,a=n.referenceField??"id";if(!r)throw new Error(`Relation on '${e}' targeting '${n.targetTable}' is missing a local field.`);if(!(r in t.columns))throw new Error(`Relation '${e}.${r}' references missing local field '${r}'.`);return {sourceField:r,targetField:a}}function Wr(e){return e.size===0?"":`import { ${Array.from(e).sort().join(", ")} } from "./auth.schema";
|
|
9055
|
+
`}function Hr(e){return Object.values(e.relations).filter(t=>t.relation==="one").map(t=>t.targetTable)}function Lr(e,t,n){if(t.references)return {tableName:t.references.table,fieldName:t.references.column};let r=Object.values(n.relations).find(a=>a.relation==="one"&&a.field===e);if(r)return {tableName:r.targetTable,fieldName:r.referenceField??"id"}}function zr(e){let t=[];for(let[n,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=se(i.jsonShape);a.push(`${g(o)}: { shape: ${s} },`);}a.length!==0&&t.push(`${g(n)}: {
|
|
9056
|
+
${a.map(o=>` ${o}`).join(`
|
|
9057
|
+
`)}
|
|
9058
|
+
},`);}return t.length===0?`export const __appflareJsonColumns = {} as const;
|
|
9059
|
+
`:`export const __appflareJsonColumns = {
|
|
9060
|
+
${t.map(n=>` ${n}`).join(`
|
|
9061
|
+
`)}
|
|
9062
|
+
} as const;
|
|
9063
|
+
`}function se(e){return e.kind==="array"?`{ kind: "array", element: ${se(e.element)} }`:e.kind==="object"?`{ kind: "object", shape: { ${Object.entries(e.shape).map(([n,r])=>`${g(n)}: ${se(r)}`).join(", ")} } }`:`{ kind: ${g(e.kind)} }`}function Ur(e){let t=[];for(let[n,r]of Object.entries(e.tables)){let a=[];for(let[o,i]of Object.entries(r.relations))i.relation==="manyToMany"&&i.junctionTable&&a.push(`${g(o)}: {
|
|
9064
|
+
targetTable: ${g(i.targetTable)},
|
|
9065
|
+
junctionTable: ${g(i.junctionTable)},
|
|
9066
|
+
sourceField: ${g(i.sourceField??"")},
|
|
9067
|
+
targetField: ${g(i.targetField??"")},
|
|
9068
|
+
},`);a.length!==0&&t.push(`${g(n)}: {
|
|
8877
9069
|
${a.map(o=>` ${o}`).join(`
|
|
8878
9070
|
`)}
|
|
8879
9071
|
},`);}return t.length===0?`export const __appflareManyToMany = {} as const;
|
|
@@ -8881,25 +9073,25 @@ ${a.map(o=>` ${o}`).join(`
|
|
|
8881
9073
|
${t.map(n=>` ${n}`).join(`
|
|
8882
9074
|
`)}
|
|
8883
9075
|
} as const;
|
|
8884
|
-
`}function
|
|
9076
|
+
`}function Qr(e){let t=[];for(let[n,r]of Object.entries(e.tables)){let a=[];for(let[o,i]of Object.entries(r.relations)){if(i.relation==="one"){a.push(`${g(o)}: {
|
|
8885
9077
|
kind: "one",
|
|
8886
|
-
targetTable: ${
|
|
8887
|
-
sourceField: ${
|
|
8888
|
-
referenceField: ${
|
|
8889
|
-
},`);continue}if(
|
|
9078
|
+
targetTable: ${g(i.targetTable)},
|
|
9079
|
+
sourceField: ${g(i.field??"")},
|
|
9080
|
+
referenceField: ${g(i.referenceField??"id")},
|
|
9081
|
+
},`);continue}if(i.relation==="many"){a.push(`${g(o)}: {
|
|
8890
9082
|
kind: "many",
|
|
8891
|
-
targetTable: ${
|
|
8892
|
-
sourceField: ${
|
|
8893
|
-
referenceField: ${
|
|
8894
|
-
},`);continue}a.push(`${
|
|
9083
|
+
targetTable: ${g(i.targetTable)},
|
|
9084
|
+
sourceField: ${g(i.field??"")},
|
|
9085
|
+
referenceField: ${g(i.referenceField??"id")},
|
|
9086
|
+
},`);continue}a.push(`${g(o)}: {
|
|
8895
9087
|
kind: "manyToMany",
|
|
8896
|
-
targetTable: ${
|
|
8897
|
-
junctionTable: ${
|
|
8898
|
-
sourceField: ${
|
|
8899
|
-
targetField: ${
|
|
8900
|
-
referenceField: ${
|
|
8901
|
-
targetReferenceField: ${
|
|
8902
|
-
},`);}a.length!==0&&t.push(`${
|
|
9088
|
+
targetTable: ${g(i.targetTable)},
|
|
9089
|
+
junctionTable: ${g(i.junctionTable??"")},
|
|
9090
|
+
sourceField: ${g(i.sourceField??"")},
|
|
9091
|
+
targetField: ${g(i.targetField??"")},
|
|
9092
|
+
referenceField: ${g(i.referenceField??"id")},
|
|
9093
|
+
targetReferenceField: ${g(i.targetReferenceField??"id")},
|
|
9094
|
+
},`);}a.length!==0&&t.push(`${g(n)}: {
|
|
8903
9095
|
${a.map(o=>` ${o}`).join(`
|
|
8904
9096
|
`)}
|
|
8905
9097
|
},`);}return t.length===0?`export const __appflareRelations = {} as const;
|
|
@@ -8907,46 +9099,53 @@ ${a.map(o=>` ${o}`).join(`
|
|
|
8907
9099
|
${t.map(n=>` ${n}`).join(`
|
|
8908
9100
|
`)}
|
|
8909
9101
|
} as const;
|
|
8910
|
-
`}function
|
|
8911
|
-
${
|
|
9102
|
+
`}function _r(e,t){let n=new Set(Object.keys(e.tables)),r=new Set;for(let l of Object.values(e.tables)){for(let u of Hr(l))n.has(u)||r.add(u);for(let u of Object.values(l.columns))u.references&&!n.has(u.references.table)&&r.add(u.references.table);}let a=new Map;for(let l of Object.values(e.tables))for(let[u,p]of Object.entries(l.columns))if(p.type==="enum"&&p.enumValues&&p.enumValues.length>0){let d=p.enumRef??`${u}`;a.has(d)||a.set(d,p);}let o=[],i=[];for(let[l,u]of a.entries()){let p=M(l),d=u.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=[],c=[];for(let[l,u]of Object.entries(e.tables)){let p=u.sqlName??O(l),d=[],y=[];for(let[b,h]of Object.entries(u.columns)){let T;if(h.type==="enum"&&h.enumValues&&h.enumValues.length>0){let R=h.enumRef??b,j=M(R),V=h.sqlName??O(b);T=V!==b?`${j}Column(${g(V)})`:`${j}Column()`,h.isArray&&(T+=".array()");}else T=Vr(b,h,t);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(${Mr(h.sqlDefault)})`);let C=Lr(b,h,u);if(C)if(h.references?.onDelete||h.references?.onUpdate){let R=[];h.references.onDelete&&R.push(`onDelete: ${g(h.references.onDelete)}`),h.references.onUpdate&&R.push(`onUpdate: ${g(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(${g(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(${g(R)}).on(table.${b})`);}d.push(` ${b}: ${T},`);}y.length>0?s.push(`export const ${l} = table(
|
|
9103
|
+
${g(p)},
|
|
8912
9104
|
{
|
|
8913
|
-
${
|
|
9105
|
+
${d.join(`
|
|
8914
9106
|
`)}
|
|
8915
9107
|
},
|
|
8916
9108
|
(table) => [
|
|
8917
|
-
${
|
|
9109
|
+
${y.join(`,
|
|
8918
9110
|
`)}
|
|
8919
9111
|
],
|
|
8920
|
-
);`):
|
|
8921
|
-
${
|
|
9112
|
+
);`):s.push(`export const ${l} = table(${g(p)}, {
|
|
9113
|
+
${d.join(`
|
|
8922
9114
|
`)}
|
|
8923
|
-
});`);let
|
|
8924
|
-
fields: [${
|
|
8925
|
-
references: [${
|
|
8926
|
-
}),`);}for(let[
|
|
8927
|
-
${
|
|
9115
|
+
});`);let v=Object.entries(u.relations).filter(([,b])=>b.relation==="one"),A=Object.entries(u.relations).filter(([,b])=>b.relation==="many"),w=Object.entries(u.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=Br(l,u,h);I.push(` ${b}: one(${h.targetTable}, {
|
|
9116
|
+
fields: [${l}.${T.sourceField}],
|
|
9117
|
+
references: [${h.targetTable}.${T.targetField}],
|
|
9118
|
+
}),`);}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}),`);}c.push(`export const ${l}Relations = relations(${l}, ({ one, many }) => ({
|
|
9119
|
+
${I.join(`
|
|
8928
9120
|
`)}
|
|
8929
9121
|
}));`);}return `import * as t from "drizzle-orm/sqlite-core";
|
|
8930
9122
|
import { sqliteTable as table } from "drizzle-orm/sqlite-core";
|
|
8931
9123
|
import { relations } from "drizzle-orm";
|
|
8932
|
-
${
|
|
8933
|
-
${
|
|
9124
|
+
${Wr(r)}
|
|
9125
|
+
${o.join(`
|
|
9126
|
+
`)}
|
|
9127
|
+
${i.join(`
|
|
9128
|
+
`)}
|
|
9129
|
+
|
|
9130
|
+
${s.join(`
|
|
8934
9131
|
|
|
8935
9132
|
`)}
|
|
8936
9133
|
|
|
8937
|
-
${
|
|
9134
|
+
${c.join(`
|
|
8938
9135
|
|
|
8939
9136
|
`)}
|
|
8940
9137
|
|
|
8941
|
-
${
|
|
9138
|
+
${zr(e)}
|
|
9139
|
+
|
|
9140
|
+
${Ur(e)}
|
|
8942
9141
|
|
|
8943
|
-
${
|
|
8944
|
-
`}function
|
|
9142
|
+
${Qr(e)}
|
|
9143
|
+
`}function le(e){return e.kind==="array"?`z.array(${le(e.element)})`:e.kind==="object"?`z.object({ ${Object.entries(e.shape).map(([n,r])=>`${g(n)}: ${le(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 fn(e,t,n){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=le(e.jsonShape));return t&&(r+=".optional()"),n&&(r+=".nullable()"),r}function Kr(e){let t=[];for(let[n,r]of Object.entries(e.tables)){let a=M(n),o=[],i=[];for(let[s,c]of Object.entries(r.columns))o.push(` ${s}: ${fn(c,hn(c),E(c))},`),i.push(` ${s}: ${fn(c,E(c),E(c))},`);t.push(`export const ${n}InsertSchema = z.object({
|
|
8945
9144
|
${o.join(`
|
|
8946
9145
|
`)}
|
|
8947
9146
|
});
|
|
8948
9147
|
export const ${n}SelectSchema = z.object({
|
|
8949
|
-
${
|
|
9148
|
+
${i.join(`
|
|
8950
9149
|
`)}
|
|
8951
9150
|
});
|
|
8952
9151
|
|
|
@@ -8955,34 +9154,36 @@ export type ${a}Select = z.infer<typeof ${n}SelectSchema>;
|
|
|
8955
9154
|
`);}return `import { z } from "zod";
|
|
8956
9155
|
|
|
8957
9156
|
${t.join(`
|
|
8958
|
-
`)}`}function
|
|
8959
|
-
${
|
|
9157
|
+
`)}`}function L(e){return e.kind==="array"?`Array<${L(e.element)}>`:e.kind==="object"?`{ ${Object.entries(e.shape).map(([n,r])=>`${n}: ${L(r)}`).join("; ")} }`:e.kind==="string"?"string":e.kind==="number"?"number":e.kind==="boolean"?"boolean":e.kind==="date"?"Date":"unknown"}function Jr(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 t=e.enumValues.map(n=>`"${n}"`).join(" | ");return e.isArray?`Array<${t}>`:t}return e.type==="json"&&e.jsonShape?L(e.jsonShape):"unknown"}function Gr(e){let t=[];for(let[r,a]of Object.entries(e.enums??{})){let o=M(r),i=a.values.map(s=>`"${s}"`).join(" | ");t.push(`export type ${o} = ${i};`);}let n=[];for(let[r,a]of Object.entries(e.tables)){let o=M(r),i=[],s=[];for(let[c,l]of Object.entries(a.columns)){let u=Jr(l),p=E(l)?" | null":"";i.push(` ${c}${E(l)?"?":""}: ${u}${p};`),s.push(` ${c}${hn(l)?"?":""}: ${u}${p};`);}n.push(`export type ${o} = {
|
|
9158
|
+
${i.join(`
|
|
8960
9159
|
`)}
|
|
8961
9160
|
};
|
|
8962
9161
|
|
|
8963
|
-
export type New${
|
|
9162
|
+
export type New${o} = {
|
|
8964
9163
|
${s.join(`
|
|
8965
9164
|
`)}
|
|
8966
9165
|
};`);}return `${t.join(`
|
|
9166
|
+
`)}
|
|
9167
|
+
${n.join(`
|
|
8967
9168
|
|
|
8968
9169
|
`)}
|
|
8969
|
-
`}function
|
|
8970
|
-
`);let u=dirname(fileURLToPath(import.meta.url)),
|
|
8971
|
-
`);let
|
|
8972
|
-
`),...
|
|
8973
|
-
`),Bun.write(
|
|
8974
|
-
`);let
|
|
8975
|
-
`);function
|
|
8976
|
-
`)]),process.stdout.write(`\u{1F4C4} TS configs (${(performance.now()-
|
|
8977
|
-
`);async function
|
|
8978
|
-
`);let
|
|
8979
|
-
`);async function
|
|
8980
|
-
`);let
|
|
8981
|
-
`);let
|
|
8982
|
-
`);let
|
|
8983
|
-
`);}}var
|
|
9170
|
+
`}function Zr(e,t){if(t){let n=e[t];if(!re(n))throw new Error(`schemaDsl.exportName '${t}' does not point to a schema() export.`);return n}for(let n of Object.values(e))if(re(n))return n;throw new Error("No schema() export found in schemaDsl entry module. Set schemaDsl.exportName to the correct export.")}async function yn(e){let t=e.config.schemaDsl;if(!t)return;let n=t.namingStrategy??"camelToSnake",r=resolve(e.configDir,t.entry),a=resolve(e.configDir,t.outFile??resolve(e.outDirAbs,"schema.compiled.ts")),o=resolve(e.configDir,t.typesOutFile??resolve(e.outDirAbs,"schema.types.ts")),i=resolve(e.configDir,t.zodOutFile??resolve(e.outDirAbs,"schema.zod.ts")),c=await import(`${pathToFileURL(r).href}?t=${Date.now()}`),l=Zr(c,t.exportName),u=jr(l);await Promise.all([mkdir(dirname(a),{recursive:true}),mkdir(dirname(o),{recursive:true}),mkdir(dirname(i),{recursive:true})]);let p=_r(u,n),d=Gr(u),y=Kr(u);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(u.tables)}}function Xr(e){return e.replaceAll("\\","/")}function F(e,t){let n=Xr(relative(e,t)).replace(/\.tsx?$/,"");return n.startsWith(".")?n:`./${n}`}var ra=new Set([".ts",".tsx",".mts",".cts"]);async function Tn(e){let t=await readdir(e,{withFileTypes:true}),n=[];for(let r of t){if(r.name.startsWith(".")||r.name==="node_modules"||r.name==="_generated")continue;let a=resolve(e,r.name);if(r.isDirectory()){n.push(...await Tn(a));continue}r.isFile()&&ra.has(extname(r.name))&&n.push(a);}return n}function ue(e){return e.replace(/\.[cm]?tsx?$/,"")}function aa(e,t){let n=e,r=false,a,o="unknown";for(;f.isCallExpression(n);){let i=n.expression;if(!f.isPropertyAccessExpression(i))break;let s=i.name.text;if(s==="optional"||s==="nullable")r=true,n=i.expression;else if(s==="default"){r=true;let c=n.arguments[0];c&&(f.isStringLiteral(c)||f.isNumericLiteral(c)?a=c.text:c.kind===f.SyntaxKind.TrueKeyword?a="true":c.kind===f.SyntaxKind.FalseKeyword&&(a="false")),n=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 n=i.expression;}return {name:t,type:o,optional:r,defaultValue:a}}function oa(e){if(!e||!f.isObjectLiteralExpression(e))return [];let t=e.properties.find(r=>f.isPropertyAssignment(r)&&f.isIdentifier(r.name)&&r.name.text==="args");if(!t||!f.isObjectLiteralExpression(t.initializer))return [];let n=[];for(let r of t.initializer.properties)!f.isPropertyAssignment(r)||!f.isIdentifier(r.name)||n.push(aa(r.initializer,r.name.text));return n}function ia(e){return f.isVariableStatement(e)?e.modifiers?.some(t=>t.kind===f.SyntaxKind.ExportKeyword)??false:false}function vn(e){return f.isIdentifier(e)?e.text:f.isParenthesizedExpression(e)?vn(e.expression):null}function sa(e){if(!e||!f.isObjectLiteralExpression(e))return [];let t=e.properties.find(r=>!f.isPropertyAssignment(r)||!f.isIdentifier(r.name)?false:r.name.text==="cronTrigger");if(!t||!f.isPropertyAssignment(t))return [];let n=t.initializer;return f.isStringLiteral(n)||f.isNoSubstitutionTemplateLiteral(n)?[n.text.trim()].filter(r=>r.length>0):f.isArrayLiteralExpression(n)?n.elements.map(r=>f.isStringLiteral(r)||f.isNoSubstitutionTemplateLiteral(r)?r.text.trim():"").filter(r=>r.length>0):[]}function la(e,t){let n=f.createSourceFile(t,e,f.ScriptTarget.Latest,true,f.ScriptKind.TS),r=[];for(let a of n.statements)if(ia(a))for(let o of a.declarationList.declarations){if(!f.isIdentifier(o.name)||!o.initializer||!f.isCallExpression(o.initializer))continue;let i=vn(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"?sa(o.initializer.arguments[0]):[],args:i==="query"||i==="mutation"?oa(o.initializer.arguments[0]):[]});}return r}function bn(e,t,n){let r=t.replace(/\\/g,"/"),o=ue(r).split("/").filter(Boolean);return `/${[e,...o,n].filter(Boolean).map(s=>s.trim()).filter(s=>s.length>0).join("/")}`}function ua(e,t){let n=e.replace(/\\/g,"/"),r=`${t}/`,a=n.indexOf(r);return a>=0?n.slice(a+r.length):n===t?"index.ts":n}function wn(e,t){let n=e.replace(/\\/g,"/"),a=ue(n).split("/").filter(Boolean),o=a[a.length-1]??"index";return [a.length>1?a[a.length-2]:"root",o,t].map(s=>s.trim()).filter(s=>s.length>0).join("/")}async function Rn(e){let t=[],n=await Tn(e.scanDirAbs).catch(()=>[]);for(let a of n){let o=Bun.file(a);if(!await o.exists())continue;let i=await o.text(),s=relative(e.scanDirAbs,a),c=la(i,a),l=[{kind:"query",kindDirectory:"queries",exports:c.filter(u=>u.kind==="query")},{kind:"mutation",kindDirectory:"mutations",exports:c.filter(u=>u.kind==="mutation")},{kind:"scheduler",kindDirectory:"schedulers",exports:c.filter(u=>u.kind==="scheduler")},{kind:"cron",kindDirectory:"crons",exports:c.filter(u=>u.kind==="cron")},{kind:"storage",kindDirectory:"queries",exports:c.filter(u=>u.kind==="storage")}];for(let u of l){if(u.exports.length===0)continue;let p=ua(s,u.kindDirectory);for(let d of u.exports){let y=u.kind==="query"||u.kind==="mutation"?wn(p,d.exportName):void 0,v=u.kind==="scheduler"||u.kind==="cron"?wn(p,d.exportName):void 0,A=u.kind==="query"||u.kind==="mutation"?[...ue(p).split("/").filter(Boolean),d.exportName]:void 0,w=u.kind==="query"?bn("queries",p,d.exportName):u.kind==="mutation"?bn("mutations",p,d.exportName):u.kind==="storage"?`/storage/managers/${d.exportName}`:`/${u.kindDirectory}/${v}`;t.push({kind:u.kind,exportName:d.exportName,filePath:a,importPath:F(e.outDirAbs,a),clientImportPath:F(resolve(e.outDirAbs,"client"),a),routePath:w,handlerName:y,clientSegments:A,taskName:v,cronTriggers:d.cronTriggers,args:d.args});}}}t.sort((a,o)=>a.routePath.localeCompare(o.routePath));let r=new Map;for(let a of t){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 t}function da(e){let t=[],n="",r=0,a=0,o=0,i=false,s=false,c=false,l=false;for(let p=0;p<e.length;p+=1){let d=e[p];if(l){n+=d,l=false;continue}if(d==="\\"){n+=d,l=true;continue}if(!s&&!c&&d==="'"){i=!i,n+=d;continue}if(!i&&!c&&d==='"'){s=!s,n+=d;continue}if(!i&&!s&&d==="`"){c=!c,n+=d;continue}if(i||s||c){n+=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=n.trim();y.length>0&&t.push(y),n="";continue}n+=d;}let u=n.trim();return u.length>0&&t.push(u),t}function pa(e){let t=0,n=0,r=0,a=false,o=false,i=false,s=false;for(let c=0;c<e.length;c+=1){let l=e[c];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==="("){t+=1;continue}if(l===")"){t-=1;continue}if(l==="{"){n+=1;continue}if(l==="}"){n-=1;continue}if(l==="["){r+=1;continue}if(l==="]"){r-=1;continue}if(l===":"&&t===0&&n===0&&r===0)return c}}return -1}function ma(e){let t=e.toLowerCase();return /mode\s*:\s*["'`](timestamp|timestamp_ms)["'`]/.test(t)?"date":/mode\s*:\s*["'`]boolean["'`]/.test(t)?"boolean":/\.(date|datetime|timestamp)\s*\(/.test(t)?"date":/\.(int|integer|real|numeric|decimal|float|double)\s*\(/.test(t)?"number":/\.(text|varchar|char)\s*\(/.test(t)?"string":/\.(boolean|bool)\s*\(/.test(t)?"boolean":"unknown"}function ga(e){let t=da(e),n=[];for(let r of t){let a=pa(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),c=/autoincrement\s*:\s*true/i.test(i),l=/\.default\s*\(/i.test(i),p=!/\.notnull\s*\(/i.test(i)||l||c||s;n.push({name:o,expression:i,type:ma(i),optional:p,primaryKey:s,autoIncrement:c});}return n}function fa(e){let t=/export\s+const\s+(\w+)\s*=\s*table\s*\(\s*["'`]([^"'`]+)["'`]/g,n=[],r=(o,i)=>{let s=0,c=false,l=false,u=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&&!u&&y==="'"){c=!c;continue}if(!c&&!u&&y==='"'){l=!l;continue}if(!c&&!l&&y==="`"){u=!u;continue}if(!(c||l||u)){if(y==="{"){s+=1;continue}if(y==="}"&&(s-=1,s===0))return d}}return -1},a=t.exec(e);for(;a;){let o=a[1],i=a[2],s=e.indexOf("{",t.lastIndex);if(s===-1){a=t.exec(e);continue}let c=r(e,s);if(c===-1){a=t.exec(e);continue}let l=e.slice(s+1,c);n.push({exportName:o,tableName:i,columns:ga(l)}),a=t.exec(e);}return n}async function Sn(e){let t=await readdir(e,{withFileTypes:true}),n=[];for(let r of t){if(r.name.startsWith(".")||r.name==="node_modules"||r.name==="_generated")continue;let a=resolve(e,r.name);if(r.isDirectory()){n.push(...await Sn(a));continue}r.isFile()&&r.name==="schema.ts"&&n.push(a);}return n}async function An(e,t=[]){let n=await Sn(e.scanDirAbs).catch(()=>[]),r=resolve(e.configDir,"schema.ts"),a=[...t,...n.length?n:[r]];for(let o of a){let i=Bun.file(o);if(!await i.exists())continue;let s=await i.text(),c=fa(s);if(c.length>0)return {schemaPath:o,tables:c}}throw new Error(`Unable to discover schema.ts under scanDir (${e.scanDirAbs}) or fallback (${r}).`)}function ba(e){let t=e.auth.options.plugins;if(!Array.isArray(t))return [];for(let n of t)if(n&&typeof n=="object"){let r=n;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 wa(e,t){let n=relative(e,t).replace(/\\/g,"/");return n.startsWith(".")?n:`./${n}`}async function Cn(e){let{outDirAbs:t,wranglerOutDirAbs:n,config:r,configPath:a,configDir:o}=e,i=F(t,a),s=resolve(t,"client"),c=F(s,a),l=performance.now();await Promise.all([mkdir(t,{recursive:true}),mkdir(s,{recursive:true}),mkdir(n,{recursive:true})]),process.stdout.write(`\u{1F4C1} Directories (${(performance.now()-l).toFixed(0)}ms)
|
|
9171
|
+
`);let u=dirname(fileURLToPath(import.meta.url)),p=join(dirname(Bun.resolveSync("typescript/package.json",u)),"bin","tsc"),d=join(dirname(Bun.resolveSync("@better-auth/cli/package.json",u)),"dist","index.mjs"),y=resolve(t,"server.ts"),v=resolve(t,"client.ts"),A=resolve(t,"auth.config.ts"),w=resolve(t,"auth.schema.ts"),I=resolve(t,"drizzle.config.ts"),b=resolve(n,"wrangler.json"),h=await yn(e),T=await An(e,h?[h.schemaPath]:[]),C=F(t,T.schemaPath),R=await Rn(e);process.stdout.write(`\u{1F50D} ${R.length} handler(s) (${(performance.now()-l).toFixed(0)}ms)
|
|
9172
|
+
`);let j=ba(r),V=xt(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),me=Se(c,R),Vn=Z(C,R,r.r2[0]?.binding,j),Bn=be(i),Wn=h?[wa(o,h.schemaPath),...r.schema.filter(x=>!/(^|\/)schema\.ts$/.test(x))]:r.schema,Hn=Ae(Wn),Ln=vt(e,R),zn=cn(C,T,R),Un=resolve(t,"admin.routes.ts"),Qn=Vn.map(x=>Bun.write(resolve(t,x.relativePath),x.source)),_n=me.map(x=>Bun.write(resolve(t,x.relativePath),x.source));await Promise.all([Bun.write(y,V),Bun.write(v,`export * from "./client/index";
|
|
9173
|
+
`),..._n,...Qn,Bun.write(A,Bn),Bun.write(w,""),Bun.write(I,Hn),Bun.write(b,`${JSON.stringify(Ln,null,2)}
|
|
9174
|
+
`),Bun.write(Un,zn)]),process.stdout.write(`\u{1F4DD} Source artifacts (${(performance.now()-l).toFixed(0)}ms)
|
|
9175
|
+
`);let _=relative(o,A).replace(/\\/g,"/"),Kn=_.startsWith(".")?_:`./${_}`,K=relative(o,w).replace(/\\/g,"/"),Jn=K.startsWith(".")?K:`./${K}`,ge=await Bun.spawn([process.execPath,d,"generate","--config",Kn,"--output",Jn,"--yes"],{cwd:o,stdout:"inherit",stderr:"inherit"}).exited;if(ge!==0)throw new Error(`better-auth generation failed with exit code ${ge}`);process.stdout.write(`\u{1F510} Auth schema (${(performance.now()-l).toFixed(0)}ms)
|
|
9176
|
+
`);function Gn(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 fe=resolve(t,"tsconfig.js.json");await Promise.all([Bun.write(fe,`${JSON.stringify(Gn({declaration:true,emitDeclarationOnly:false}),null,2)}
|
|
9177
|
+
`)]),process.stdout.write(`\u{1F4C4} TS configs (${(performance.now()-l).toFixed(0)}ms)
|
|
9178
|
+
`);async function Zn(x,$){process.stdout.write(`\u2699\uFE0F ${$}... (${(performance.now()-l).toFixed(0)}ms)
|
|
9179
|
+
`);let N=await Bun.spawn([process.execPath,p,"-p",x],{cwd:t,stdout:"inherit",stderr:"inherit"}).exited;if(N!==0)throw new Error(`tsc ${$} failed with exit code ${N}`)}await Zn(fe,"JS files"),process.stdout.write(`\u2705 JS + declarations (${(performance.now()-l).toFixed(0)}ms)
|
|
9180
|
+
`);async function he(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 he(N);}else k.name.endsWith(".ts")&&!k.name.endsWith(".d.ts")&&await rm(N);}}await he(t),process.stdout.write(`\u{1F4E6} Cleaned .ts files (${(performance.now()-l).toFixed(0)}ms)
|
|
9181
|
+
`);let Yn=t+"/";async function ye(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===t)continue;await ye(N);}else !N.startsWith(Yn)&&(k.name.endsWith(".d.ts")||k.name.endsWith(".js"))&&await rm(N);}}await ye(o),process.stdout.write(`\u{1F9F9} Cleanup (${(performance.now()-l).toFixed(0)}ms)
|
|
9182
|
+
`);let Xn=resolve(o,"tsconfig.json");if(e.config.build&&existsSync(Xn)){process.stdout.write(`\u2699\uFE0F Building project... (${(performance.now()-l).toFixed(0)}ms)
|
|
9183
|
+
`);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)
|
|
9184
|
+
`);}}var qn=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(),Mn=z.object({binding:z.string().min(1),id:z.string().min(1),previewId:z.string().min(1).optional()}).strict(),Fn=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(),In=z.object({enabled:z.boolean().optional(),binding:z.string().min(1).optional(),queue:z.string().min(1).optional()}).strict(),Ra=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(),ka=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([qn,z.array(qn).min(1)]),kv:z.union([Mn,z.array(Mn)]).optional(),r2:z.union([Fn,z.array(Fn)]).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:In.optional(),realtime:Ra.optional(),wranglerOverrides:z.record(z.string(),z.unknown()).optional(),build:z.boolean().optional()}).strict();function Pn(e){return typeof e=="object"&&e!==null}function Sa(e){let t=Pn(e.wranglerOverrides)?e.wranglerOverrides.scheduler:void 0,n=In.safeParse(t);return n.success?n.data:{}}function Aa(e){if(!Pn(e)||!("scheduler"in e))return e;let{scheduler:t,...n}=e;return n}function Na(e){let n={...Sa(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:n.enabled??true,binding:n.binding??"APPFLARE_SCHEDULER_QUEUE",queue:n.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:Aa(e.wranglerOverrides),wranglerOutDir:e.wranglerOutDir??e.wranglerOutPath??e.outDir,build:e.build??true}}async function D(e){let t=isAbsolute(e??"")?e:resolve(process.cwd(),e??"appflare.config.ts"),n=dirname(t),o=(await import(pathToFileURL(t).href)).default,i=ka.parse(o),s=Na(i);return {configPath:t,configDir:n,scanDirAbs:resolve(n,s.scanDir),outDirAbs:resolve(n,s.outDir),wranglerOutDirAbs:resolve(n,s.wranglerOutDir),config:s}}function Ma(e){let t=e;for(;;){if(existsSync(resolve(t,"package.json")))return t;let n=dirname(t);if(n===t)return e;t=n;}}async function Q(e,t={}){let n=await D(e);if(t.build!==void 0&&(n.config.build=t.build),await Cn(n),n.wranglerOutDirAbs===n.outDirAbs){process.stdout.write(`\u2705 Generated artifacts in ${n.outDirAbs}
|
|
8984
9185
|
`);return}process.stdout.write(`\u2705 Generated server/client in ${n.outDirAbs} and wrangler.json in ${n.wranglerOutDirAbs}
|
|
8985
|
-
`);}async function
|
|
8986
|
-
`);}finally{r=false,a&&(a=false,await o());}}
|
|
9186
|
+
`);}async function En(e,t={}){if(await Q(e,{build:t.build}),!t.watch)return;let n=await D(e),r=false,a=false,o=async()=>{if(r){a=true;return}r=true;try{await Q(e,{build:t.build});}catch(s){process.stderr.write(`\u274C Build failed: ${s.message}
|
|
9187
|
+
`);}finally{r=false,a&&(a=false,await o());}};$a.watch(n.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,c)=>{process.stdout.write(`\u{1F504} Change detected: ${c}
|
|
8987
9188
|
`),await o();}),process.stdout.write(`\u{1F440} Watching ${n.scanDirAbs}
|
|
8988
|
-
`);}async function
|
|
9189
|
+
`);}async function Dn(e,t={}){let n=await D(e),r=Ma(process.cwd());if([!!t.local,!!t.remote,!!t.preview].filter(Boolean).length>1)throw new Error("Only one of --local, --remote, or --preview can be set.");let o=resolve(n.outDirAbs,"drizzle.config.js"),i=process.platform==="win32"?"npx.cmd":"npx",c=await Bun.spawn([i,"drizzle-kit","generate","--config",o],{cwd:r,stdin:"inherit",stdout:"inherit",stderr:"inherit"}).exited;if(c!==0)throw new Error(`drizzle-kit generate failed with exit code ${c}`);let l=n.config.database[0].databaseName,u=[i,"wrangler","d1","migrations","apply",l];t.local?u.push("--local"):t.remote?u.push("--remote"):t.preview&&u.push("--preview");let d=await Bun.spawn(u,{cwd:n.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 jn(e,t={name:"",email:"",password:""}){let n=await D(e);if([!!t.local,!!t.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(t.password),i=crypto.randomUUID(),s=crypto.randomUUID(),c=Date.now(),l=t.name.replace(/'/g,"''"),u=t.email.replace(/'/g,"''"),p=["INSERT INTO users (id, name, email, email_verified, created_at, updated_at, role, banned)",`VALUES ('${i}', '${l}', '${u}', 1, ${c}, ${c}, 'admin', 0);`,"INSERT INTO accounts (id, account_id, provider_id, user_id, password, created_at, updated_at)",`VALUES ('${s}', '${u}', 'credential', '${i}', '${o}', ${c}, ${c});`].join(" "),d=n.config.database[0].databaseName,v=[process.platform==="win32"?"npx.cmd":"npx","wrangler","d1","execute",d,`--command=${p}`];t.local?v.push("--local"):t.remote&&v.push("--remote");let w=await Bun.spawn(v,{cwd:n.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 "+t.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 En(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 Dn(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 jn(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);});
|