appflare 0.2.26 → 0.2.27
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/cli/templates/core/client/storage.ts +26 -1
- package/cli/templates/core/client/types.ts +2 -0
- package/cli/templates/handlers/generators/context/storage-api.ts +0 -52
- package/cli/templates/handlers/generators/registration/modules/storage.ts +33 -37
- package/cli/templates/handlers/generators/types/context.ts +0 -1
- package/dist/cli/index.js +105 -135
- package/dist/cli/index.mjs +105 -135
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -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 Fn(e){let t=e.replace(/[^A-Za-z0-9_]/g,"_");return /^[0-9]/.test(t)?`_${t}`:t||"_route"}function ae(e){return e.split(/[^A-Za-z0-9]+/).filter(Boolean).map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join("")}function Dn(e){return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(e)?e:JSON.stringify(e)}function oe(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 V(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}${Dn(i)}: ${V(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 En(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===0)return null;let r=Fn(`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:`${ae(e.kind)}${ae(n.join("_"))}`}}function On(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,7 +353,7 @@ export function createAppflare<Options extends BetterAuthClientOptions = Inferre
|
|
|
353
353
|
schema: ${r},
|
|
354
354
|
run,
|
|
355
355
|
};
|
|
356
|
-
};`}function B(e){let t=e.map((u,c)=>
|
|
356
|
+
};`}function B(e){let t=e.map((u,c)=>En(u,c)).filter(u=>u!==null),n=t.filter(u=>u.kind==="query"),r=t.filter(u=>u.kind==="mutation"),a=t.map(u=>`import { ${u.exportName} as ${u.alias} } from "${u.importPath}";`).join(`
|
|
357
357
|
`),o=t.map(u=>{let c=`${u.typeBase}Input`,f=`${u.typeBase}Output`,d=`${u.typeBase}Schema`;return `const ${u.schemaConst} = z.object(${u.alias}.definition.args);
|
|
358
358
|
export type ${c} = z.input<typeof ${u.schemaConst}>;
|
|
359
359
|
export type ${f} = Awaited<ReturnType<typeof ${u.alias}.definition.handler>>;
|
|
@@ -809,6 +809,26 @@ export function createStorageClient(
|
|
|
809
809
|
): StorageClient {
|
|
810
810
|
return {
|
|
811
811
|
upload: async (args) => {
|
|
812
|
+
let base64BodyToSend: string | undefined;
|
|
813
|
+
|
|
814
|
+
if (args.body instanceof File) {
|
|
815
|
+
const buffer = await args.body.arrayBuffer();
|
|
816
|
+
const bytes = new Uint8Array(buffer);
|
|
817
|
+
let binary = "";
|
|
818
|
+
const chunkSize = 8192;
|
|
819
|
+
for (let i = 0; i < bytes.length; i += chunkSize) {
|
|
820
|
+
const chunk = bytes.subarray(i, i + chunkSize);
|
|
821
|
+
binary += String.fromCharCode(...chunk);
|
|
822
|
+
}
|
|
823
|
+
base64BodyToSend = btoa(binary);
|
|
824
|
+
} else if (typeof args.body === "string") {
|
|
825
|
+
base64BodyToSend = btoa(args.body);
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
if (args.base64Body) {
|
|
829
|
+
base64BodyToSend = args.base64Body;
|
|
830
|
+
}
|
|
831
|
+
|
|
812
832
|
const headers = await createAuthorizedHeaders(
|
|
813
833
|
{
|
|
814
834
|
"content-type": "application/json",
|
|
@@ -819,7 +839,12 @@ export function createStorageClient(
|
|
|
819
839
|
const response = await request(\`\${endpoint}/storage/upload\`, {
|
|
820
840
|
method: "POST",
|
|
821
841
|
headers,
|
|
822
|
-
body: JSON.stringify(
|
|
842
|
+
body: JSON.stringify({
|
|
843
|
+
path: args.path,
|
|
844
|
+
contentType: args.contentType,
|
|
845
|
+
expiresIn: args.expiresIn,
|
|
846
|
+
base64Body: base64BodyToSend,
|
|
847
|
+
}),
|
|
823
848
|
});
|
|
824
849
|
if (!response.ok) {
|
|
825
850
|
throw new Error(await response.text());
|
|
@@ -1067,6 +1092,8 @@ export type StorageClient = {
|
|
|
1067
1092
|
path: string;
|
|
1068
1093
|
contentType?: string;
|
|
1069
1094
|
expiresIn?: number;
|
|
1095
|
+
base64Body?: string;
|
|
1096
|
+
body?: string | File;
|
|
1070
1097
|
}) => Promise<StorageSignedUrlResponse>;
|
|
1071
1098
|
download: (args: {
|
|
1072
1099
|
path: string;
|
|
@@ -1278,28 +1305,6 @@ function createStorageApi(
|
|
|
1278
1305
|
contentType: args.contentType,
|
|
1279
1306
|
});
|
|
1280
1307
|
|
|
1281
|
-
if (args.returnSignedUrlOnly) {
|
|
1282
|
-
const currentBucket = requireBucket();
|
|
1283
|
-
if (typeof currentBucket.createPresignedUrl !== "function") {
|
|
1284
|
-
throw new Error("R2 createPresignedUrl is unavailable for this runtime binding");
|
|
1285
|
-
}
|
|
1286
|
-
|
|
1287
|
-
const signedRequest = buildSignedRequest(
|
|
1288
|
-
{
|
|
1289
|
-
path,
|
|
1290
|
-
method: "PUT",
|
|
1291
|
-
contentType: args.contentType,
|
|
1292
|
-
expiresIn: args.expiresIn,
|
|
1293
|
-
},
|
|
1294
|
-
path,
|
|
1295
|
-
);
|
|
1296
|
-
const signedUrl = await currentBucket.createPresignedUrl(signedRequest, {
|
|
1297
|
-
expiresIn: args.expiresIn ?? 60 * 5,
|
|
1298
|
-
});
|
|
1299
|
-
|
|
1300
|
-
return signedUrl.toString();
|
|
1301
|
-
}
|
|
1302
|
-
|
|
1303
1308
|
return requireBucket().put(path, args.body, {
|
|
1304
1309
|
httpMetadata: {
|
|
1305
1310
|
...(args.httpMetadata ?? {}),
|
|
@@ -1344,36 +1349,6 @@ function createStorageApi(
|
|
|
1344
1349
|
include: args.include,
|
|
1345
1350
|
});
|
|
1346
1351
|
},
|
|
1347
|
-
signedUrl: async (args) => {
|
|
1348
|
-
const path = normalizeStoragePath(args.path);
|
|
1349
|
-
const requestMethod = args.method ?? "GET";
|
|
1350
|
-
const method: StorageMethod =
|
|
1351
|
-
requestMethod === "PUT"
|
|
1352
|
-
? "put"
|
|
1353
|
-
: requestMethod === "DELETE"
|
|
1354
|
-
? "delete"
|
|
1355
|
-
: args.downloadAsAttachment === false
|
|
1356
|
-
? "preview"
|
|
1357
|
-
: "download";
|
|
1358
|
-
|
|
1359
|
-
await assertAuthorized({
|
|
1360
|
-
path: "/" + path,
|
|
1361
|
-
method,
|
|
1362
|
-
contentType: args.contentType,
|
|
1363
|
-
});
|
|
1364
|
-
|
|
1365
|
-
const currentBucket = requireBucket();
|
|
1366
|
-
if (typeof currentBucket.createPresignedUrl !== "function") {
|
|
1367
|
-
throw new Error("R2 createPresignedUrl is unavailable for this runtime binding");
|
|
1368
|
-
}
|
|
1369
|
-
|
|
1370
|
-
const signedRequest = buildSignedRequest(args, path);
|
|
1371
|
-
const signedUrl = await currentBucket.createPresignedUrl(signedRequest, {
|
|
1372
|
-
expiresIn: args.expiresIn ?? 60 * 5,
|
|
1373
|
-
});
|
|
1374
|
-
|
|
1375
|
-
return signedUrl.toString();
|
|
1376
|
-
},
|
|
1377
1352
|
};
|
|
1378
1353
|
}
|
|
1379
1354
|
`}function be(e){return `
|
|
@@ -3618,7 +3593,7 @@ type TableInsertModel<TName extends TableName> = InferInsertModel<
|
|
|
3618
3593
|
);
|
|
3619
3594
|
});
|
|
3620
3595
|
},
|
|
3621
|
-
`}function
|
|
3596
|
+
`}function Ce(){return `export function createQueryDb(
|
|
3622
3597
|
$db: AppflareDb,
|
|
3623
3598
|
options?: QueryDbOptions,
|
|
3624
3599
|
): AppflareQueryDb {
|
|
@@ -3660,7 +3635,7 @@ type TableInsertModel<TName extends TableName> = InferInsertModel<
|
|
|
3660
3635
|
};
|
|
3661
3636
|
|
|
3662
3637
|
const tableApi = {
|
|
3663
|
-
`}function
|
|
3638
|
+
`}function Ie(){return ` insert: async <TArgs extends QueryInsertArgs<TableName>>(args: TArgs) => {
|
|
3664
3639
|
const transaction = ($db as any).transaction;
|
|
3665
3640
|
|
|
3666
3641
|
const valuesArray = Array.isArray(args.values)
|
|
@@ -4333,7 +4308,7 @@ type TableInsertModel<TName extends TableName> = InferInsertModel<
|
|
|
4333
4308
|
);
|
|
4334
4309
|
return rows;
|
|
4335
4310
|
},
|
|
4336
|
-
`}function Me(){return [
|
|
4311
|
+
`}function Me(){return [Ce(),qe(),Ie(),Ne(),$e()].join(`
|
|
4337
4312
|
|
|
4338
4313
|
`)}function Pe(){return `type AuthSession = typeof auth.$Infer.Session;
|
|
4339
4314
|
type AuthAdapter = Awaited<typeof auth.$context>["internalAdapter"];
|
|
@@ -4385,7 +4360,6 @@ export type AppflareStorage = {
|
|
|
4385
4360
|
get: (args: StorageGetArgs) => Promise<unknown | null>;
|
|
4386
4361
|
delete: (args: StorageDeleteArgs) => Promise<void>;
|
|
4387
4362
|
list: (args?: StorageListArgs) => Promise<unknown>;
|
|
4388
|
-
signedUrl: (args: StorageSignedUrlArgs) => Promise<string>;
|
|
4389
4363
|
};
|
|
4390
4364
|
|
|
4391
4365
|
export type AppflareContext = {
|
|
@@ -4400,7 +4374,7 @@ export type AppflareContext = {
|
|
|
4400
4374
|
storage: AppflareStorage;
|
|
4401
4375
|
error: (status: number, message: string, details?: unknown) => never;
|
|
4402
4376
|
};
|
|
4403
|
-
`}function
|
|
4377
|
+
`}function Fe(){return `type InferOperationArgs<TShape extends ZodRawShape> = z.output<z.ZodObject<TShape>>;
|
|
4404
4378
|
|
|
4405
4379
|
export type SchedulerEnqueueOptions = {
|
|
4406
4380
|
delaySeconds?: number;
|
|
@@ -4532,9 +4506,9 @@ export function cron(definition: CronDefinition): RegisteredCron {
|
|
|
4532
4506
|
definition,
|
|
4533
4507
|
};
|
|
4534
4508
|
}
|
|
4535
|
-
`}function De(){return [ve(),Ae(),Me(),Pe(),
|
|
4509
|
+
`}function De(){return [ve(),Ae(),Me(),Pe(),Fe()].join(`
|
|
4536
4510
|
|
|
4537
|
-
`)}function
|
|
4511
|
+
`)}function Ee(e){return `import type { Context } from "hono";
|
|
4538
4512
|
import type { D1Database } from "@cloudflare/workers-types";
|
|
4539
4513
|
import { drizzle } from "drizzle-orm/d1";
|
|
4540
4514
|
import { z, type ZodRawShape } from "zod";
|
|
@@ -4545,7 +4519,7 @@ ${De()}
|
|
|
4545
4519
|
`}function jn(e){let t=e.replace(/[^A-Za-z0-9_]/g,"_");return /^[0-9]/.test(t)?`_${t}`:t}function Vn(e,t){let n=e.routePath.replace(/^\//,"").replace(/\//g,"_");return jn(`op_${t}_${n}`)}function Bn(e){return e.map((t,n)=>({operation:t,index:n,alias:Vn(t,n)}))}function Hn(e){return e.map(({operation:t,alias:n})=>`import { ${t.exportName} as ${n} } from "${t.importPath}";`).join(`
|
|
4546
4520
|
`)}function Wn(e){return e.filter(({operation:t})=>t.kind==="query"||t.kind==="mutation").map(({alias:t})=>`const ${`${t}Schema`} = z.object(${t}.definition.args);`).join(`
|
|
4547
4521
|
`)}function Ln(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(`
|
|
4548
|
-
`)}function
|
|
4522
|
+
`)}function zn(e){return e.filter(({operation:t})=>t.kind==="query").map(({operation:t,alias:n})=>{let r=`${n}Schema`;return `
|
|
4549
4523
|
app.get(
|
|
4550
4524
|
"${t.routePath}",
|
|
4551
4525
|
sValidator("query", ${r}),
|
|
@@ -4558,7 +4532,7 @@ ${De()}
|
|
|
4558
4532
|
}
|
|
4559
4533
|
},
|
|
4560
4534
|
);`}).join(`
|
|
4561
|
-
`)}function
|
|
4535
|
+
`)}function Un(e){return e.filter(({operation:t})=>t.kind==="mutation").map(({operation:t,alias:n})=>{let r=`${n}Schema`;return `
|
|
4562
4536
|
app.post(
|
|
4563
4537
|
"${t.routePath}",
|
|
4564
4538
|
sValidator("json", ${r}),
|
|
@@ -4592,7 +4566,7 @@ ${De()}
|
|
|
4592
4566
|
},`}).join(`
|
|
4593
4567
|
`)}function Jn(e){return e.filter(({operation:t})=>t.kind==="storage").map(({alias:t})=>`
|
|
4594
4568
|
${t}.definition.handler,`).join(`
|
|
4595
|
-
`)}function Oe(e){let t=Bn(e);return {imports:Hn(t),operationSchemas:Wn(t),schedulerSchemas:Ln(t),queryRoutes:
|
|
4569
|
+
`)}function Oe(e){let t=Bn(e);return {imports:Hn(t),operationSchemas:Wn(t),schedulerSchemas:Ln(t),queryRoutes:zn(t),mutationRoutes:Un(t),queryRegistryEntries:Qn(t),schedulerEntries:_n(t),schedulerPayloadMapEntries:Kn(t),cronEntries:Gn(t),storageHandlersEntries:Jn(t)}}var je=`
|
|
4596
4570
|
function getRealtimeStub(
|
|
4597
4571
|
env: Record<string, unknown>,
|
|
4598
4572
|
options: RegisterHandlersOptions,
|
|
@@ -5617,9 +5591,9 @@ function doesSubscriptionMatchMutation(
|
|
|
5617
5591
|
|
|
5618
5592
|
return false;
|
|
5619
5593
|
}
|
|
5620
|
-
`;var
|
|
5594
|
+
`;var ze=[We,Le,je,Be,He,Ve].join(`
|
|
5621
5595
|
|
|
5622
|
-
`);var
|
|
5596
|
+
`);var Ue=`
|
|
5623
5597
|
function parseExpiresIn(value: string | undefined): number | undefined {
|
|
5624
5598
|
if (!value) {
|
|
5625
5599
|
return undefined;
|
|
@@ -5658,25 +5632,34 @@ export function registerGeneratedStorageRoutes(
|
|
|
5658
5632
|
const path = toStoragePath(String(body.path ?? ""));
|
|
5659
5633
|
const contentType =
|
|
5660
5634
|
typeof body.contentType === "string" ? body.contentType : undefined;
|
|
5661
|
-
const
|
|
5662
|
-
|
|
5663
|
-
? Math.floor(body.expiresIn)
|
|
5664
|
-
: undefined;
|
|
5635
|
+
const encodedBody = typeof body.body === "string" ? body.body : undefined;
|
|
5636
|
+
const base64Body = typeof body.base64Body === "string" ? body.base64Body : undefined;
|
|
5665
5637
|
|
|
5666
|
-
|
|
5638
|
+
if (!base64Body && !encodedBody) {
|
|
5639
|
+
return c.json(
|
|
5640
|
+
{ message: "File content is required. Provide either 'body' or 'base64Body' field." },
|
|
5641
|
+
400,
|
|
5642
|
+
);
|
|
5643
|
+
}
|
|
5644
|
+
|
|
5645
|
+
const uploadBody = base64Body
|
|
5646
|
+
? Uint8Array.from(atob(base64Body), (char) => char.charCodeAt(0))
|
|
5647
|
+
: encodedBody
|
|
5648
|
+
? Uint8Array.from(atob(encodedBody), (char) => char.charCodeAt(0))
|
|
5649
|
+
: new Uint8Array();
|
|
5650
|
+
|
|
5651
|
+
await ctx.storage.put({
|
|
5667
5652
|
path,
|
|
5668
|
-
body:
|
|
5653
|
+
body: uploadBody,
|
|
5669
5654
|
contentType,
|
|
5670
|
-
expiresIn,
|
|
5671
|
-
returnSignedUrlOnly: true,
|
|
5672
5655
|
});
|
|
5673
5656
|
|
|
5674
5657
|
return c.json({
|
|
5675
|
-
url,
|
|
5658
|
+
url: null,
|
|
5676
5659
|
method: "PUT",
|
|
5677
5660
|
path,
|
|
5678
5661
|
contentType,
|
|
5679
|
-
|
|
5662
|
+
uploaded: true,
|
|
5680
5663
|
}, 200);
|
|
5681
5664
|
} catch (error) {
|
|
5682
5665
|
if (error instanceof AppflareHandledError) {
|
|
@@ -5696,20 +5679,13 @@ export function registerGeneratedStorageRoutes(
|
|
|
5696
5679
|
const path = readStoragePath(c);
|
|
5697
5680
|
const fileName = c.req.query("fileName") ?? undefined;
|
|
5698
5681
|
const expiresIn = parseExpiresIn(c.req.query("expiresIn"));
|
|
5699
|
-
|
|
5700
|
-
|
|
5701
|
-
|
|
5702
|
-
|
|
5703
|
-
|
|
5704
|
-
|
|
5705
|
-
|
|
5706
|
-
|
|
5707
|
-
return c.json({
|
|
5708
|
-
url,
|
|
5709
|
-
method: "GET",
|
|
5710
|
-
path,
|
|
5711
|
-
disposition: "attachment",
|
|
5712
|
-
}, 200);
|
|
5682
|
+
|
|
5683
|
+
// For now, we'll return an error since signed URLs are not available
|
|
5684
|
+
// In the future, we could implement direct file serving here
|
|
5685
|
+
return c.json(
|
|
5686
|
+
{ message: "Download via signed URL is not available in this runtime. Use direct file access instead." },
|
|
5687
|
+
501,
|
|
5688
|
+
);
|
|
5713
5689
|
} catch (error) {
|
|
5714
5690
|
if (error instanceof AppflareHandledError) {
|
|
5715
5691
|
return c.json(error.payload, error.status as any);
|
|
@@ -5727,19 +5703,13 @@ export function registerGeneratedStorageRoutes(
|
|
|
5727
5703
|
try {
|
|
5728
5704
|
const path = readStoragePath(c);
|
|
5729
5705
|
const expiresIn = parseExpiresIn(c.req.query("expiresIn"));
|
|
5730
|
-
|
|
5731
|
-
|
|
5732
|
-
|
|
5733
|
-
|
|
5734
|
-
|
|
5735
|
-
|
|
5736
|
-
|
|
5737
|
-
return c.json({
|
|
5738
|
-
url,
|
|
5739
|
-
method: "GET",
|
|
5740
|
-
path,
|
|
5741
|
-
disposition: "inline",
|
|
5742
|
-
}, 200);
|
|
5706
|
+
|
|
5707
|
+
// For now, we'll return an error since signed URLs are not available
|
|
5708
|
+
// In the future, we could implement direct file serving here
|
|
5709
|
+
return c.json(
|
|
5710
|
+
{ message: "Preview via signed URL is not available in this runtime. Use direct file access instead." },
|
|
5711
|
+
501,
|
|
5712
|
+
);
|
|
5743
5713
|
} catch (error) {
|
|
5744
5714
|
if (error instanceof AppflareHandledError) {
|
|
5745
5715
|
return c.json(error.payload, error.status as any);
|
|
@@ -5953,7 +5923,7 @@ setStorageHandlers([...storageHandlers]);
|
|
|
5953
5923
|
|
|
5954
5924
|
${Qe}
|
|
5955
5925
|
|
|
5956
|
-
${
|
|
5926
|
+
${ze}
|
|
5957
5927
|
|
|
5958
5928
|
export function registerGeneratedHandlers(
|
|
5959
5929
|
app: Hono<WorkerEnv>,
|
|
@@ -5966,10 +5936,10 @@ export function registerGeneratedHandlers(
|
|
|
5966
5936
|
`}
|
|
5967
5937
|
}
|
|
5968
5938
|
|
|
5969
|
-
${
|
|
5939
|
+
${Ue}
|
|
5970
5940
|
|
|
5971
5941
|
${_e}
|
|
5972
|
-
`}function H(e,t,n){let r=
|
|
5942
|
+
`}function H(e,t,n){let r=Ee(e),a=ye(n),o=xe(),i=Ke(t);return [{relativePath:"handlers.ts",source:r},{relativePath:"handlers.context.ts",source:a},{relativePath:"handlers.execution.ts",source:o},{relativePath:"handlers.routes.ts",source:i}]}function Zn(e){return e?`,
|
|
5973
5943
|
KV: c.env["${e}"] as KVNamespace`:""}function Ge(e,t){return `{
|
|
5974
5944
|
DATABASE: c.env["${e}"] as D1Database${Zn(t)}
|
|
5975
5945
|
}`}function Je(e,t,n){return `app.on(["GET", "POST"], "${e}/*", async (c) => {
|
|
@@ -6182,7 +6152,7 @@ import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@clou
|
|
|
6182
6152
|
<label class="label"><span class="label-text text-sm font-medium">${t}</span></label>
|
|
6183
6153
|
<input type="${o}" name="${t}" class="input input-bordered w-full text-sm"${a} />
|
|
6184
6154
|
</div>
|
|
6185
|
-
`}function
|
|
6155
|
+
`}function z(e,t){return t.map(n=>{let r=e.columns.find(o=>o.name===n);if(!r)return "";let a=r.optional?"":`
|
|
6186
6156
|
if (raw_${n} === '') {
|
|
6187
6157
|
return c.text('${n} is required', 400);
|
|
6188
6158
|
}
|
|
@@ -6280,7 +6250,7 @@ import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@clou
|
|
|
6280
6250
|
</div>
|
|
6281
6251
|
</div>
|
|
6282
6252
|
</div>
|
|
6283
|
-
</td>`:'<td class="text-right"><span class="text-xs opacity-30">No primary key</span></td>'}function
|
|
6253
|
+
</td>`:'<td class="text-right"><span class="text-xs opacity-30">No primary key</span></td>'}function C(e){return `
|
|
6284
6254
|
<div class="flex flex-col sm:flex-row justify-between items-center mt-4 gap-3 py-3 px-1">
|
|
6285
6255
|
<div class="text-xs text-base-content/40">
|
|
6286
6256
|
Total found: <span class="font-medium text-base-content/60">\${total}</span>
|
|
@@ -6302,7 +6272,7 @@ import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@clou
|
|
|
6302
6272
|
\` : 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>\`}
|
|
6303
6273
|
</div>
|
|
6304
6274
|
\` : ''}
|
|
6305
|
-
</div>`}function
|
|
6275
|
+
</div>`}function I(e,t="Search term or filter..."){return `
|
|
6306
6276
|
<div class="form-control w-full md:w-auto relative">
|
|
6307
6277
|
<iconify-icon icon="mdi:magnify" width="18" height="18" class="absolute left-3 top-1/2 -translate-y-1/2 opacity-40"></iconify-icon>
|
|
6308
6278
|
<input type="text"
|
|
@@ -6313,7 +6283,7 @@ import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@clou
|
|
|
6313
6283
|
hx-trigger="keyup changed delay:500ms, search"
|
|
6314
6284
|
hx-target="#main-content"
|
|
6315
6285
|
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" />
|
|
6316
|
-
</div>`}function yt(e,t,n,r,a,o,i,s,l,u){let c=
|
|
6286
|
+
</div>`}function yt(e,t,n,r,a,o,i,s,l,u){let c=C(`/admin/table/${e.exportName}`),f=I(`/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>',w=r?`
|
|
6317
6287
|
<div id="bulk-delete-bar-${e.exportName}" class="fixed bottom-4 left-1/2 -translate-x-1/2 z-40 hidden">
|
|
6318
6288
|
<div class="bg-base-100 border border-base-200 rounded-xl shadow-lg px-3 py-2 flex items-center gap-3">
|
|
6319
6289
|
<div class="text-xs text-base-content/70">
|
|
@@ -6698,7 +6668,7 @@ import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@clou
|
|
|
6698
6668
|
return c.redirect('/admin/table/${e}?' + query.toString());
|
|
6699
6669
|
});
|
|
6700
6670
|
${c}
|
|
6701
|
-
`}function
|
|
6671
|
+
`}function U(e){let t=gt(e),n=!!t,r=e.columns.map(m=>m.name),a=r.filter(m=>ft(e,m)),o=r.filter(m=>ht(e,m)),i=dt(e),s=pt(e,r),l=mt(r,t),u=a.map(m=>L(e,m,"create")).join(""),c=o.map(m=>L(e,m,"edit")).join(""),f=z(e,a),d=z(e,o),y=n?t:r[0]||"id",w=e.columns.find(m=>m.name===t)?.type,b=bt(e,n,t,c);return yt(e,y,t,n,r,i,s,l,b,u)+`
|
|
6702
6672
|
`+wt(e.exportName,y,t,w,n,i,f,d)}function xt(){return `
|
|
6703
6673
|
const buildUsersRedirect = (params: { page?: string; sort?: string; order?: string; search?: string }) => {
|
|
6704
6674
|
const page = params.page && params.page.trim() ? params.page : '1';
|
|
@@ -6749,7 +6719,7 @@ ${c}
|
|
|
6749
6719
|
<label class="modal-backdrop" for="delete-user-modal-\${String((row as any).id)}">Close</label>
|
|
6750
6720
|
</div>
|
|
6751
6721
|
\`}`}var nr=["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 ar(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 Rt(){let e=nr.map(ar).join(`
|
|
6752
|
-
`),t=
|
|
6722
|
+
`),t=C("/admin/users");return `
|
|
6753
6723
|
const tableHtml = html\`
|
|
6754
6724
|
<div class="bg-base-100 rounded-xl border border-base-200 overflow-hidden">
|
|
6755
6725
|
<div class="overflow-x-auto">
|
|
@@ -6846,7 +6816,7 @@ ${Tt()}
|
|
|
6846
6816
|
<iconify-icon icon="mdi:refresh" width="14" height="14"></iconify-icon>
|
|
6847
6817
|
</button>
|
|
6848
6818
|
</div>
|
|
6849
|
-
${
|
|
6819
|
+
${I("/admin/users","Search users...")}
|
|
6850
6820
|
</div>
|
|
6851
6821
|
\${tableHtml}
|
|
6852
6822
|
</div>
|
|
@@ -7064,7 +7034,7 @@ ${Tt()}
|
|
|
7064
7034
|
${St()}
|
|
7065
7035
|
|
|
7066
7036
|
${At()}
|
|
7067
|
-
`}function Nt(e){return `${e.tables.map(t=>
|
|
7037
|
+
`}function Nt(e){return `${e.tables.map(t=>U(t)).join(`
|
|
7068
7038
|
`)}
|
|
7069
7039
|
${Q()}`}function $t(e){return `
|
|
7070
7040
|
<div class="flex items-center justify-between">
|
|
@@ -7205,7 +7175,7 @@ ${Q()}`}function $t(e){return `
|
|
|
7205
7175
|
</form>
|
|
7206
7176
|
</div>
|
|
7207
7177
|
</div>
|
|
7208
|
-
`}function
|
|
7178
|
+
`}function Ct(){return `
|
|
7209
7179
|
<div class="card bg-base-100 border border-base-200 shadow-sm overflow-hidden flex flex-col">
|
|
7210
7180
|
<!-- Panel Header -->
|
|
7211
7181
|
<div class="px-5 py-3 border-b border-base-200 bg-base-200/20 flex items-center justify-between">
|
|
@@ -7287,7 +7257,7 @@ ${Q()}`}function $t(e){return `
|
|
|
7287
7257
|
|
|
7288
7258
|
</div>
|
|
7289
7259
|
</div>
|
|
7290
|
-
`}function
|
|
7260
|
+
`}function It(e){let t=e.kind==="query",n=e.routePath,r=e.handlerName??e.routePath;return `
|
|
7291
7261
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/atom-one-dark.min.css">
|
|
7292
7262
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
|
|
7293
7263
|
|
|
@@ -7839,11 +7809,11 @@ ${Q()}`}function $t(e){return `
|
|
|
7839
7809
|
${qt(e)}
|
|
7840
7810
|
|
|
7841
7811
|
<!-- Result Panel -->
|
|
7842
|
-
${
|
|
7812
|
+
${Ct()}
|
|
7843
7813
|
</div>
|
|
7844
7814
|
</div>
|
|
7845
7815
|
|
|
7846
|
-
${
|
|
7816
|
+
${It(e)}
|
|
7847
7817
|
\`;
|
|
7848
7818
|
|
|
7849
7819
|
if (c.req.header('hx-request')) {
|
|
@@ -7857,7 +7827,7 @@ ${Q()}`}function $t(e){return `
|
|
|
7857
7827
|
adminApp.get('/functions${n.routePath}', (c) => {
|
|
7858
7828
|
${Mt(n)}
|
|
7859
7829
|
});`).join(`
|
|
7860
|
-
`)}function
|
|
7830
|
+
`)}function Ft(){return `
|
|
7861
7831
|
const getStorageBucket = (c: any): R2Bucket | null => {
|
|
7862
7832
|
const r2Binding = (options as any).r2Binding;
|
|
7863
7833
|
if (!r2Binding || !c.env[r2Binding]) return null;
|
|
@@ -8053,7 +8023,7 @@ ${Q()}`}function $t(e){return `
|
|
|
8053
8023
|
</div>
|
|
8054
8024
|
\`;
|
|
8055
8025
|
};
|
|
8056
|
-
`}function
|
|
8026
|
+
`}function Et(){return `
|
|
8057
8027
|
const handleStorageListRoute = async (c: any) => {
|
|
8058
8028
|
const bucket = getStorageBucket(c);
|
|
8059
8029
|
if (!bucket) {
|
|
@@ -8183,14 +8153,14 @@ ${Q()}`}function $t(e){return `
|
|
|
8183
8153
|
|
|
8184
8154
|
${Vt()}
|
|
8185
8155
|
|
|
8186
|
-
${Ft()}
|
|
8187
|
-
`}function Lt(){return `
|
|
8188
8156
|
${Et()}
|
|
8157
|
+
`}function Lt(){return `
|
|
8158
|
+
${Ft()}
|
|
8189
8159
|
|
|
8190
8160
|
${Dt()}
|
|
8191
8161
|
|
|
8192
8162
|
${Wt()}
|
|
8193
|
-
`}function
|
|
8163
|
+
`}function zt(e,t){let n=ct(t);return `
|
|
8194
8164
|
function Layout(props: { children: any; title: string; hideSidebar?: boolean }) {
|
|
8195
8165
|
return html\`<!DOCTYPE html>
|
|
8196
8166
|
<html lang="en" data-theme="light">
|
|
@@ -8565,7 +8535,7 @@ function Layout(props: { children: any; title: string; hideSidebar?: boolean })
|
|
|
8565
8535
|
</body>
|
|
8566
8536
|
</html>\`;
|
|
8567
8537
|
}
|
|
8568
|
-
`}function
|
|
8538
|
+
`}function Ut(){return `
|
|
8569
8539
|
// Auth Middleware
|
|
8570
8540
|
adminApp.use('*', async (c, next) => {
|
|
8571
8541
|
const auth = createAuth({ DATABASE: c.env[options.databaseBinding] } as any, c.req.raw.cf as any);
|
|
@@ -8641,7 +8611,7 @@ function Layout(props: { children: any; title: string; hideSidebar?: boolean })
|
|
|
8641
8611
|
\`
|
|
8642
8612
|
}));
|
|
8643
8613
|
});
|
|
8644
|
-
`}function _t(e,t,n){let r=st(t),a=lt(r),o=ut(r),i=Nt(t),s=Pt(n),l=Lt(),u=
|
|
8614
|
+
`}function _t(e,t,n){let r=st(t),a=lt(r),o=ut(r),i=Nt(t),s=Pt(n),l=Lt(),u=zt(a,n),c=Ut(),f=Qt(o);return `import { Hono } from "hono";
|
|
8645
8615
|
import { html, raw } from "hono/html";
|
|
8646
8616
|
import { drizzle } from "drizzle-orm/d1";
|
|
8647
8617
|
import { eq, desc, asc, sql, like, or, inArray } from "drizzle-orm";
|
|
@@ -8670,7 +8640,7 @@ ${f}
|
|
|
8670
8640
|
app.route('/admin', adminApp);
|
|
8671
8641
|
app.get('/admin/', (c) => c.redirect('/admin'));
|
|
8672
8642
|
}
|
|
8673
|
-
`}function _(e){if(typeof e!="object"||e===null)return false;let t=e;return t.kind==="schema"&&typeof t.tables=="object"}function M(e){return e.replace(/([a-z0-9])([A-Z])/g,"$1_$2").replace(/[\s-]+/g,"_").toLowerCase()}function
|
|
8643
|
+
`}function _(e){if(typeof e!="object"||e===null)return false;let t=e;return t.kind==="schema"&&typeof t.tables=="object"}function M(e){return e.replace(/([a-z0-9])([A-Z])/g,"$1_$2").replace(/[\s-]+/g,"_").toLowerCase()}function F(e){return e.replace(/[_-]+/g," ").replace(/\s+(.)/g,(t,n)=>n.toUpperCase()).replace(/\s/g,"").replace(/^(.)/,(t,n)=>n.toUpperCase())}function J(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 h(e){return JSON.stringify(e)}function dr(e){if(typeof e=="string")return h(e);if(typeof e=="number"||typeof e=="boolean")return String(e);if(e===null)return "null";if(e instanceof Date)return h(e.toISOString());throw new Error(`Unsupported SQL default value '${String(e)}'. Use string, number, boolean, null, or Date.`)}function pr(e){return {kind:"schema",tables:Object.fromEntries(Object.entries(e.tables).map(([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}]))}]))}}function P(e,t,n){let r=e.tables[t];return r?r.columns[n]?.type:void 0}function Kt(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 Gt(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 Jt(e,t){return `${e}:${t}`}function mr(e,t,n,r){let a=Jt(e,t),o=Jt(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 gr(e,t){return `${e}${F(t)}Links`}function Zt(e,t,n){let r=J(e),a=J(t);return r===a?`${n}${F(r)}Id`:`${r}Id`}function fr(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 hr(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=mr(n,o,a.targetTable,i),l=Zt(s.leftTable,s.rightTable,"source"),u=Zt(s.rightTable,s.leftTable,"target"),c={leftTable:s.leftTable,leftReferenceField:s.leftReferenceField,rightTable:s.rightTable,rightReferenceField:s.rightReferenceField,junctionTable:a.junctionTable??gr(s.leftTable,s.rightTable),leftField:s.sourceIsLeft?a.sourceField??l:a.targetField??l,rightField:s.sourceIsLeft?a.targetField??u:a.sourceField??u,leftSqlName:s.sourceIsLeft?a.sourceSqlName:a.targetSqlName,rightSqlName:s.sourceIsLeft?a.targetSqlName:a.sourceSqlName,onDelete:a.onDelete,onUpdate:a.onUpdate};if(c.leftField===c.rightField)throw new Error(`manyToMany pair '${s.key}' resolves to duplicate junction fields '${c.leftField}'. Set sourceField/targetField explicitly.`);let f=t.get(s.key);f?fr(f,c,s.key):t.set(s.key,c),a.referenceField=o,a.targetReferenceField=i,a.junctionTable=c.junctionTable,a.sourceField=s.sourceIsLeft?c.leftField:c.rightField,a.targetField=s.sourceIsLeft?c.rightField:c.leftField,a.sourceSqlName=s.sourceIsLeft?c.leftSqlName:c.rightSqlName,a.targetSqlName=s.sourceIsLeft?c.rightSqlName:c.leftSqlName;}for(let 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=P(e,n.leftTable,n.leftReferenceField)??"string",a=P(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 br(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 yr(e){br(e);let t=pr(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 l=P(t,o.targetTable,i)??o.fkType??"string";Kt(n,r,s,o.targetTable,i,{fkType:o.fkType,sqlName:o.sqlName,notNull:Gt(`${n}.${a}`,o,true),onDelete:o.onDelete,onUpdate:o.onUpdate},l);}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??`${J(n)}Id`;a.field=s;let l=P(t,n,i)??a.fkType??"string";Kt(a.targetTable,o,s,n,i,{fkType:a.fkType,sqlName:a.sqlName,notNull:Gt(`${n}.${a.targetTable}`,a,true),onDelete:a.onDelete,onUpdate:a.onUpdate},l);}return hr(t),t}function Xt(e){return e.primaryKey===true||e.notNull!==true||e.autoIncrement===true||e.sqlDefault!==void 0||e.runtimeDefaultFn!==void 0}function $(e){return e.notNull!==true}function wr(e,t,n){let r=t.sqlName??M(e),a=r!==e;return t.type==="int"?a?`t.int(${h(r)})`:"t.int()":t.type==="string"?t.length!==void 0?a?`t.text(${h(r)}, { length: ${t.length} })`:`t.text({ length: ${t.length} })`:a?`t.text(${h(r)})`:"t.text()":t.type==="boolean"?a?`t.int(${h(r)}, { mode: "boolean" })`:'t.int({ mode: "boolean" })':t.type==="date"?a?`t.int(${h(r)}, { mode: "timestamp_ms" })`:'t.int({ mode: "timestamp_ms" })':n==="camelToSnake"&&a?`t.text(${h(r)})`:"t.text()"}function xr(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 vr(e){return e.size===0?"":`import { ${Array.from(e).sort().join(", ")} } from "./auth.schema";
|
|
8674
8644
|
`}function Tr(e){return Object.values(e.relations).filter(t=>t.relation==="one").map(t=>t.targetTable)}function Rr(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 kr(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(`${h(o)}: {
|
|
8675
8645
|
targetTable: ${h(i.targetTable)},
|
|
8676
8646
|
junctionTable: ${h(i.junctionTable)},
|
|
@@ -8744,7 +8714,7 @@ ${o.join(`
|
|
|
8744
8714
|
${kr(e)}
|
|
8745
8715
|
|
|
8746
8716
|
${Sr(e)}
|
|
8747
|
-
`}function Yt(e,t,n){let r="z.unknown()";return e.type==="int"?r="z.number().int()":e.type==="string"?(r="z.string()",e.length!==void 0&&(r+=`.max(${e.length})`)):e.type==="boolean"?r="z.boolean()":e.type==="date"&&(r="z.date()"),t&&(r+=".optional()"),n&&(r+=".nullable()"),r}function Nr(e){let t=[];for(let[n,r]of Object.entries(e.tables)){let a=
|
|
8717
|
+
`}function Yt(e,t,n){let r="z.unknown()";return e.type==="int"?r="z.number().int()":e.type==="string"?(r="z.string()",e.length!==void 0&&(r+=`.max(${e.length})`)):e.type==="boolean"?r="z.boolean()":e.type==="date"&&(r="z.date()"),t&&(r+=".optional()"),n&&(r+=".nullable()"),r}function Nr(e){let t=[];for(let[n,r]of Object.entries(e.tables)){let a=F(n),o=[],i=[];for(let[s,l]of Object.entries(r.columns))o.push(` ${s}: ${Yt(l,Xt(l),$(l))},`),i.push(` ${s}: ${Yt(l,$(l),$(l))},`);t.push(`export const ${n}InsertSchema = z.object({
|
|
8748
8718
|
${o.join(`
|
|
8749
8719
|
`)}
|
|
8750
8720
|
});
|
|
@@ -8758,7 +8728,7 @@ export type ${a}Select = z.infer<typeof ${n}SelectSchema>;
|
|
|
8758
8728
|
`);}return `import { z } from "zod";
|
|
8759
8729
|
|
|
8760
8730
|
${t.join(`
|
|
8761
|
-
`)}`}function $r(e){return e.type==="int"?"number":e.type==="string"?"string":e.type==="boolean"?"boolean":e.type==="date"?"Date":"unknown"}function qr(e){let t=[];for(let[n,r]of Object.entries(e.tables)){let a=
|
|
8731
|
+
`)}`}function $r(e){return e.type==="int"?"number":e.type==="string"?"string":e.type==="boolean"?"boolean":e.type==="date"?"Date":"unknown"}function qr(e){let t=[];for(let[n,r]of Object.entries(e.tables)){let a=F(n),o=[],i=[];for(let[s,l]of Object.entries(r.columns)){let u=$r(l),c=$(l)?" | null":"";o.push(` ${s}${$(l)?"?":""}: ${u}${c};`),i.push(` ${s}${Xt(l)?"?":""}: ${u}${c};`);}t.push(`export type ${a} = {
|
|
8762
8732
|
${o.join(`
|
|
8763
8733
|
`)}
|
|
8764
8734
|
};
|
|
@@ -8769,11 +8739,11 @@ ${i.join(`
|
|
|
8769
8739
|
};`);}return `${t.join(`
|
|
8770
8740
|
|
|
8771
8741
|
`)}
|
|
8772
|
-
`}function Ir(e,t){if(t){let n=e[t];if(!_(n))throw new Error(`schemaDsl.exportName '${t}' does not point to a schema() export.`);return n}for(let n of Object.values(e))if(_(n))return n;throw new Error("No schema() export found in schemaDsl entry module. Set schemaDsl.exportName to the correct export.")}async function en(e){let t=e.config.schemaDsl;if(!t)return;let n=t.namingStrategy??"camelToSnake",r=path.resolve(e.configDir,t.entry),a=path.resolve(e.configDir,t.outFile??path.resolve(e.outDirAbs,"schema.compiled.ts")),o=path.resolve(e.configDir,t.typesOutFile??path.resolve(e.outDirAbs,"schema.types.ts")),i=path.resolve(e.configDir,t.zodOutFile??path.resolve(e.outDirAbs,"schema.zod.ts")),l=await import(`${url.pathToFileURL(r).href}?t=${Date.now()}`),u=Ir(l,t.exportName),c=yr(u);await Promise.all([promises.mkdir(path.dirname(a),{recursive:true}),promises.mkdir(path.dirname(o),{recursive:true}),promises.mkdir(path.dirname(i),{recursive:true})]);let f=Ar(c,n),d=qr(c),y=Nr(c);return await Promise.all([Bun.write(a,f),Bun.write(o,d),Bun.write(i,y)]),{schemaPath:a,typesPath:o,zodPath:i,tableNames:Object.keys(c.tables)}}function Mr(e){return e.replaceAll("\\","/")}function A(e,t){let n=Mr(path.relative(e,t)).replace(/\.tsx?$/,"");return n.startsWith(".")?n:`./${n}`}var Fr=new Set([".ts",".tsx",".mts",".cts"]);async function an(e){let t=await promises.readdir(e,{withFileTypes:true}),n=[];for(let r of t){if(r.name.startsWith(".")||r.name==="node_modules"||r.name==="_generated")continue;let a=path.resolve(e,r.name);if(r.isDirectory()){n.push(...await an(a));continue}r.isFile()&&Fr.has(path.extname(r.name))&&n.push(a);}return n}function Z(e){return e.replace(/\.[cm]?tsx?$/,"")}function Or(e,t){let n=e,r=false,a,o="unknown";for(;g__namespace.isCallExpression(n);){let i=n.expression;if(!g__namespace.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 l=n.arguments[0];l&&(g__namespace.isStringLiteral(l)||g__namespace.isNumericLiteral(l)?a=l.text:l.kind===g__namespace.SyntaxKind.TrueKeyword?a="true":l.kind===g__namespace.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 jr(e){if(!e||!g__namespace.isObjectLiteralExpression(e))return [];let t=e.properties.find(r=>g__namespace.isPropertyAssignment(r)&&g__namespace.isIdentifier(r.name)&&r.name.text==="args");if(!t||!g__namespace.isObjectLiteralExpression(t.initializer))return [];let n=[];for(let r of t.initializer.properties)!g__namespace.isPropertyAssignment(r)||!g__namespace.isIdentifier(r.name)||n.push(Or(r.initializer,r.name.text));return n}function Vr(e){return g__namespace.isVariableStatement(e)?e.modifiers?.some(t=>t.kind===g__namespace.SyntaxKind.ExportKeyword)??false:false}function on(e){return g__namespace.isIdentifier(e)?e.text:g__namespace.isParenthesizedExpression(e)?on(e.expression):null}function Br(e){if(!e||!g__namespace.isObjectLiteralExpression(e))return [];let t=e.properties.find(r=>!g__namespace.isPropertyAssignment(r)||!g__namespace.isIdentifier(r.name)?false:r.name.text==="cronTrigger");if(!t||!g__namespace.isPropertyAssignment(t))return [];let n=t.initializer;return g__namespace.isStringLiteral(n)||g__namespace.isNoSubstitutionTemplateLiteral(n)?[n.text.trim()].filter(r=>r.length>0):g__namespace.isArrayLiteralExpression(n)?n.elements.map(r=>g__namespace.isStringLiteral(r)||g__namespace.isNoSubstitutionTemplateLiteral(r)?r.text.trim():"").filter(r=>r.length>0):[]}function Hr(e,t){let n=g__namespace.createSourceFile(t,e,g__namespace.ScriptTarget.Latest,true,g__namespace.ScriptKind.TS),r=[];for(let a of n.statements)if(Vr(a))for(let o of a.declarationList.declarations){if(!g__namespace.isIdentifier(o.name)||!o.initializer||!g__namespace.isCallExpression(o.initializer))continue;let i=on(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"?Br(o.initializer.arguments[0]):[],args:i==="query"||i==="mutation"?jr(o.initializer.arguments[0]):[]});}return r}function tn(e,t,n){let r=t.replace(/\\/g,"/"),o=Z(r).split("/").filter(Boolean);return `/${[e,...o,n].filter(Boolean).map(s=>s.trim()).filter(s=>s.length>0).join("/")}`}function Wr(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 nn(e,t){let n=e.replace(/\\/g,"/"),a=Z(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 sn(e){let t=[],n=await an(e.scanDirAbs).catch(()=>[]);for(let a of n){let o=Bun.file(a);if(!await o.exists())continue;let i=await o.text(),s=path.relative(e.scanDirAbs,a),l=Hr(i,a),u=[{kind:"query",kindDirectory:"queries",exports:l.filter(c=>c.kind==="query")},{kind:"mutation",kindDirectory:"mutations",exports:l.filter(c=>c.kind==="mutation")},{kind:"scheduler",kindDirectory:"schedulers",exports:l.filter(c=>c.kind==="scheduler")},{kind:"cron",kindDirectory:"crons",exports:l.filter(c=>c.kind==="cron")},{kind:"storage",kindDirectory:"queries",exports:l.filter(c=>c.kind==="storage")}];for(let c of u){if(c.exports.length===0)continue;let f=Wr(s,c.kindDirectory);for(let d of c.exports){let y=c.kind==="query"||c.kind==="mutation"?nn(f,d.exportName):void 0,w=c.kind==="scheduler"||c.kind==="cron"?nn(f,d.exportName):void 0,b=c.kind==="query"||c.kind==="mutation"?[...Z(f).split("/").filter(Boolean),d.exportName]:void 0,m=c.kind==="query"?tn("queries",f,d.exportName):c.kind==="mutation"?tn("mutations",f,d.exportName):c.kind==="storage"?`/storage/managers/${d.exportName}`:`/${c.kindDirectory}/${w}`;t.push({kind:c.kind,exportName:d.exportName,filePath:a,importPath:A(e.outDirAbs,a),clientImportPath:A(path.resolve(e.outDirAbs,"client"),a),routePath:m,handlerName:y,clientSegments:b,taskName:w,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 Ur(e){let t=[],n="",r=0,a=0,o=0,i=false,s=false,l=false,u=false;for(let f=0;f<e.length;f+=1){let d=e[f];if(u){n+=d,u=false;continue}if(d==="\\"){n+=d,u=true;continue}if(!s&&!l&&d==="'"){i=!i,n+=d;continue}if(!i&&!l&&d==='"'){s=!s,n+=d;continue}if(!i&&!s&&d==="`"){l=!l,n+=d;continue}if(i||s||l){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 c=n.trim();return c.length>0&&t.push(c),t}function zr(e){let t=0,n=0,r=0,a=false,o=false,i=false,s=false;for(let l=0;l<e.length;l+=1){let u=e[l];if(s){s=false;continue}if(u==="\\"){s=true;continue}if(!o&&!i&&u==="'"){a=!a;continue}if(!a&&!i&&u==='"'){o=!o;continue}if(!a&&!o&&u==="`"){i=!i;continue}if(!(a||o||i)){if(u==="("){t+=1;continue}if(u===")"){t-=1;continue}if(u==="{"){n+=1;continue}if(u==="}"){n-=1;continue}if(u==="["){r+=1;continue}if(u==="]"){r-=1;continue}if(u===":"&&t===0&&n===0&&r===0)return l}}return -1}function Qr(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 _r(e){let t=Ur(e),n=[];for(let r of t){let a=zr(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),l=/autoincrement\s*:\s*true/i.test(i),u=/\.default\s*\(/i.test(i),f=!/\.notnull\s*\(/i.test(i)||u||l||s;n.push({name:o,expression:i,type:Qr(i),optional:f,primaryKey:s,autoIncrement:l});}return n}function Kr(e){let t=/export\s+const\s+(\w+)\s*=\s*table\s*\(\s*["'`]([^"'`]+)["'`]/g,n=[],r=(o,i)=>{let s=0,l=false,u=false,c=false,f=false;for(let d=i;d<o.length;d+=1){let y=o[d];if(f){f=false;continue}if(y==="\\"){f=true;continue}if(!u&&!c&&y==="'"){l=!l;continue}if(!l&&!c&&y==='"'){u=!u;continue}if(!l&&!u&&y==="`"){c=!c;continue}if(!(l||u||c)){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 l=r(e,s);if(l===-1){a=t.exec(e);continue}let u=e.slice(s+1,l);n.push({exportName:o,tableName:i,columns:_r(u)}),a=t.exec(e);}return n}async function cn(e){let t=await promises.readdir(e,{withFileTypes:true}),n=[];for(let r of t){if(r.name.startsWith(".")||r.name==="node_modules"||r.name==="_generated")continue;let a=path.resolve(e,r.name);if(r.isDirectory()){n.push(...await cn(a));continue}r.isFile()&&r.name==="schema.ts"&&n.push(a);}return n}async function un(e,t=[]){let n=await cn(e.scanDirAbs).catch(()=>[]),r=path.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(),l=Kr(s);if(l.length>0)return {schemaPath:o,tables:l}}throw new Error(`Unable to discover schema.ts under scanDir (${e.scanDirAbs}) or fallback (${r}).`)}function Jr(e,t){let n=path.relative(e,t).replace(/\\/g,"/");return n.startsWith(".")?n:`./${n}`}async function dn(e){let{outDirAbs:t,wranglerOutDirAbs:n,config:r,configPath:a,configDir:o}=e,i=A(t,a),s=path.resolve(t,"client"),l=A(s,a);await Promise.all([promises.mkdir(t,{recursive:true}),promises.mkdir(s,{recursive:true}),promises.mkdir(n,{recursive:true})]);let u=path.resolve(t,"server.ts"),c=path.resolve(t,"client.ts"),f=path.resolve(t,"auth.config.ts"),d=path.resolve(t,"auth.schema.ts"),y=path.resolve(t,"drizzle.config.ts"),w=path.resolve(n,"wrangler.json"),b=await en(e),m=await un(e,b?[b.schemaPath]:[]),x=A(t,m.schemaPath),T=await sn(e),R=at(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),vn=ce(l,T),Tn=H(x,T,r.r2[0]?.binding),Rn=ne(i),kn=b?[Jr(o,b.schemaPath),...r.schema.filter(k=>!/(^|\/)schema\.ts$/.test(k))]:r.schema,Sn=ue(kn),An=it(e,T),Nn=_t(x,m,T),$n=path.resolve(t,"admin.routes.ts"),qn=Tn.map(k=>Bun.write(path.resolve(t,k.relativePath),k.source)),In=vn.map(k=>Bun.write(path.resolve(t,k.relativePath),k.source));await Promise.all([Bun.write(u,R),Bun.write(c,`export * from "./client/index";
|
|
8773
|
-
`),...
|
|
8774
|
-
`),Bun.write($n,Nn)]);let O=path.relative(o,f).replace(/\\/g,"/"),
|
|
8742
|
+
`}function Cr(e,t){if(t){let n=e[t];if(!_(n))throw new Error(`schemaDsl.exportName '${t}' does not point to a schema() export.`);return n}for(let n of Object.values(e))if(_(n))return n;throw new Error("No schema() export found in schemaDsl entry module. Set schemaDsl.exportName to the correct export.")}async function en(e){let t=e.config.schemaDsl;if(!t)return;let n=t.namingStrategy??"camelToSnake",r=path.resolve(e.configDir,t.entry),a=path.resolve(e.configDir,t.outFile??path.resolve(e.outDirAbs,"schema.compiled.ts")),o=path.resolve(e.configDir,t.typesOutFile??path.resolve(e.outDirAbs,"schema.types.ts")),i=path.resolve(e.configDir,t.zodOutFile??path.resolve(e.outDirAbs,"schema.zod.ts")),l=await import(`${url.pathToFileURL(r).href}?t=${Date.now()}`),u=Cr(l,t.exportName),c=yr(u);await Promise.all([promises.mkdir(path.dirname(a),{recursive:true}),promises.mkdir(path.dirname(o),{recursive:true}),promises.mkdir(path.dirname(i),{recursive:true})]);let f=Ar(c,n),d=qr(c),y=Nr(c);return await Promise.all([Bun.write(a,f),Bun.write(o,d),Bun.write(i,y)]),{schemaPath:a,typesPath:o,zodPath:i,tableNames:Object.keys(c.tables)}}function Mr(e){return e.replaceAll("\\","/")}function A(e,t){let n=Mr(path.relative(e,t)).replace(/\.tsx?$/,"");return n.startsWith(".")?n:`./${n}`}var Er=new Set([".ts",".tsx",".mts",".cts"]);async function an(e){let t=await promises.readdir(e,{withFileTypes:true}),n=[];for(let r of t){if(r.name.startsWith(".")||r.name==="node_modules"||r.name==="_generated")continue;let a=path.resolve(e,r.name);if(r.isDirectory()){n.push(...await an(a));continue}r.isFile()&&Er.has(path.extname(r.name))&&n.push(a);}return n}function Z(e){return e.replace(/\.[cm]?tsx?$/,"")}function Or(e,t){let n=e,r=false,a,o="unknown";for(;g__namespace.isCallExpression(n);){let i=n.expression;if(!g__namespace.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 l=n.arguments[0];l&&(g__namespace.isStringLiteral(l)||g__namespace.isNumericLiteral(l)?a=l.text:l.kind===g__namespace.SyntaxKind.TrueKeyword?a="true":l.kind===g__namespace.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 jr(e){if(!e||!g__namespace.isObjectLiteralExpression(e))return [];let t=e.properties.find(r=>g__namespace.isPropertyAssignment(r)&&g__namespace.isIdentifier(r.name)&&r.name.text==="args");if(!t||!g__namespace.isObjectLiteralExpression(t.initializer))return [];let n=[];for(let r of t.initializer.properties)!g__namespace.isPropertyAssignment(r)||!g__namespace.isIdentifier(r.name)||n.push(Or(r.initializer,r.name.text));return n}function Vr(e){return g__namespace.isVariableStatement(e)?e.modifiers?.some(t=>t.kind===g__namespace.SyntaxKind.ExportKeyword)??false:false}function on(e){return g__namespace.isIdentifier(e)?e.text:g__namespace.isParenthesizedExpression(e)?on(e.expression):null}function Br(e){if(!e||!g__namespace.isObjectLiteralExpression(e))return [];let t=e.properties.find(r=>!g__namespace.isPropertyAssignment(r)||!g__namespace.isIdentifier(r.name)?false:r.name.text==="cronTrigger");if(!t||!g__namespace.isPropertyAssignment(t))return [];let n=t.initializer;return g__namespace.isStringLiteral(n)||g__namespace.isNoSubstitutionTemplateLiteral(n)?[n.text.trim()].filter(r=>r.length>0):g__namespace.isArrayLiteralExpression(n)?n.elements.map(r=>g__namespace.isStringLiteral(r)||g__namespace.isNoSubstitutionTemplateLiteral(r)?r.text.trim():"").filter(r=>r.length>0):[]}function Hr(e,t){let n=g__namespace.createSourceFile(t,e,g__namespace.ScriptTarget.Latest,true,g__namespace.ScriptKind.TS),r=[];for(let a of n.statements)if(Vr(a))for(let o of a.declarationList.declarations){if(!g__namespace.isIdentifier(o.name)||!o.initializer||!g__namespace.isCallExpression(o.initializer))continue;let i=on(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"?Br(o.initializer.arguments[0]):[],args:i==="query"||i==="mutation"?jr(o.initializer.arguments[0]):[]});}return r}function tn(e,t,n){let r=t.replace(/\\/g,"/"),o=Z(r).split("/").filter(Boolean);return `/${[e,...o,n].filter(Boolean).map(s=>s.trim()).filter(s=>s.length>0).join("/")}`}function Wr(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 nn(e,t){let n=e.replace(/\\/g,"/"),a=Z(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 sn(e){let t=[],n=await an(e.scanDirAbs).catch(()=>[]);for(let a of n){let o=Bun.file(a);if(!await o.exists())continue;let i=await o.text(),s=path.relative(e.scanDirAbs,a),l=Hr(i,a),u=[{kind:"query",kindDirectory:"queries",exports:l.filter(c=>c.kind==="query")},{kind:"mutation",kindDirectory:"mutations",exports:l.filter(c=>c.kind==="mutation")},{kind:"scheduler",kindDirectory:"schedulers",exports:l.filter(c=>c.kind==="scheduler")},{kind:"cron",kindDirectory:"crons",exports:l.filter(c=>c.kind==="cron")},{kind:"storage",kindDirectory:"queries",exports:l.filter(c=>c.kind==="storage")}];for(let c of u){if(c.exports.length===0)continue;let f=Wr(s,c.kindDirectory);for(let d of c.exports){let y=c.kind==="query"||c.kind==="mutation"?nn(f,d.exportName):void 0,w=c.kind==="scheduler"||c.kind==="cron"?nn(f,d.exportName):void 0,b=c.kind==="query"||c.kind==="mutation"?[...Z(f).split("/").filter(Boolean),d.exportName]:void 0,m=c.kind==="query"?tn("queries",f,d.exportName):c.kind==="mutation"?tn("mutations",f,d.exportName):c.kind==="storage"?`/storage/managers/${d.exportName}`:`/${c.kindDirectory}/${w}`;t.push({kind:c.kind,exportName:d.exportName,filePath:a,importPath:A(e.outDirAbs,a),clientImportPath:A(path.resolve(e.outDirAbs,"client"),a),routePath:m,handlerName:y,clientSegments:b,taskName:w,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 zr(e){let t=[],n="",r=0,a=0,o=0,i=false,s=false,l=false,u=false;for(let f=0;f<e.length;f+=1){let d=e[f];if(u){n+=d,u=false;continue}if(d==="\\"){n+=d,u=true;continue}if(!s&&!l&&d==="'"){i=!i,n+=d;continue}if(!i&&!l&&d==='"'){s=!s,n+=d;continue}if(!i&&!s&&d==="`"){l=!l,n+=d;continue}if(i||s||l){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 c=n.trim();return c.length>0&&t.push(c),t}function Ur(e){let t=0,n=0,r=0,a=false,o=false,i=false,s=false;for(let l=0;l<e.length;l+=1){let u=e[l];if(s){s=false;continue}if(u==="\\"){s=true;continue}if(!o&&!i&&u==="'"){a=!a;continue}if(!a&&!i&&u==='"'){o=!o;continue}if(!a&&!o&&u==="`"){i=!i;continue}if(!(a||o||i)){if(u==="("){t+=1;continue}if(u===")"){t-=1;continue}if(u==="{"){n+=1;continue}if(u==="}"){n-=1;continue}if(u==="["){r+=1;continue}if(u==="]"){r-=1;continue}if(u===":"&&t===0&&n===0&&r===0)return l}}return -1}function Qr(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 _r(e){let t=zr(e),n=[];for(let r of t){let a=Ur(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),l=/autoincrement\s*:\s*true/i.test(i),u=/\.default\s*\(/i.test(i),f=!/\.notnull\s*\(/i.test(i)||u||l||s;n.push({name:o,expression:i,type:Qr(i),optional:f,primaryKey:s,autoIncrement:l});}return n}function Kr(e){let t=/export\s+const\s+(\w+)\s*=\s*table\s*\(\s*["'`]([^"'`]+)["'`]/g,n=[],r=(o,i)=>{let s=0,l=false,u=false,c=false,f=false;for(let d=i;d<o.length;d+=1){let y=o[d];if(f){f=false;continue}if(y==="\\"){f=true;continue}if(!u&&!c&&y==="'"){l=!l;continue}if(!l&&!c&&y==='"'){u=!u;continue}if(!l&&!u&&y==="`"){c=!c;continue}if(!(l||u||c)){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 l=r(e,s);if(l===-1){a=t.exec(e);continue}let u=e.slice(s+1,l);n.push({exportName:o,tableName:i,columns:_r(u)}),a=t.exec(e);}return n}async function cn(e){let t=await promises.readdir(e,{withFileTypes:true}),n=[];for(let r of t){if(r.name.startsWith(".")||r.name==="node_modules"||r.name==="_generated")continue;let a=path.resolve(e,r.name);if(r.isDirectory()){n.push(...await cn(a));continue}r.isFile()&&r.name==="schema.ts"&&n.push(a);}return n}async function un(e,t=[]){let n=await cn(e.scanDirAbs).catch(()=>[]),r=path.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(),l=Kr(s);if(l.length>0)return {schemaPath:o,tables:l}}throw new Error(`Unable to discover schema.ts under scanDir (${e.scanDirAbs}) or fallback (${r}).`)}function Jr(e,t){let n=path.relative(e,t).replace(/\\/g,"/");return n.startsWith(".")?n:`./${n}`}async function dn(e){let{outDirAbs:t,wranglerOutDirAbs:n,config:r,configPath:a,configDir:o}=e,i=A(t,a),s=path.resolve(t,"client"),l=A(s,a);await Promise.all([promises.mkdir(t,{recursive:true}),promises.mkdir(s,{recursive:true}),promises.mkdir(n,{recursive:true})]);let u=path.resolve(t,"server.ts"),c=path.resolve(t,"client.ts"),f=path.resolve(t,"auth.config.ts"),d=path.resolve(t,"auth.schema.ts"),y=path.resolve(t,"drizzle.config.ts"),w=path.resolve(n,"wrangler.json"),b=await en(e),m=await un(e,b?[b.schemaPath]:[]),x=A(t,m.schemaPath),T=await sn(e),R=at(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),vn=ce(l,T),Tn=H(x,T,r.r2[0]?.binding),Rn=ne(i),kn=b?[Jr(o,b.schemaPath),...r.schema.filter(k=>!/(^|\/)schema\.ts$/.test(k))]:r.schema,Sn=ue(kn),An=it(e,T),Nn=_t(x,m,T),$n=path.resolve(t,"admin.routes.ts"),qn=Tn.map(k=>Bun.write(path.resolve(t,k.relativePath),k.source)),Cn=vn.map(k=>Bun.write(path.resolve(t,k.relativePath),k.source));await Promise.all([Bun.write(u,R),Bun.write(c,`export * from "./client/index";
|
|
8743
|
+
`),...Cn,...qn,Bun.write(f,Rn),Bun.write(d,""),Bun.write(y,Sn),Bun.write(w,`${JSON.stringify(An,null,2)}
|
|
8744
|
+
`),Bun.write($n,Nn)]);let O=path.relative(o,f).replace(/\\/g,"/"),In=O.startsWith(".")?O:`./${O}`,j=path.relative(o,d).replace(/\\/g,"/"),Mn=j.startsWith(".")?j:`./${j}`,ee=await Bun.spawn(["npx","@better-auth/cli","generate","--config",In,"--output",Mn,"--yes"],{cwd:o,stdout:"inherit",stderr:"inherit"}).exited;if(ee!==0)throw new Error(`better-auth generation failed with exit code ${ee}`);let Pn=path.resolve(o,"tsconfig.json");if(e.config.build&&fs.existsSync(Pn)){let k=process.platform==="win32"?"npx.cmd":"npx",te=await Bun.spawn([k,"--yes","-p","typescript","tsc","--build"],{cwd:o,stdout:"inherit",stderr:"inherit"}).exited;if(te!==0)throw new Error(`TypeScript build failed with exit code ${te}`)}}var pn=zod.z.object({binding:zod.z.string().min(1),databaseName:zod.z.string().min(1),databaseId:zod.z.string().min(1),previewDatabaseId:zod.z.string().min(1).optional(),migrationsDir:zod.z.string().min(1).optional()}).strict(),mn=zod.z.object({binding:zod.z.string().min(1),id:zod.z.string().min(1),previewId:zod.z.string().min(1).optional()}).strict(),gn=zod.z.object({binding:zod.z.string().min(1),bucketName:zod.z.string().min(1),previewBucketName:zod.z.string().min(1).optional(),jurisdiction:zod.z.string().min(1).optional()}).strict(),fn=zod.z.object({enabled:zod.z.boolean().optional(),binding:zod.z.string().min(1).optional(),queue:zod.z.string().min(1).optional()}).strict(),ea=zod.z.object({enabled:zod.z.boolean().optional(),binding:zod.z.string().min(1).optional(),className:zod.z.string().min(1).optional(),objectName:zod.z.string().min(1).optional(),subscribePath:zod.z.string().min(1).optional(),websocketPath:zod.z.string().min(1).optional(),protocol:zod.z.string().min(1).optional()}).strict(),ta=zod.z.object({scanDir:zod.z.string().min(1),outDir:zod.z.string().min(1),wranglerOutDir:zod.z.string().min(1).optional(),wranglerOutPath:zod.z.string().min(1).optional(),schema:zod.z.array(zod.z.string()).min(1),schemaDsl:zod.z.object({entry:zod.z.string().min(1),exportName:zod.z.string().min(1).optional(),outFile:zod.z.string().min(1).optional(),typesOutFile:zod.z.string().min(1).optional(),zodOutFile:zod.z.string().min(1).optional(),namingStrategy:zod.z.literal("camelToSnake").optional()}).strict().optional(),database:zod.z.union([pn,zod.z.array(pn).min(1)]),kv:zod.z.union([mn,zod.z.array(mn)]).optional(),r2:zod.z.union([gn,zod.z.array(gn)]).optional(),auth:zod.z.object({enabled:zod.z.boolean(),basePath:zod.z.string().min(1),options:zod.z.custom(e=>typeof e=="object"&&e!==null),clientOptions:zod.z.custom(e=>typeof e=="object"&&e!==null)}).strict(),scheduler:fn.optional(),realtime:ea.optional(),wranglerOverrides:zod.z.record(zod.z.string(),zod.z.unknown()).optional(),build:zod.z.boolean().optional()}).strict();function hn(e){return typeof e=="object"&&e!==null}function na(e){let t=hn(e.wranglerOverrides)?e.wranglerOverrides.scheduler:void 0,n=fn.safeParse(t);return n.success?n.data:{}}function ra(e){if(!hn(e)||!("scheduler"in e))return e;let{scheduler:t,...n}=e;return n}function aa(e){let n={...na(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:ra(e.wranglerOverrides),wranglerOutDir:e.wranglerOutDir??e.wranglerOutPath??e.outDir,build:e.build??true}}async function q(e){let t=path.isAbsolute(e??"")?e:path.resolve(process.cwd(),e??"appflare.config.ts"),n=path.dirname(t),o=(await import(url.pathToFileURL(t).href)).default,i=ta.parse(o),s=aa(i);return {configPath:t,configDir:n,scanDirAbs:path.resolve(n,s.scanDir),outDirAbs:path.resolve(n,s.outDir),wranglerOutDirAbs:path.resolve(n,s.wranglerOutDir),config:s}}function la(e){let t=e;for(;;){if(fs.existsSync(path.resolve(t,"package.json")))return t;let n=path.dirname(t);if(n===t)return e;t=n;}}async function E(e,t={}){let n=await q(e);if(t.build!==void 0&&(n.config.build=t.build),await dn(n),n.wranglerOutDirAbs===n.outDirAbs){process.stdout.write(`\u2705 Generated artifacts in ${n.outDirAbs}
|
|
8775
8745
|
`);return}process.stdout.write(`\u2705 Generated server/client in ${n.outDirAbs} and wrangler.json in ${n.wranglerOutDirAbs}
|
|
8776
|
-
`);}async function yn(e,t={}){if(await
|
|
8746
|
+
`);}async function yn(e,t={}){if(await E(e,{build:t.build}),!t.watch)return;let n=await q(e),r=false,a=false,o=async()=>{if(r){a=true;return}r=true;try{await E(e,{build:t.build});}catch(s){process.stderr.write(`\u274C Build failed: ${s.message}
|
|
8777
8747
|
`);}finally{r=false,a&&(a=false,await o());}};oa__default.default.watch(n.scanDirAbs,{ignoreInitial:true}).on("all",async(s,l)=>{process.stdout.write(`\u{1F504} Change detected: ${l}
|
|
8778
8748
|
`),await o();}),process.stdout.write(`\u{1F440} Watching ${n.scanDirAbs}
|
|
8779
|
-
`);}async function wn(e,t={}){let n=await q(e),r=la(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=path.resolve(n.outDirAbs,"drizzle.config.ts"),i=process.platform==="win32"?"npx.cmd":"npx",l=await Bun.spawn([i,"drizzle-kit","generate","--config",o],{cwd:r,stdin:"inherit",stdout:"inherit",stderr:"inherit"}).exited;if(l!==0)throw new Error(`drizzle-kit generate failed with exit code ${l}`);let u=n.config.database[0].databaseName,c=[i,"wrangler","d1","migrations","apply",u];t.local?c.push("--local"):t.remote?c.push("--remote"):t.preview&&c.push("--preview");let d=await Bun.spawn(c,{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 xn(e,t={name:"",email:"",password:""}){let n=await q(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(),l=Date.now(),u=t.name.replace(/'/g,"''"),c=t.email.replace(/'/g,"''"),f=["INSERT INTO users (id, name, email, email_verified, created_at, updated_at, role, banned)",`VALUES ('${i}', '${u}', '${c}', 1, ${l}, ${l}, 'admin', 0);`,"INSERT INTO accounts (id, account_id, provider_id, user_id, password, created_at, updated_at)",`VALUES ('${s}', '${c}', 'credential', '${i}', '${o}', ${l}, ${l});`].join(" "),d=n.config.database[0].databaseName,w=[process.platform==="win32"?"npx.cmd":"npx","wrangler","d1","execute",d,`--command=${f}`];t.local?w.push("--local"):t.remote&&w.push("--remote");let m=await Bun.spawn(w,{cwd:n.configDir,stdin:"inherit",stdout:"inherit",stderr:"inherit"}).exited;if(m!==0)throw new Error(`Failed to add admin user. wrangler d1 execute exited with code ${m}`);console.log("\u2705 Admin user "+t.email+" created successfully!");}var N=new commander.Command;N.name("appflare").description("Appflare compiler/bundler for Cloudflare-native backends and SDK generation").version("0.0.28");N.command("build").description("Generate server.ts, client.ts, auth.config.ts, drizzle.config.ts, 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
|
|
8749
|
+
`);}async function wn(e,t={}){let n=await q(e),r=la(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=path.resolve(n.outDirAbs,"drizzle.config.ts"),i=process.platform==="win32"?"npx.cmd":"npx",l=await Bun.spawn([i,"drizzle-kit","generate","--config",o],{cwd:r,stdin:"inherit",stdout:"inherit",stderr:"inherit"}).exited;if(l!==0)throw new Error(`drizzle-kit generate failed with exit code ${l}`);let u=n.config.database[0].databaseName,c=[i,"wrangler","d1","migrations","apply",u];t.local?c.push("--local"):t.remote?c.push("--remote"):t.preview&&c.push("--preview");let d=await Bun.spawn(c,{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 xn(e,t={name:"",email:"",password:""}){let n=await q(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(),l=Date.now(),u=t.name.replace(/'/g,"''"),c=t.email.replace(/'/g,"''"),f=["INSERT INTO users (id, name, email, email_verified, created_at, updated_at, role, banned)",`VALUES ('${i}', '${u}', '${c}', 1, ${l}, ${l}, 'admin', 0);`,"INSERT INTO accounts (id, account_id, provider_id, user_id, password, created_at, updated_at)",`VALUES ('${s}', '${c}', 'credential', '${i}', '${o}', ${l}, ${l});`].join(" "),d=n.config.database[0].databaseName,w=[process.platform==="win32"?"npx.cmd":"npx","wrangler","d1","execute",d,`--command=${f}`];t.local?w.push("--local"):t.remote&&w.push("--remote");let m=await Bun.spawn(w,{cwd:n.configDir,stdin:"inherit",stdout:"inherit",stderr:"inherit"}).exited;if(m!==0)throw new Error(`Failed to add admin user. wrangler d1 execute exited with code ${m}`);console.log("\u2705 Admin user "+t.email+" created successfully!");}var N=new commander.Command;N.name("appflare").description("Appflare compiler/bundler for Cloudflare-native backends and SDK generation").version("0.0.28");N.command("build").description("Generate server.ts, client.ts, auth.config.ts, drizzle.config.ts, 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 E(e.config,{build:e.build});});N.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 yn(e.config,{watch:e.watch,build:e.build});});N.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 wn(e.config,{local:e.local,remote:e.remote,preview:e.preview});});N.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 xn(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 N.parseAsync(process.argv);})().catch(e=>{console.error(e),process.exit(1);});
|