appflare 0.2.16 → 0.2.18
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/dashboard/builders/table-routes/fragments.ts +8 -5
- package/cli/templates/dashboard/builders/table-routes/table/index.ts +1 -1
- package/cli/templates/dashboard/builders/table-routes/users/html/table.ts +3 -2
- package/cli/templates/handlers/generators/context/context-creation.ts +4 -1
- package/cli/templates/handlers/generators/types/query-definitions/filter-and-where-types.ts +36 -26
- package/cli/templates/handlers/generators/types/query-definitions/query-api-types.ts +3 -1
- package/cli/templates/handlers/generators/types/query-definitions/schema-and-table-types.ts +29 -35
- package/cli/templates/handlers/generators/types/query-runtime/runtime-write.ts +190 -70
- package/dist/cli/index.js +300 -170
- package/dist/cli/index.mjs +300 -170
- package/package.json +5 -5
- package/dist/cli/index.d.mts +0 -2
- package/dist/cli/index.d.ts +0 -2
package/dist/cli/index.mjs
CHANGED
|
@@ -164,8 +164,8 @@ export function createAppflare<Options extends BetterAuthClientOptions = Inferre
|
|
|
164
164
|
): Appflare<Options> {
|
|
165
165
|
return new Appflare(options);
|
|
166
166
|
}
|
|
167
|
-
`}function
|
|
168
|
-
`)}function Dn(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=
|
|
167
|
+
`}function Mn(e){let t=e.replace(/[^A-Za-z0-9_]/g,"_");return /^[0-9]/.test(t)?`_${t}`:t||"_route"}function re(e){return e.split(/[^A-Za-z0-9]+/).filter(Boolean).map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join("")}function Pn(e){return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(e)?e:JSON.stringify(e)}function ae(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}${Pn(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(`
|
|
168
|
+
`)}function Dn(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=Mn(`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:`${re(e.kind)}${re(n.join("_"))}`}}function En(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 = (
|
|
169
169
|
runtime: RequestRuntime,
|
|
170
170
|
): AppflareQueryRouteClient<typeof ${e.schemaConst}, ${n}> => {
|
|
171
171
|
const run: AppflareQueryRouteClient<typeof ${e.schemaConst}, ${n}>["run"] = async (
|
|
@@ -1368,6 +1368,9 @@ export function createSchedulerExecutionContext(
|
|
|
1368
1368
|
const schedulerBinding = options.schedulerBinding ?? "APPFLARE_SCHEDULER_QUEUE";
|
|
1369
1369
|
const schedulerQueue = env[schedulerBinding] as SchedulerQueueBinding | undefined;
|
|
1370
1370
|
const helpers = createContextErrorHelpers();
|
|
1371
|
+
const schedulerContext = {
|
|
1372
|
+
env: env as WorkerEnv["Bindings"],
|
|
1373
|
+
} as unknown as Context<WorkerEnv>;
|
|
1371
1374
|
const ctx = {
|
|
1372
1375
|
$db: db,
|
|
1373
1376
|
db: createQueryDb(db, {
|
|
@@ -1378,7 +1381,7 @@ export function createSchedulerExecutionContext(
|
|
|
1378
1381
|
mutationEvents,
|
|
1379
1382
|
user: null as never,
|
|
1380
1383
|
session: null as never,
|
|
1381
|
-
context:
|
|
1384
|
+
context: schedulerContext,
|
|
1382
1385
|
scheduler: createScheduler(schedulerQueue),
|
|
1383
1386
|
storage: null as never,
|
|
1384
1387
|
...helpers,
|
|
@@ -1755,11 +1758,11 @@ type QueryWithRelationInputForTable<
|
|
|
1755
1758
|
TSourceTable extends TableName,
|
|
1756
1759
|
TRelationName extends string,
|
|
1757
1760
|
TEntry,
|
|
1758
|
-
> = ManyToManyTargetTableName<TSourceTable, TRelationName> extends
|
|
1759
|
-
?
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1761
|
+
> = [ManyToManyTargetTableName<TSourceTable, TRelationName>] extends [never]
|
|
1762
|
+
? QueryNativeWithRelationInput<TEntry>
|
|
1763
|
+
: QueryManyToManyWithRelationInput<
|
|
1764
|
+
Extract<ManyToManyTargetTableName<TSourceTable, TRelationName>, TableName>
|
|
1765
|
+
>;
|
|
1763
1766
|
|
|
1764
1767
|
type QueryWithInputForTable<
|
|
1765
1768
|
TSourceTable extends TableName,
|
|
@@ -1795,13 +1798,6 @@ export type QueryFindFirstArgs<TName extends TableName> = Omit<
|
|
|
1795
1798
|
with?: QueryWithInput<TName, NativeFindFirstWith<TName>>;
|
|
1796
1799
|
};
|
|
1797
1800
|
|
|
1798
|
-
type SingularizeRelationName<TName extends string> =
|
|
1799
|
-
TName extends \`\${infer TRoot}ies\`
|
|
1800
|
-
? \`\${TRoot}y\`
|
|
1801
|
-
: TName extends \`\${infer TRoot}s\`
|
|
1802
|
-
? TRoot
|
|
1803
|
-
: TName;
|
|
1804
|
-
|
|
1805
1801
|
type RelationInsertItem<TTargetTable extends TableName> =
|
|
1806
1802
|
| TableModel<TTargetTable>
|
|
1807
1803
|
| TableInsertModel<TTargetTable>
|
|
@@ -1827,21 +1823,38 @@ type RelationInsertFields<TName extends TableName> = {
|
|
|
1827
1823
|
>;
|
|
1828
1824
|
};
|
|
1829
1825
|
|
|
1830
|
-
type RelationInsertIdAliasFields<TName extends TableName> = {
|
|
1831
|
-
[TRelationName in RuntimeRelationName<TName> as \`\${TRelationName}Id\`]?: RelationInsertValue<
|
|
1832
|
-
TName,
|
|
1833
|
-
TRelationName
|
|
1834
|
-
>;
|
|
1835
|
-
} & {
|
|
1836
|
-
[TRelationName in RuntimeRelationName<TName> as \`\${SingularizeRelationName<TRelationName>}Id\`]?: RelationInsertValue<
|
|
1837
|
-
TName,
|
|
1838
|
-
TRelationName
|
|
1839
|
-
>;
|
|
1840
|
-
};
|
|
1841
|
-
|
|
1842
1826
|
type QueryInsertValue<TName extends TableName> = TableInsertScalarModel<TName> &
|
|
1843
|
-
RelationInsertFields<TName
|
|
1844
|
-
|
|
1827
|
+
RelationInsertFields<TName>;
|
|
1828
|
+
|
|
1829
|
+
type InsertItemValue<TArgs> = TArgs extends { values: infer TValue }
|
|
1830
|
+
? TValue extends Array<infer TItem>
|
|
1831
|
+
? TItem
|
|
1832
|
+
: TValue
|
|
1833
|
+
: never;
|
|
1834
|
+
|
|
1835
|
+
type InsertRelationNameFromArgs<
|
|
1836
|
+
TName extends TableName,
|
|
1837
|
+
TArgs,
|
|
1838
|
+
> = Extract<keyof InsertItemValue<TArgs>, RuntimeRelationName<TName>>;
|
|
1839
|
+
|
|
1840
|
+
type InsertRelationResultValue<
|
|
1841
|
+
TSourceTable extends TableName,
|
|
1842
|
+
TRelationName extends RuntimeRelationName<TSourceTable>,
|
|
1843
|
+
> = RuntimeRelationTargetTable<TSourceTable, TRelationName> extends infer TTargetTable
|
|
1844
|
+
? TTargetTable extends TableName
|
|
1845
|
+
? RuntimeRelationKind<TSourceTable, TRelationName> extends "one"
|
|
1846
|
+
? TableModel<TTargetTable> | null
|
|
1847
|
+
: Array<TableModel<TTargetTable>>
|
|
1848
|
+
: never
|
|
1849
|
+
: never;
|
|
1850
|
+
|
|
1851
|
+
export type QueryInsertResultRow<
|
|
1852
|
+
TName extends TableName,
|
|
1853
|
+
TArgs extends QueryInsertArgs<TName>,
|
|
1854
|
+
> = TableModel<TName> & {
|
|
1855
|
+
[TRelationName in InsertRelationNameFromArgs<TName, TArgs>]:
|
|
1856
|
+
InsertRelationResultValue<TName, TRelationName>;
|
|
1857
|
+
};
|
|
1845
1858
|
|
|
1846
1859
|
export type QueryInsertArgs<TName extends TableName> = {
|
|
1847
1860
|
values: QueryInsertValue<TName> | Array<QueryInsertValue<TName>>;
|
|
@@ -1963,7 +1976,9 @@ export type QueryTableApi<TName extends TableName> = {
|
|
|
1963
1976
|
>(
|
|
1964
1977
|
args?: TArgs,
|
|
1965
1978
|
) => ApplyFindFirstWithAggregateResult<TableFindFirstResult<TName, TArgs>, TArgs>;
|
|
1966
|
-
insert:
|
|
1979
|
+
insert: <TArgs extends QueryInsertArgs<TName>>(
|
|
1980
|
+
args: TArgs,
|
|
1981
|
+
) => Promise<Array<QueryInsertResultRow<TName, TArgs>>>;
|
|
1967
1982
|
update: (args: QueryUpdateArgs<TName>) => Promise<Array<TableModel<TName>>>;
|
|
1968
1983
|
upsert: (args: QueryUpsertArgs<TName>) => Promise<Array<TableModel<TName>>>;
|
|
1969
1984
|
delete: (args?: QueryDeleteArgs<TName>) => Promise<Array<TableModel<TName>>>;
|
|
@@ -3068,45 +3083,44 @@ type TableModel<TName extends TableName> = InferSelectModel<
|
|
|
3068
3083
|
(typeof mergedSchema)[TName]
|
|
3069
3084
|
>;
|
|
3070
3085
|
type ManyToManySchemaMap = typeof schema extends {
|
|
3071
|
-
__appflareManyToMany: infer TMap
|
|
3086
|
+
__appflareManyToMany: infer TMap extends Record<string, unknown>;
|
|
3072
3087
|
}
|
|
3073
|
-
? TMap
|
|
3074
|
-
? TMap
|
|
3075
|
-
: {}
|
|
3088
|
+
? TMap
|
|
3076
3089
|
: {};
|
|
3090
|
+
type ManyToManySourceTableMap<TSourceTable extends TableName> =
|
|
3091
|
+
TSourceTable extends keyof ManyToManySchemaMap
|
|
3092
|
+
? ManyToManySchemaMap[TSourceTable] extends Record<string, unknown>
|
|
3093
|
+
? ManyToManySchemaMap[TSourceTable]
|
|
3094
|
+
: {}
|
|
3095
|
+
: {};
|
|
3077
3096
|
type ManyToManyTargetTableName<
|
|
3078
3097
|
TSourceTable extends TableName,
|
|
3079
3098
|
TRelationName extends string,
|
|
3080
|
-
> =
|
|
3081
|
-
? TRelationName extends
|
|
3082
|
-
? ManyToManySchemaMap[TSourceTable][TRelationName] extends {
|
|
3099
|
+
> = TRelationName extends keyof ManyToManySourceTableMap<TSourceTable>
|
|
3100
|
+
? ManyToManySourceTableMap<TSourceTable>[TRelationName] extends {
|
|
3083
3101
|
targetTable: infer TTarget extends string;
|
|
3084
3102
|
}
|
|
3085
3103
|
? Extract<TTarget, TableName>
|
|
3086
3104
|
: never
|
|
3087
|
-
: never
|
|
3088
3105
|
: never;
|
|
3089
3106
|
type RuntimeRelationsSchemaMap = typeof schema extends {
|
|
3090
|
-
__appflareRelations: infer TMap
|
|
3107
|
+
__appflareRelations: infer TMap extends Record<string, unknown>;
|
|
3091
3108
|
}
|
|
3092
|
-
? TMap
|
|
3093
|
-
string,
|
|
3094
|
-
Record<string, { kind: string; targetTable: string }>
|
|
3095
|
-
>
|
|
3096
|
-
? TMap
|
|
3097
|
-
: {}
|
|
3109
|
+
? TMap
|
|
3098
3110
|
: {};
|
|
3099
|
-
type
|
|
3111
|
+
type RuntimeRelationsSourceTableMap<TSourceTable extends TableName> =
|
|
3100
3112
|
TSourceTable extends keyof RuntimeRelationsSchemaMap
|
|
3101
|
-
?
|
|
3102
|
-
|
|
3113
|
+
? RuntimeRelationsSchemaMap[TSourceTable] extends Record<string, unknown>
|
|
3114
|
+
? RuntimeRelationsSchemaMap[TSourceTable]
|
|
3115
|
+
: {}
|
|
3116
|
+
: {};
|
|
3117
|
+
type RuntimeRelationName<TSourceTable extends TableName> =
|
|
3118
|
+
Extract<keyof RuntimeRelationsSourceTableMap<TSourceTable>, string>;
|
|
3103
3119
|
type RuntimeRelationConfig<
|
|
3104
3120
|
TSourceTable extends TableName,
|
|
3105
3121
|
TRelationName extends string,
|
|
3106
|
-
> =
|
|
3107
|
-
? TRelationName
|
|
3108
|
-
? RuntimeRelationsSchemaMap[TSourceTable][TRelationName]
|
|
3109
|
-
: never
|
|
3122
|
+
> = TRelationName extends keyof RuntimeRelationsSourceTableMap<TSourceTable>
|
|
3123
|
+
? RuntimeRelationsSourceTableMap<TSourceTable>[TRelationName]
|
|
3110
3124
|
: never;
|
|
3111
3125
|
type RuntimeRelationKind<
|
|
3112
3126
|
TSourceTable extends TableName,
|
|
@@ -3124,10 +3138,7 @@ type RuntimeRelationTargetTable<
|
|
|
3124
3138
|
}
|
|
3125
3139
|
? Extract<TTarget, TableName>
|
|
3126
3140
|
: never;
|
|
3127
|
-
type TableInsertScalarModel<TName extends TableName> =
|
|
3128
|
-
TableInsertModel<TName>,
|
|
3129
|
-
RuntimeRelationName<TName>
|
|
3130
|
-
>;
|
|
3141
|
+
type TableInsertScalarModel<TName extends TableName> = TableInsertModel<TName>;
|
|
3131
3142
|
type FindManyWithFromArgs<TArgs> = TArgs extends { with?: infer TWith }
|
|
3132
3143
|
? TWith
|
|
3133
3144
|
: undefined;
|
|
@@ -3156,11 +3167,12 @@ type ReplaceManyToManyRelationsInRow<
|
|
|
3156
3167
|
[K in keyof TRow]: K extends string
|
|
3157
3168
|
? TWith extends Record<string, unknown>
|
|
3158
3169
|
? K extends keyof TWith
|
|
3159
|
-
? ManyToManyTargetTableName<TSourceTable, K> extends
|
|
3160
|
-
?
|
|
3161
|
-
|
|
3162
|
-
|
|
3163
|
-
|
|
3170
|
+
? [ManyToManyTargetTableName<TSourceTable, K>] extends [never]
|
|
3171
|
+
? TRow[K]
|
|
3172
|
+
: ManyToManyRelationRows<
|
|
3173
|
+
Extract<ManyToManyTargetTableName<TSourceTable, K>, TableName>,
|
|
3174
|
+
TWith[K]
|
|
3175
|
+
>
|
|
3164
3176
|
: TRow[K]
|
|
3165
3177
|
: TRow[K]
|
|
3166
3178
|
: TRow[K];
|
|
@@ -3222,10 +3234,7 @@ type TableFindFirstArgs<TName extends TableName> = Omit<
|
|
|
3222
3234
|
TableFindManyArgs<TName>,
|
|
3223
3235
|
"limit"
|
|
3224
3236
|
>;
|
|
3225
|
-
type NativeFindFirstWith<TName extends TableName> =
|
|
3226
|
-
NonNullable<TableFindFirstArgs<TName>> extends { with?: infer TWith }
|
|
3227
|
-
? TWith
|
|
3228
|
-
: never;
|
|
3237
|
+
type NativeFindFirstWith<TName extends TableName> = NativeFindManyWith<TName>;
|
|
3229
3238
|
type ResolveNativeFindFirstWith<
|
|
3230
3239
|
TName extends TableName,
|
|
3231
3240
|
TArgs extends QueryFindFirstArgs<TName> | undefined,
|
|
@@ -3611,7 +3620,7 @@ type TableInsertModel<TName extends TableName> = InferInsertModel<
|
|
|
3611
3620
|
};
|
|
3612
3621
|
|
|
3613
3622
|
const tableApi = {
|
|
3614
|
-
`}function
|
|
3623
|
+
`}function Ie(){return ` insert: async <TArgs extends QueryInsertArgs<TableName>>(args: TArgs) => {
|
|
3615
3624
|
const transaction = ($db as any).transaction;
|
|
3616
3625
|
|
|
3617
3626
|
const valuesArray = Array.isArray(args.values)
|
|
@@ -3626,16 +3635,6 @@ type TableInsertModel<TName extends TableName> = InferInsertModel<
|
|
|
3626
3635
|
}>
|
|
3627
3636
|
> = [];
|
|
3628
3637
|
|
|
3629
|
-
const resolveSingularAlias = (relationName: string): string => {
|
|
3630
|
-
if (relationName.endsWith("ies")) {
|
|
3631
|
-
return relationName.slice(0, -3) + "yId";
|
|
3632
|
-
}
|
|
3633
|
-
if (relationName.endsWith("s") && relationName.length > 1) {
|
|
3634
|
-
return relationName.slice(0, -1) + "Id";
|
|
3635
|
-
}
|
|
3636
|
-
return relationName + "Id";
|
|
3637
|
-
};
|
|
3638
|
-
|
|
3639
3638
|
const toRelationItems = (
|
|
3640
3639
|
relation: RuntimeRelation,
|
|
3641
3640
|
relationName: string,
|
|
@@ -3688,7 +3687,7 @@ type TableInsertModel<TName extends TableName> = InferInsertModel<
|
|
|
3688
3687
|
const referenceField =
|
|
3689
3688
|
relation.kind === "manyToMany"
|
|
3690
3689
|
? (relation.targetReferenceField ?? "id")
|
|
3691
|
-
: "id";
|
|
3690
|
+
: (relation.referenceField ?? "id");
|
|
3692
3691
|
const existingId = input[referenceField];
|
|
3693
3692
|
if (existingId !== undefined && existingId !== null) {
|
|
3694
3693
|
return existingId;
|
|
@@ -3741,6 +3740,74 @@ type TableInsertModel<TName extends TableName> = InferInsertModel<
|
|
|
3741
3740
|
return createdId;
|
|
3742
3741
|
};
|
|
3743
3742
|
|
|
3743
|
+
const getRelationTargetTable = (
|
|
3744
|
+
relation: RuntimeRelation,
|
|
3745
|
+
relationName: string,
|
|
3746
|
+
): any => {
|
|
3747
|
+
const targetTable = (mergedSchema as Record<string, unknown>)[
|
|
3748
|
+
relation.targetTable
|
|
3749
|
+
];
|
|
3750
|
+
if (!targetTable) {
|
|
3751
|
+
throw new Error(
|
|
3752
|
+
"Unknown target table '" +
|
|
3753
|
+
relation.targetTable +
|
|
3754
|
+
"' for relation '" +
|
|
3755
|
+
tableName +
|
|
3756
|
+
"." +
|
|
3757
|
+
relationName +
|
|
3758
|
+
"'.",
|
|
3759
|
+
);
|
|
3760
|
+
}
|
|
3761
|
+
return targetTable;
|
|
3762
|
+
};
|
|
3763
|
+
|
|
3764
|
+
const getRelationReferenceField = (relation: RuntimeRelation): string => {
|
|
3765
|
+
if (relation.kind === "manyToMany") {
|
|
3766
|
+
return relation.targetReferenceField ?? "id";
|
|
3767
|
+
}
|
|
3768
|
+
return relation.referenceField ?? "id";
|
|
3769
|
+
};
|
|
3770
|
+
|
|
3771
|
+
const fetchRelatedRowByIdentifier = async (
|
|
3772
|
+
tx: any,
|
|
3773
|
+
relation: RuntimeRelation,
|
|
3774
|
+
relationName: string,
|
|
3775
|
+
identifier: unknown,
|
|
3776
|
+
): Promise<Record<string, unknown> | null> => {
|
|
3777
|
+
if (identifier === undefined || identifier === null) {
|
|
3778
|
+
return null;
|
|
3779
|
+
}
|
|
3780
|
+
|
|
3781
|
+
const targetTable = getRelationTargetTable(relation, relationName);
|
|
3782
|
+
const referenceField = getRelationReferenceField(relation);
|
|
3783
|
+
const referenceColumn = (targetTable as Record<string, unknown>)[
|
|
3784
|
+
referenceField
|
|
3785
|
+
];
|
|
3786
|
+
if (!referenceColumn) {
|
|
3787
|
+
throw new Error(
|
|
3788
|
+
"Target table '" +
|
|
3789
|
+
relation.targetTable +
|
|
3790
|
+
"' is missing column '" +
|
|
3791
|
+
referenceField +
|
|
3792
|
+
"' required by relation '" +
|
|
3793
|
+
tableName +
|
|
3794
|
+
"." +
|
|
3795
|
+
relationName +
|
|
3796
|
+
"'.",
|
|
3797
|
+
);
|
|
3798
|
+
}
|
|
3799
|
+
|
|
3800
|
+
let query: any = tx
|
|
3801
|
+
.select()
|
|
3802
|
+
.from(targetTable as any)
|
|
3803
|
+
.where(eq(referenceColumn as any, identifier as any));
|
|
3804
|
+
if (typeof query.limit === "function") {
|
|
3805
|
+
query = query.limit(1);
|
|
3806
|
+
}
|
|
3807
|
+
const rows = (await query) as Array<Record<string, unknown>>;
|
|
3808
|
+
return rows[0] ?? null;
|
|
3809
|
+
};
|
|
3810
|
+
|
|
3744
3811
|
for (const inputValue of valuesArray) {
|
|
3745
3812
|
const scalarValues: Record<string, unknown> = {};
|
|
3746
3813
|
const relationInputs: Array<{
|
|
@@ -3760,50 +3827,16 @@ type TableInsertModel<TName extends TableName> = InferInsertModel<
|
|
|
3760
3827
|
});
|
|
3761
3828
|
continue;
|
|
3762
3829
|
}
|
|
3763
|
-
|
|
3764
|
-
let matchedAlias = false;
|
|
3765
|
-
if (fieldName.endsWith("Id")) {
|
|
3766
|
-
for (const [relationName, relationValue] of Object.entries(
|
|
3767
|
-
runtimeRelationMap[tableName] ?? {},
|
|
3768
|
-
)) {
|
|
3769
|
-
const pluralAlias = relationName + "Id";
|
|
3770
|
-
const singularAlias = resolveSingularAlias(relationName);
|
|
3771
|
-
if (fieldName !== pluralAlias && fieldName !== singularAlias) {
|
|
3772
|
-
continue;
|
|
3773
|
-
}
|
|
3774
|
-
|
|
3775
|
-
if (valueRecord[relationName] !== undefined) {
|
|
3776
|
-
throw new Error(
|
|
3777
|
-
"Insert payload for '" +
|
|
3778
|
-
tableName +
|
|
3779
|
-
"' cannot contain both '" +
|
|
3780
|
-
relationName +
|
|
3781
|
-
"' and '" +
|
|
3782
|
-
fieldName +
|
|
3783
|
-
"'.",
|
|
3784
|
-
);
|
|
3785
|
-
}
|
|
3786
|
-
|
|
3787
|
-
relationInputs.push({
|
|
3788
|
-
relationName,
|
|
3789
|
-
relation: relationValue,
|
|
3790
|
-
value: fieldValue,
|
|
3791
|
-
});
|
|
3792
|
-
matchedAlias = true;
|
|
3793
|
-
break;
|
|
3794
|
-
}
|
|
3795
|
-
}
|
|
3796
|
-
|
|
3797
|
-
if (!matchedAlias) {
|
|
3798
|
-
scalarValues[fieldName] = fieldValue;
|
|
3799
|
-
}
|
|
3830
|
+
scalarValues[fieldName] = fieldValue;
|
|
3800
3831
|
}
|
|
3801
3832
|
|
|
3802
3833
|
baseValuesArray.push(scalarValues);
|
|
3803
3834
|
postInsertRelations.push(relationInputs);
|
|
3804
3835
|
}
|
|
3805
3836
|
|
|
3806
|
-
const executeInsertGraph = async (
|
|
3837
|
+
const executeInsertGraph = async (
|
|
3838
|
+
tx: any,
|
|
3839
|
+
): Promise<Array<QueryInsertResultRow<TableName, TArgs>>> => {
|
|
3807
3840
|
for (let index = 0; index < baseValuesArray.length; index += 1) {
|
|
3808
3841
|
const relationInputs = postInsertRelations[index] ?? [];
|
|
3809
3842
|
for (const relationInput of relationInputs) {
|
|
@@ -3859,13 +3892,46 @@ type TableInsertModel<TName extends TableName> = InferInsertModel<
|
|
|
3859
3892
|
insertQuery = insertQuery.returning();
|
|
3860
3893
|
}
|
|
3861
3894
|
const insertedRows = (await insertQuery) as Array<TableModel<TableName>>;
|
|
3895
|
+
const hydratedRows: Array<Record<string, unknown>> = [];
|
|
3862
3896
|
|
|
3863
3897
|
for (let index = 0; index < insertedRows.length; index += 1) {
|
|
3864
3898
|
const parentRow = insertedRows[index] as unknown as Record<string, unknown>;
|
|
3899
|
+
const hydratedRow: Record<string, unknown> = {
|
|
3900
|
+
...parentRow,
|
|
3901
|
+
};
|
|
3865
3902
|
const relationInputs = postInsertRelations[index] ?? [];
|
|
3866
3903
|
|
|
3867
3904
|
for (const relationInput of relationInputs) {
|
|
3868
3905
|
if (relationInput.relation.kind === "one") {
|
|
3906
|
+
const sourceField = relationInput.relation.sourceField;
|
|
3907
|
+
if (!sourceField) {
|
|
3908
|
+
throw new Error(
|
|
3909
|
+
"Relation '" +
|
|
3910
|
+
tableName +
|
|
3911
|
+
"." +
|
|
3912
|
+
relationInput.relationName +
|
|
3913
|
+
"' is missing sourceField metadata.",
|
|
3914
|
+
);
|
|
3915
|
+
}
|
|
3916
|
+
|
|
3917
|
+
const relationItems = toRelationItems(
|
|
3918
|
+
relationInput.relation,
|
|
3919
|
+
relationInput.relationName,
|
|
3920
|
+
relationInput.value,
|
|
3921
|
+
);
|
|
3922
|
+
if (relationItems.length === 0) {
|
|
3923
|
+
hydratedRow[relationInput.relationName] = null;
|
|
3924
|
+
continue;
|
|
3925
|
+
}
|
|
3926
|
+
|
|
3927
|
+
const sourceIdentifier = parentRow[sourceField];
|
|
3928
|
+
hydratedRow[relationInput.relationName] =
|
|
3929
|
+
(await fetchRelatedRowByIdentifier(
|
|
3930
|
+
tx,
|
|
3931
|
+
relationInput.relation,
|
|
3932
|
+
relationInput.relationName,
|
|
3933
|
+
sourceIdentifier,
|
|
3934
|
+
)) ?? null;
|
|
3869
3935
|
continue;
|
|
3870
3936
|
}
|
|
3871
3937
|
|
|
@@ -3886,6 +3952,9 @@ type TableInsertModel<TName extends TableName> = InferInsertModel<
|
|
|
3886
3952
|
);
|
|
3887
3953
|
}
|
|
3888
3954
|
|
|
3955
|
+
const relatedRows: Array<Record<string, unknown>> = [];
|
|
3956
|
+
hydratedRow[relationInput.relationName] = relatedRows;
|
|
3957
|
+
|
|
3889
3958
|
const relationItems = toRelationItems(
|
|
3890
3959
|
relationInput.relation,
|
|
3891
3960
|
relationInput.relationName,
|
|
@@ -3896,29 +3965,36 @@ type TableInsertModel<TName extends TableName> = InferInsertModel<
|
|
|
3896
3965
|
}
|
|
3897
3966
|
|
|
3898
3967
|
if (relationInput.relation.kind === "many") {
|
|
3899
|
-
const targetTable = (
|
|
3900
|
-
relationInput.relation
|
|
3901
|
-
|
|
3902
|
-
|
|
3968
|
+
const targetTable = getRelationTargetTable(
|
|
3969
|
+
relationInput.relation,
|
|
3970
|
+
relationInput.relationName,
|
|
3971
|
+
);
|
|
3972
|
+
|
|
3973
|
+
const sourceField = relationInput.relation.sourceField;
|
|
3974
|
+
const targetReferenceField =
|
|
3975
|
+
relationInput.relation.referenceField ?? "id";
|
|
3976
|
+
const targetReferenceColumn =
|
|
3977
|
+
(targetTable as Record<string, unknown>)[targetReferenceField];
|
|
3978
|
+
if (!sourceField) {
|
|
3903
3979
|
throw new Error(
|
|
3904
|
-
"
|
|
3905
|
-
relationInput.relation.targetTable +
|
|
3906
|
-
"' for relation '" +
|
|
3980
|
+
"Relation '" +
|
|
3907
3981
|
tableName +
|
|
3908
3982
|
"." +
|
|
3909
3983
|
relationInput.relationName +
|
|
3910
|
-
"'.",
|
|
3984
|
+
"' is missing sourceField metadata.",
|
|
3911
3985
|
);
|
|
3912
3986
|
}
|
|
3913
|
-
|
|
3914
|
-
const sourceField = relationInput.relation.sourceField;
|
|
3915
|
-
if (!sourceField) {
|
|
3987
|
+
if (!targetReferenceColumn) {
|
|
3916
3988
|
throw new Error(
|
|
3917
|
-
"
|
|
3989
|
+
"Target table '" +
|
|
3990
|
+
relationInput.relation.targetTable +
|
|
3991
|
+
"' is missing column '" +
|
|
3992
|
+
targetReferenceField +
|
|
3993
|
+
"' required by relation '" +
|
|
3918
3994
|
tableName +
|
|
3919
3995
|
"." +
|
|
3920
3996
|
relationInput.relationName +
|
|
3921
|
-
"'
|
|
3997
|
+
"'.",
|
|
3922
3998
|
);
|
|
3923
3999
|
}
|
|
3924
4000
|
|
|
@@ -3931,7 +4007,18 @@ type TableInsertModel<TName extends TableName> = InferInsertModel<
|
|
|
3931
4007
|
await tx
|
|
3932
4008
|
.update(targetTable as any)
|
|
3933
4009
|
.set({ [sourceField]: parentReferenceValue } as any)
|
|
3934
|
-
.where(
|
|
4010
|
+
.where(
|
|
4011
|
+
eq(targetReferenceColumn as any, relationItem as any),
|
|
4012
|
+
);
|
|
4013
|
+
const linkedRow = await fetchRelatedRowByIdentifier(
|
|
4014
|
+
tx,
|
|
4015
|
+
relationInput.relation,
|
|
4016
|
+
relationInput.relationName,
|
|
4017
|
+
relationItem,
|
|
4018
|
+
);
|
|
4019
|
+
if (linkedRow) {
|
|
4020
|
+
relatedRows.push(linkedRow);
|
|
4021
|
+
}
|
|
3935
4022
|
continue;
|
|
3936
4023
|
}
|
|
3937
4024
|
|
|
@@ -3945,22 +4032,48 @@ type TableInsertModel<TName extends TableName> = InferInsertModel<
|
|
|
3945
4032
|
);
|
|
3946
4033
|
}
|
|
3947
4034
|
|
|
3948
|
-
const existingId = relationItem
|
|
4035
|
+
const existingId = relationItem[targetReferenceField];
|
|
3949
4036
|
const payload = {
|
|
3950
4037
|
...relationItem,
|
|
3951
4038
|
[sourceField]: parentReferenceValue,
|
|
3952
4039
|
};
|
|
3953
4040
|
|
|
3954
4041
|
if (existingId !== undefined && existingId !== null) {
|
|
3955
|
-
const
|
|
4042
|
+
const setPayload: Record<string, unknown> = {
|
|
4043
|
+
...payload,
|
|
4044
|
+
};
|
|
4045
|
+
delete setPayload[targetReferenceField];
|
|
3956
4046
|
await tx
|
|
3957
4047
|
.update(targetTable as any)
|
|
3958
4048
|
.set(setPayload as any)
|
|
3959
|
-
.where(
|
|
4049
|
+
.where(
|
|
4050
|
+
eq(targetReferenceColumn as any, existingId as any),
|
|
4051
|
+
);
|
|
4052
|
+
const linkedRow = await fetchRelatedRowByIdentifier(
|
|
4053
|
+
tx,
|
|
4054
|
+
relationInput.relation,
|
|
4055
|
+
relationInput.relationName,
|
|
4056
|
+
existingId,
|
|
4057
|
+
);
|
|
4058
|
+
if (linkedRow) {
|
|
4059
|
+
relatedRows.push(linkedRow);
|
|
4060
|
+
}
|
|
3960
4061
|
continue;
|
|
3961
4062
|
}
|
|
3962
4063
|
|
|
3963
|
-
|
|
4064
|
+
let createQuery: any = tx
|
|
4065
|
+
.insert(targetTable as any)
|
|
4066
|
+
.values(payload as any);
|
|
4067
|
+
if (typeof createQuery.returning === "function") {
|
|
4068
|
+
createQuery = createQuery.returning();
|
|
4069
|
+
}
|
|
4070
|
+
const createdRows = (await createQuery) as Array<
|
|
4071
|
+
Record<string, unknown>
|
|
4072
|
+
>;
|
|
4073
|
+
const createdRow = createdRows[0];
|
|
4074
|
+
if (createdRow) {
|
|
4075
|
+
relatedRows.push(createdRow);
|
|
4076
|
+
}
|
|
3964
4077
|
}
|
|
3965
4078
|
continue;
|
|
3966
4079
|
}
|
|
@@ -3993,6 +4106,7 @@ type TableInsertModel<TName extends TableName> = InferInsertModel<
|
|
|
3993
4106
|
}
|
|
3994
4107
|
|
|
3995
4108
|
const linkValues: Array<Record<string, unknown>> = [];
|
|
4109
|
+
const targetIdentifiers: unknown[] = [];
|
|
3996
4110
|
for (const relationItem of relationItems) {
|
|
3997
4111
|
const targetId = await resolveRelationIdentifier(
|
|
3998
4112
|
tx,
|
|
@@ -4000,6 +4114,7 @@ type TableInsertModel<TName extends TableName> = InferInsertModel<
|
|
|
4000
4114
|
relationInput.relationName,
|
|
4001
4115
|
relationItem,
|
|
4002
4116
|
);
|
|
4117
|
+
targetIdentifiers.push(targetId);
|
|
4003
4118
|
|
|
4004
4119
|
linkValues.push({
|
|
4005
4120
|
[sourceField]: parentReferenceValue,
|
|
@@ -4010,13 +4125,27 @@ type TableInsertModel<TName extends TableName> = InferInsertModel<
|
|
|
4010
4125
|
if (linkValues.length > 0) {
|
|
4011
4126
|
await tx.insert(junctionTable as any).values(linkValues as any);
|
|
4012
4127
|
}
|
|
4128
|
+
|
|
4129
|
+
for (const targetId of targetIdentifiers) {
|
|
4130
|
+
const linkedRow = await fetchRelatedRowByIdentifier(
|
|
4131
|
+
tx,
|
|
4132
|
+
relationInput.relation,
|
|
4133
|
+
relationInput.relationName,
|
|
4134
|
+
targetId,
|
|
4135
|
+
);
|
|
4136
|
+
if (linkedRow) {
|
|
4137
|
+
relatedRows.push(linkedRow);
|
|
4138
|
+
}
|
|
4139
|
+
}
|
|
4013
4140
|
}
|
|
4141
|
+
|
|
4142
|
+
hydratedRows.push(hydratedRow);
|
|
4014
4143
|
}
|
|
4015
4144
|
|
|
4016
|
-
return
|
|
4145
|
+
return hydratedRows as Array<QueryInsertResultRow<TableName, TArgs>>;
|
|
4017
4146
|
};
|
|
4018
4147
|
|
|
4019
|
-
let rows: Array<
|
|
4148
|
+
let rows: Array<QueryInsertResultRow<TableName, TArgs>>;
|
|
4020
4149
|
if (typeof transaction === "function") {
|
|
4021
4150
|
try {
|
|
4022
4151
|
rows = await transaction.call($db, (tx: any) =>
|
|
@@ -4164,9 +4293,9 @@ type TableInsertModel<TName extends TableName> = InferInsertModel<
|
|
|
4164
4293
|
);
|
|
4165
4294
|
return rows;
|
|
4166
4295
|
},
|
|
4167
|
-
`}function
|
|
4296
|
+
`}function Ce(){return [qe(),$e(),Ie(),Ae(),Ne()].join(`
|
|
4168
4297
|
|
|
4169
|
-
`)}function
|
|
4298
|
+
`)}function Me(){return `type AuthSession = typeof auth.$Infer.Session;
|
|
4170
4299
|
type User = AuthSession['user']
|
|
4171
4300
|
type Session = AuthSession['session']
|
|
4172
4301
|
|
|
@@ -4227,7 +4356,7 @@ export type AppflareContext = {
|
|
|
4227
4356
|
storage: AppflareStorage;
|
|
4228
4357
|
error: (status: number, message: string, details?: unknown) => never;
|
|
4229
4358
|
};
|
|
4230
|
-
`}function
|
|
4359
|
+
`}function Pe(){return `type InferOperationArgs<TShape extends ZodRawShape> = z.output<z.ZodObject<TShape>>;
|
|
4231
4360
|
|
|
4232
4361
|
export type SchedulerEnqueueOptions = {
|
|
4233
4362
|
delaySeconds?: number;
|
|
@@ -4359,7 +4488,7 @@ export function cron(definition: CronDefinition): RegisteredCron {
|
|
|
4359
4488
|
definition,
|
|
4360
4489
|
};
|
|
4361
4490
|
}
|
|
4362
|
-
`}function De(){return [xe(),Se(),
|
|
4491
|
+
`}function De(){return [xe(),Se(),Ce(),Me(),Pe()].join(`
|
|
4363
4492
|
|
|
4364
4493
|
`)}function Ee(e){return `import type { Context } from "hono";
|
|
4365
4494
|
import type { D1Database } from "@cloudflare/workers-types";
|
|
@@ -4369,7 +4498,7 @@ import * as authSchema from "./auth.schema";
|
|
|
4369
4498
|
import * as schema from "${e}";
|
|
4370
4499
|
|
|
4371
4500
|
${De()}
|
|
4372
|
-
`}function
|
|
4501
|
+
`}function Fn(e){let t=e.replace(/[^A-Za-z0-9_]/g,"_");return /^[0-9]/.test(t)?`_${t}`:t}function On(e,t){let n=e.routePath.replace(/^\//,"").replace(/\//g,"_");return Fn(`op_${t}_${n}`)}function jn(e){return e.map((t,n)=>({operation:t,index:n,alias:On(t,n)}))}function Vn(e){return e.map(({operation:t,alias:n})=>`import { ${t.exportName} as ${n} } from "${t.importPath}";`).join(`
|
|
4373
4502
|
`)}function Bn(e){return e.filter(({operation:t})=>t.kind==="query"||t.kind==="mutation").map(({alias:t})=>`const ${`${t}Schema`} = z.object(${t}.definition.args);`).join(`
|
|
4374
4503
|
`)}function Hn(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(`
|
|
4375
4504
|
`)}function Wn(e){return e.filter(({operation:t})=>t.kind==="query").map(({operation:t,alias:n})=>{let r=`${n}Schema`;return `
|
|
@@ -4419,7 +4548,7 @@ ${De()}
|
|
|
4419
4548
|
},`}).join(`
|
|
4420
4549
|
`)}function Kn(e){return e.filter(({operation:t})=>t.kind==="storage").map(({alias:t})=>`
|
|
4421
4550
|
${t}.definition.handler,`).join(`
|
|
4422
|
-
`)}function
|
|
4551
|
+
`)}function Fe(e){let t=jn(e);return {imports:Vn(t),operationSchemas:Bn(t),schedulerSchemas:Hn(t),queryRoutes:Wn(t),mutationRoutes:Ln(t),queryRegistryEntries:zn(t),schedulerEntries:Un(t),schedulerPayloadMapEntries:Qn(t),cronEntries:_n(t),storageHandlersEntries:Kn(t)}}var Oe=`
|
|
4423
4552
|
function getRealtimeStub(
|
|
4424
4553
|
env: Record<string, unknown>,
|
|
4425
4554
|
options: RegisterHandlersOptions,
|
|
@@ -5444,7 +5573,7 @@ function doesSubscriptionMatchMutation(
|
|
|
5444
5573
|
|
|
5445
5574
|
return false;
|
|
5446
5575
|
}
|
|
5447
|
-
`;var Le=[He,We,
|
|
5576
|
+
`;var Le=[He,We,Oe,Ve,Be,je].join(`
|
|
5448
5577
|
|
|
5449
5578
|
`);var ze=`
|
|
5450
5579
|
function parseExpiresIn(value: string | undefined): number | undefined {
|
|
@@ -5723,7 +5852,7 @@ export async function executeCronTriggers(
|
|
|
5723
5852
|
}
|
|
5724
5853
|
}
|
|
5725
5854
|
}
|
|
5726
|
-
`;function _e(e){let{imports:t,operationSchemas:n,schedulerSchemas:r,queryRoutes:a,mutationRoutes:o,queryRegistryEntries:i,schedulerEntries:s,schedulerPayloadMapEntries:l,cronEntries:u,storageHandlersEntries:c}=
|
|
5855
|
+
`;function _e(e){let{imports:t,operationSchemas:n,schedulerSchemas:r,queryRoutes:a,mutationRoutes:o,queryRegistryEntries:i,schedulerEntries:s,schedulerPayloadMapEntries:l,cronEntries:u,storageHandlersEntries:c}=Fe(e);return `import { sValidator } from "@hono/standard-validator";
|
|
5727
5856
|
import type { Hono } from "hono";
|
|
5728
5857
|
import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@cloudflare/workers-types";
|
|
5729
5858
|
import { ZodError, z } from "zod";
|
|
@@ -5965,7 +6094,7 @@ import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@clou
|
|
|
5965
6094
|
<span class="text-[10px] opacity-30">\${sort === '${n}' ? (order === 'asc' ? '\u25B2' : '\u25BC') : ''}</span>
|
|
5966
6095
|
</a>
|
|
5967
6096
|
</th>
|
|
5968
|
-
`}).join("")}function pt(e){return e.map(t
|
|
6097
|
+
`}).join("")}function pt(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 L(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"?`
|
|
5969
6098
|
<div class="form-control">
|
|
5970
6099
|
<label class="label cursor-pointer justify-start gap-3">
|
|
5971
6100
|
<input type="checkbox" name="${t}" value="true" class="checkbox checkbox-sm checkbox-primary" \${(row as any).${t} ? 'checked' : ''} />
|
|
@@ -6101,7 +6230,7 @@ import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@clou
|
|
|
6101
6230
|
</div>
|
|
6102
6231
|
</div>
|
|
6103
6232
|
</div>
|
|
6104
|
-
</td>`:'<td class="text-right"><span class="text-xs opacity-30">No primary key</span></td>'}function
|
|
6233
|
+
</td>`:'<td class="text-right"><span class="text-xs opacity-30">No primary key</span></td>'}function I(e){return `
|
|
6105
6234
|
<div class="flex flex-col sm:flex-row justify-between items-center mt-4 gap-3 py-3 px-1">
|
|
6106
6235
|
<div class="text-xs text-base-content/40">
|
|
6107
6236
|
Total found: <span class="font-medium text-base-content/60">\${total}</span>
|
|
@@ -6123,7 +6252,7 @@ import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@clou
|
|
|
6123
6252
|
\` : 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>\`}
|
|
6124
6253
|
</div>
|
|
6125
6254
|
\` : ''}
|
|
6126
|
-
</div>`}function
|
|
6255
|
+
</div>`}function C(e,t="Search term or filter..."){return `
|
|
6127
6256
|
<div class="form-control w-full md:w-auto relative">
|
|
6128
6257
|
<iconify-icon icon="mdi:magnify" width="18" height="18" class="absolute left-3 top-1/2 -translate-y-1/2 opacity-40"></iconify-icon>
|
|
6129
6258
|
<input type="text"
|
|
@@ -6134,7 +6263,7 @@ import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@clou
|
|
|
6134
6263
|
hx-trigger="keyup changed delay:500ms, search"
|
|
6135
6264
|
hx-target="#main-content"
|
|
6136
6265
|
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" />
|
|
6137
|
-
</div>`}function bt(e,t,n,r,a,o,i,s,l,u){let c=
|
|
6266
|
+
</div>`}function bt(e,t,n,r,a,o,i,s,l,u){let c=I(`/admin/table/${e.exportName}`),f=C(`/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?`
|
|
6138
6267
|
<div id="bulk-delete-bar-${e.exportName}" class="fixed bottom-4 left-1/2 -translate-x-1/2 z-40 hidden">
|
|
6139
6268
|
<div class="bg-base-100 border border-base-200 rounded-xl shadow-lg px-3 py-2 flex items-center gap-3">
|
|
6140
6269
|
<div class="text-xs text-base-content/70">
|
|
@@ -6519,7 +6648,7 @@ import type { D1Database, IncomingRequestCfProperties, KVNamespace } from "@clou
|
|
|
6519
6648
|
return c.redirect('/admin/table/${e}?' + query.toString());
|
|
6520
6649
|
});
|
|
6521
6650
|
${c}
|
|
6522
|
-
`}function U(e){let t=mt(e),n=!!t,r=e.columns.map(m=>m.name),a=r.filter(m=>gt(e,m)),o=r.filter(m=>ft(e,m)),i=ut(e),s=dt(e,r),l=pt(r),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=ht(e,n,t,c);return bt(e,y,t,n,r,i,s,l,b,u)+`
|
|
6651
|
+
`}function U(e){let t=mt(e),n=!!t,r=e.columns.map(m=>m.name),a=r.filter(m=>gt(e,m)),o=r.filter(m=>ft(e,m)),i=ut(e),s=dt(e,r),l=pt(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=ht(e,n,t,c);return bt(e,y,t,n,r,i,s,l,b,u)+`
|
|
6523
6652
|
`+yt(e.exportName,y,t,w,n,i,f,d)}function wt(){return `
|
|
6524
6653
|
const buildUsersRedirect = (params: { page?: string; sort?: string; order?: string; search?: string }) => {
|
|
6525
6654
|
const page = params.page && params.page.trim() ? params.page : '1';
|
|
@@ -6570,7 +6699,7 @@ ${c}
|
|
|
6570
6699
|
<label class="modal-backdrop" for="delete-user-modal-\${String((row as any).id)}">Close</label>
|
|
6571
6700
|
</div>
|
|
6572
6701
|
\`}`}var er=["id","name","email","role","createdAt","banned"],tr={id:"mdi:pound",name:"mdi:format-text",email:"mdi:at",role:"mdi:shield-account-outline",createdAt:"mdi:calendar",banned:"mdi:toggle-switch-outline"};function nr(e){let t=tr[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 Tt(){let e=er.map(nr).join(`
|
|
6573
|
-
`),t=
|
|
6702
|
+
`),t=I("/admin/users");return `
|
|
6574
6703
|
const tableHtml = html\`
|
|
6575
6704
|
<div class="bg-base-100 rounded-xl border border-base-200 overflow-hidden">
|
|
6576
6705
|
<div class="overflow-x-auto">
|
|
@@ -6586,7 +6715,7 @@ ${c}
|
|
|
6586
6715
|
<tbody>
|
|
6587
6716
|
\${data.map((row) => html\`
|
|
6588
6717
|
<tr class="hover:bg-base-200/30 transition-colors">
|
|
6589
|
-
<td><
|
|
6718
|
+
<td><button type="button" class="truncate max-w-[220px] text-sm font-mono text-xs opacity-70 hover:opacity-100 cursor-copy text-left" title="Click to copy: \${String((row as any).id ?? '')}" data-copy-value="\${String((row as any).id ?? '')}" onclick="navigator.clipboard?.writeText(this.dataset.copyValue || '')">\${String((row as any).id ?? '')}</button></td>
|
|
6590
6719
|
<td><div class="truncate max-w-[220px] text-sm" title="\${String((row as any).name ?? '')}">\${String((row as any).name ?? '')}</div></td>
|
|
6591
6720
|
<td><div class="truncate max-w-[260px] text-sm" title="\${String((row as any).email ?? '')}">\${String((row as any).email ?? '')}</div></td>
|
|
6592
6721
|
<td><span class="badge badge-sm \${String((row as any).role ?? '') === 'admin' ? 'badge-primary' : 'badge-ghost'}">\${String((row as any).role ?? '')}</span></td>
|
|
@@ -6654,7 +6783,8 @@ ${vt()}
|
|
|
6654
6783
|
</div>
|
|
6655
6784
|
${t}
|
|
6656
6785
|
</div>
|
|
6657
|
-
|
|
6786
|
+
\`;
|
|
6787
|
+
`}function Rt(){return `
|
|
6658
6788
|
const content = html\`
|
|
6659
6789
|
<div id="main-content">
|
|
6660
6790
|
<div class="flex flex-col md:flex-row justify-between items-start md:items-center mb-5 gap-3">
|
|
@@ -6666,7 +6796,7 @@ ${vt()}
|
|
|
6666
6796
|
<iconify-icon icon="mdi:refresh" width="14" height="14"></iconify-icon>
|
|
6667
6797
|
</button>
|
|
6668
6798
|
</div>
|
|
6669
|
-
${
|
|
6799
|
+
${C("/admin/users","Search users...")}
|
|
6670
6800
|
</div>
|
|
6671
6801
|
\${tableHtml}
|
|
6672
6802
|
</div>
|
|
@@ -7107,7 +7237,7 @@ ${Q()}`}function Nt(e){return `
|
|
|
7107
7237
|
|
|
7108
7238
|
</div>
|
|
7109
7239
|
</div>
|
|
7110
|
-
`}function
|
|
7240
|
+
`}function It(e){let t=e.kind==="query",n=e.routePath,r=e.handlerName??e.routePath;return `
|
|
7111
7241
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/atom-one-dark.min.css">
|
|
7112
7242
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
|
|
7113
7243
|
|
|
@@ -7649,7 +7779,7 @@ ${Q()}`}function Nt(e){return `
|
|
|
7649
7779
|
_rtEnabled = false;
|
|
7650
7780
|
});
|
|
7651
7781
|
</script>
|
|
7652
|
-
`}function
|
|
7782
|
+
`}function Ct(e){return `
|
|
7653
7783
|
const content = html\`
|
|
7654
7784
|
<div class="flex flex-col gap-6 max-w-5xl mx-auto" id="main-content">
|
|
7655
7785
|
${Nt(e)}
|
|
@@ -7663,7 +7793,7 @@ ${Q()}`}function Nt(e){return `
|
|
|
7663
7793
|
</div>
|
|
7664
7794
|
</div>
|
|
7665
7795
|
|
|
7666
|
-
${
|
|
7796
|
+
${It(e)}
|
|
7667
7797
|
\`;
|
|
7668
7798
|
|
|
7669
7799
|
if (c.req.header('hx-request')) {
|
|
@@ -7673,11 +7803,11 @@ ${Q()}`}function Nt(e){return `
|
|
|
7673
7803
|
return c.html(Layout({
|
|
7674
7804
|
title: "${e.exportName} - Functions",
|
|
7675
7805
|
children: content
|
|
7676
|
-
}));`}function
|
|
7806
|
+
}));`}function Mt(e){return e.map(n=>n.kind!=="query"&&n.kind!=="mutation"?"":`
|
|
7677
7807
|
adminApp.get('/functions${n.routePath}', (c) => {
|
|
7678
|
-
${
|
|
7808
|
+
${Ct(n)}
|
|
7679
7809
|
});`).join(`
|
|
7680
|
-
`)}function
|
|
7810
|
+
`)}function Pt(){return `
|
|
7681
7811
|
const getStorageBucket = (c: any): R2Bucket | null => {
|
|
7682
7812
|
const r2Binding = (options as any).r2Binding;
|
|
7683
7813
|
if (!r2Binding || !c.env[r2Binding]) return null;
|
|
@@ -7895,7 +8025,7 @@ ${Q()}`}function Nt(e){return `
|
|
|
7895
8025
|
|
|
7896
8026
|
adminApp.get('/storage', handleStorageListRoute);
|
|
7897
8027
|
adminApp.get('/storage/*', handleStorageListRoute);
|
|
7898
|
-
`}function
|
|
8028
|
+
`}function Ft(){return `
|
|
7899
8029
|
adminApp.post('/storage/upload', async (c) => {
|
|
7900
8030
|
const bucket = getStorageBucket(c);
|
|
7901
8031
|
if (!bucket) return c.text("Storage not configured", 400);
|
|
@@ -7913,7 +8043,7 @@ ${Q()}`}function Nt(e){return `
|
|
|
7913
8043
|
|
|
7914
8044
|
return c.redirect(prefixToStoragePath(prefix));
|
|
7915
8045
|
});
|
|
7916
|
-
`}function
|
|
8046
|
+
`}function Ot(){return `
|
|
7917
8047
|
adminApp.delete('/storage/delete', async (c) => {
|
|
7918
8048
|
const bucket = getStorageBucket(c);
|
|
7919
8049
|
if (!bucket) return c.text("Storage not configured", 400);
|
|
@@ -7997,15 +8127,15 @@ ${Q()}`}function Nt(e){return `
|
|
|
7997
8127
|
|
|
7998
8128
|
${Bt()}
|
|
7999
8129
|
|
|
8000
|
-
${Ot()}
|
|
8001
|
-
|
|
8002
8130
|
${Ft()}
|
|
8003
8131
|
|
|
8132
|
+
${Ot()}
|
|
8133
|
+
|
|
8004
8134
|
${jt()}
|
|
8005
8135
|
|
|
8006
8136
|
${Et()}
|
|
8007
8137
|
`}function Wt(){return `
|
|
8008
|
-
${
|
|
8138
|
+
${Pt()}
|
|
8009
8139
|
|
|
8010
8140
|
${Dt()}
|
|
8011
8141
|
|
|
@@ -8461,7 +8591,7 @@ function Layout(props: { children: any; title: string; hideSidebar?: boolean })
|
|
|
8461
8591
|
\`
|
|
8462
8592
|
}));
|
|
8463
8593
|
});
|
|
8464
|
-
`}function Qt(e,t,n){let r=it(t),a=st(r),o=ct(r),i=At(t),s=
|
|
8594
|
+
`}function Qt(e,t,n){let r=it(t),a=st(r),o=ct(r),i=At(t),s=Mt(n),l=Wt(),u=Lt(a,n),c=zt(),f=Ut(o);return `import { Hono } from "hono";
|
|
8465
8595
|
import { html, raw } from "hono/html";
|
|
8466
8596
|
import { drizzle } from "drizzle-orm/d1";
|
|
8467
8597
|
import { eq, desc, asc, sql, like, or, inArray } from "drizzle-orm";
|
|
@@ -8490,7 +8620,7 @@ ${f}
|
|
|
8490
8620
|
app.route('/admin', adminApp);
|
|
8491
8621
|
app.get('/admin/', (c) => c.redirect('/admin'));
|
|
8492
8622
|
}
|
|
8493
|
-
`}function _(e){if(typeof e!="object"||e===null)return false;let t=e;return t.kind==="schema"&&typeof t.tables=="object"}function
|
|
8623
|
+
`}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 D(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 cr(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 ur(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 _t(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 Kt(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 Gt(e,t){return `${e}:${t}`}function dr(e,t,n,r){let a=Gt(e,t),o=Gt(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}${D(t)}Links`}function Jt(e,t,n){let r=J(e),a=J(t);return r===a?`${n}${D(r)}Id`:`${r}Id`}function mr(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 gr(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=dr(n,o,a.targetTable,i),l=Jt(s.leftTable,s.rightTable,"source"),u=Jt(s.rightTable,s.leftTable,"target"),c={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??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?mr(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 fr(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 hr(e){fr(e);let t=ur(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";_t(n,r,s,o.targetTable,i,{fkType:o.fkType,sqlName:o.sqlName,notNull:Kt(`${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";_t(a.targetTable,o,s,n,i,{fkType:a.fkType,sqlName:a.sqlName,notNull:Kt(`${n}.${a.targetTable}`,a,true),onDelete:a.onDelete,onUpdate:a.onUpdate},l);}return gr(t),t}function Yt(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 br(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 yr(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";
|
|
8494
8624
|
`}function xr(e){return Object.values(e.relations).filter(t=>t.relation==="one").map(t=>t.targetTable)}function vr(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 Tr(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)}: {
|
|
8495
8625
|
targetTable: ${h(i.targetTable)},
|
|
8496
8626
|
junctionTable: ${h(i.junctionTable)},
|
|
@@ -8530,7 +8660,7 @@ ${a.map(o=>` ${o}`).join(`
|
|
|
8530
8660
|
${t.map(n=>` ${n}`).join(`
|
|
8531
8661
|
`)}
|
|
8532
8662
|
} as const;
|
|
8533
|
-
`}function kr(e,t){let n=new Set(Object.keys(e.tables)),r=new Set;for(let i of Object.values(e.tables)){for(let s of xr(i))n.has(s)||r.add(s);for(let s of Object.values(i.columns))s.references&&!n.has(s.references.table)&&r.add(s.references.table);}let a=[],o=[];for(let[i,s]of Object.entries(e.tables)){let l=s.sqlName??
|
|
8663
|
+
`}function kr(e,t){let n=new Set(Object.keys(e.tables)),r=new Set;for(let i of Object.values(e.tables)){for(let s of xr(i))n.has(s)||r.add(s);for(let s of Object.values(i.columns))s.references&&!n.has(s.references.table)&&r.add(s.references.table);}let a=[],o=[];for(let[i,s]of Object.entries(e.tables)){let l=s.sqlName??M(i),u=[],c=[];for(let[b,m]of Object.entries(s.columns)){let x=br(b,m,t);m.uuidPrimaryKey&&(x+=".$defaultFn(() => crypto.randomUUID())"),m.primaryKey&&(x+=m.autoIncrement?".primaryKey({ autoIncrement: true })":".primaryKey()"),m.notNull&&(x+=".notNull()"),m.sqlDefault!==void 0&&(x+=`.default(${cr(m.sqlDefault)})`);let v=vr(b,m,s);if(v)if(m.references?.onDelete||m.references?.onUpdate){let R=[];m.references.onDelete&&R.push(`onDelete: ${h(m.references.onDelete)}`),m.references.onUpdate&&R.push(`onUpdate: ${h(m.references.onUpdate)}`),x+=`.references(() => ${v.tableName}.${v.fieldName}, { ${R.join(", ")} })`;}else x+=`.references(() => ${v.tableName}.${v.fieldName})`;if(m.unique){let R=typeof m.unique=="object"&&m.unique.name?m.unique.name:`${l}_${M(b)}_unique_idx`;c.push(` t.uniqueIndex(${h(R)}).on(table.${b})`);}if(m.index){let R=typeof m.index=="object"&&m.index.name?m.index.name:`${l}_${M(b)}_idx`;c.push(` t.index(${h(R)}).on(table.${b})`);}u.push(` ${b}: ${x},`);}c.length>0?a.push(`export const ${i} = table(
|
|
8534
8664
|
${h(l)},
|
|
8535
8665
|
{
|
|
8536
8666
|
${u.join(`
|
|
@@ -8589,11 +8719,11 @@ ${i.join(`
|
|
|
8589
8719
|
};`);}return `${t.join(`
|
|
8590
8720
|
|
|
8591
8721
|
`)}
|
|
8592
|
-
`}function $r(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 Xt(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")),l=await import(`${pathToFileURL(r).href}?t=${Date.now()}`),u=$r(l,t.exportName),c=hr(u);await Promise.all([mkdir(dirname(a),{recursive:true}),mkdir(dirname(o),{recursive:true}),mkdir(dirname(i),{recursive:true})]);let f=kr(c,n),d=Nr(c),y=Sr(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 Cr(e){return e.replaceAll("\\","/")}function A(e,t){let n=Cr(relative(e,t)).replace(/\.tsx?$/,"");return n.startsWith(".")?n:`./${n}`}var Dr=new Set([".ts",".tsx",".mts",".cts"]);async function rn(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 rn(a));continue}r.isFile()&&Dr.has(extname(r.name))&&n.push(a);}return n}function Z(e){return e.replace(/\.[cm]?tsx?$/,"")}function Er(e,t){let n=e,r=false,a,o="unknown";for(;g.isCallExpression(n);){let i=n.expression;if(!g.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.isStringLiteral(l)||g.isNumericLiteral(l)?a=l.text:l.kind===g.SyntaxKind.TrueKeyword?a="true":l.kind===g.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 Or(e){if(!e||!g.isObjectLiteralExpression(e))return [];let t=e.properties.find(r=>g.isPropertyAssignment(r)&&g.isIdentifier(r.name)&&r.name.text==="args");if(!t||!g.isObjectLiteralExpression(t.initializer))return [];let n=[];for(let r of t.initializer.properties)!g.isPropertyAssignment(r)||!g.isIdentifier(r.name)||n.push(Er(r.initializer,r.name.text));return n}function Fr(e){return g.isVariableStatement(e)?e.modifiers?.some(t=>t.kind===g.SyntaxKind.ExportKeyword)??false:false}function an(e){return g.isIdentifier(e)?e.text:g.isParenthesizedExpression(e)?an(e.expression):null}function jr(e){if(!e||!g.isObjectLiteralExpression(e))return [];let t=e.properties.find(r=>!g.isPropertyAssignment(r)||!g.isIdentifier(r.name)?false:r.name.text==="cronTrigger");if(!t||!g.isPropertyAssignment(t))return [];let n=t.initializer;return g.isStringLiteral(n)||g.isNoSubstitutionTemplateLiteral(n)?[n.text.trim()].filter(r=>r.length>0):g.isArrayLiteralExpression(n)?n.elements.map(r=>g.isStringLiteral(r)||g.isNoSubstitutionTemplateLiteral(r)?r.text.trim():"").filter(r=>r.length>0):[]}function Vr(e,t){let n=g.createSourceFile(t,e,g.ScriptTarget.Latest,true,g.ScriptKind.TS),r=[];for(let a of n.statements)if(Fr(a))for(let o of a.declarationList.declarations){if(!g.isIdentifier(o.name)||!o.initializer||!g.isCallExpression(o.initializer))continue;let i=an(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"?jr(o.initializer.arguments[0]):[],args:i==="query"||i==="mutation"?Or(o.initializer.arguments[0]):[]});}return r}function en(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 Br(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 tn(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 on(e){let t=[],n=await rn(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),l=Vr(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=Br(s,c.kindDirectory);for(let d of c.exports){let y=c.kind==="query"||c.kind==="mutation"?tn(f,d.exportName):void 0,w=c.kind==="scheduler"||c.kind==="cron"?tn(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"?en("queries",f,d.exportName):c.kind==="mutation"?en("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(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 Wr(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 Lr(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 zr(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 Ur(e){let t=Wr(e),n=[];for(let r of t){let a=Lr(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:zr(i),optional:f,primaryKey:s,autoIncrement:l});}return n}function Qr(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:Ur(u)}),a=t.exec(e);}return n}async function ln(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 ln(a));continue}r.isFile()&&r.name==="schema.ts"&&n.push(a);}return n}async function cn(e,t=[]){let n=await ln(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(),l=Qr(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 _r(e,t){let n=relative(e,t).replace(/\\/g,"/");return n.startsWith(".")?n:`./${n}`}async function un(e){let{outDirAbs:t,wranglerOutDirAbs:n,config:r,configPath:a,configDir:o}=e,i=A(t,a),s=resolve(t,"client"),l=A(s,a);await Promise.all([mkdir(t,{recursive:true}),mkdir(s,{recursive:true}),mkdir(n,{recursive:true})]);let u=resolve(t,"server.ts"),c=resolve(t,"client.ts"),f=resolve(t,"auth.config.ts"),d=resolve(t,"auth.schema.ts"),y=resolve(t,"drizzle.config.ts"),w=resolve(n,"wrangler.json"),b=await Xt(e),m=await cn(e,b?[b.schemaPath]:[]),x=A(t,m.schemaPath),v=await on(e),R=rt(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),xn=le(l,v),vn=H(x,v,r.r2[0]?.binding),Tn=te(i),Rn=b?[_r(o,b.schemaPath),...r.schema.filter(k=>!/(^|\/)schema\.ts$/.test(k))]:r.schema,kn=ce(Rn),Sn=ot(e,v),An=Qt(x,m,v),Nn=resolve(t,"admin.routes.ts"),$n=vn.map(k=>Bun.write(resolve(t,k.relativePath),k.source)),qn=xn.map(k=>Bun.write(resolve(t,k.relativePath),k.source));await Promise.all([Bun.write(u,R),Bun.write(c,`export * from "./client/index";
|
|
8722
|
+
`}function $r(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 Xt(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")),l=await import(`${pathToFileURL(r).href}?t=${Date.now()}`),u=$r(l,t.exportName),c=hr(u);await Promise.all([mkdir(dirname(a),{recursive:true}),mkdir(dirname(o),{recursive:true}),mkdir(dirname(i),{recursive:true})]);let f=kr(c,n),d=Nr(c),y=Sr(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 Ir(e){return e.replaceAll("\\","/")}function A(e,t){let n=Ir(relative(e,t)).replace(/\.tsx?$/,"");return n.startsWith(".")?n:`./${n}`}var Dr=new Set([".ts",".tsx",".mts",".cts"]);async function rn(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 rn(a));continue}r.isFile()&&Dr.has(extname(r.name))&&n.push(a);}return n}function Z(e){return e.replace(/\.[cm]?tsx?$/,"")}function Er(e,t){let n=e,r=false,a,o="unknown";for(;g.isCallExpression(n);){let i=n.expression;if(!g.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.isStringLiteral(l)||g.isNumericLiteral(l)?a=l.text:l.kind===g.SyntaxKind.TrueKeyword?a="true":l.kind===g.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 Fr(e){if(!e||!g.isObjectLiteralExpression(e))return [];let t=e.properties.find(r=>g.isPropertyAssignment(r)&&g.isIdentifier(r.name)&&r.name.text==="args");if(!t||!g.isObjectLiteralExpression(t.initializer))return [];let n=[];for(let r of t.initializer.properties)!g.isPropertyAssignment(r)||!g.isIdentifier(r.name)||n.push(Er(r.initializer,r.name.text));return n}function Or(e){return g.isVariableStatement(e)?e.modifiers?.some(t=>t.kind===g.SyntaxKind.ExportKeyword)??false:false}function an(e){return g.isIdentifier(e)?e.text:g.isParenthesizedExpression(e)?an(e.expression):null}function jr(e){if(!e||!g.isObjectLiteralExpression(e))return [];let t=e.properties.find(r=>!g.isPropertyAssignment(r)||!g.isIdentifier(r.name)?false:r.name.text==="cronTrigger");if(!t||!g.isPropertyAssignment(t))return [];let n=t.initializer;return g.isStringLiteral(n)||g.isNoSubstitutionTemplateLiteral(n)?[n.text.trim()].filter(r=>r.length>0):g.isArrayLiteralExpression(n)?n.elements.map(r=>g.isStringLiteral(r)||g.isNoSubstitutionTemplateLiteral(r)?r.text.trim():"").filter(r=>r.length>0):[]}function Vr(e,t){let n=g.createSourceFile(t,e,g.ScriptTarget.Latest,true,g.ScriptKind.TS),r=[];for(let a of n.statements)if(Or(a))for(let o of a.declarationList.declarations){if(!g.isIdentifier(o.name)||!o.initializer||!g.isCallExpression(o.initializer))continue;let i=an(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"?jr(o.initializer.arguments[0]):[],args:i==="query"||i==="mutation"?Fr(o.initializer.arguments[0]):[]});}return r}function en(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 Br(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 tn(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 on(e){let t=[],n=await rn(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),l=Vr(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=Br(s,c.kindDirectory);for(let d of c.exports){let y=c.kind==="query"||c.kind==="mutation"?tn(f,d.exportName):void 0,w=c.kind==="scheduler"||c.kind==="cron"?tn(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"?en("queries",f,d.exportName):c.kind==="mutation"?en("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(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 Wr(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 Lr(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 zr(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 Ur(e){let t=Wr(e),n=[];for(let r of t){let a=Lr(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:zr(i),optional:f,primaryKey:s,autoIncrement:l});}return n}function Qr(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:Ur(u)}),a=t.exec(e);}return n}async function ln(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 ln(a));continue}r.isFile()&&r.name==="schema.ts"&&n.push(a);}return n}async function cn(e,t=[]){let n=await ln(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(),l=Qr(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 _r(e,t){let n=relative(e,t).replace(/\\/g,"/");return n.startsWith(".")?n:`./${n}`}async function un(e){let{outDirAbs:t,wranglerOutDirAbs:n,config:r,configPath:a,configDir:o}=e,i=A(t,a),s=resolve(t,"client"),l=A(s,a);await Promise.all([mkdir(t,{recursive:true}),mkdir(s,{recursive:true}),mkdir(n,{recursive:true})]);let u=resolve(t,"server.ts"),c=resolve(t,"client.ts"),f=resolve(t,"auth.config.ts"),d=resolve(t,"auth.schema.ts"),y=resolve(t,"drizzle.config.ts"),w=resolve(n,"wrangler.json"),b=await Xt(e),m=await cn(e,b?[b.schemaPath]:[]),x=A(t,m.schemaPath),v=await on(e),R=rt(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),xn=le(l,v),vn=H(x,v,r.r2[0]?.binding),Tn=te(i),Rn=b?[_r(o,b.schemaPath),...r.schema.filter(k=>!/(^|\/)schema\.ts$/.test(k))]:r.schema,kn=ce(Rn),Sn=ot(e,v),An=Qt(x,m,v),Nn=resolve(t,"admin.routes.ts"),$n=vn.map(k=>Bun.write(resolve(t,k.relativePath),k.source)),qn=xn.map(k=>Bun.write(resolve(t,k.relativePath),k.source));await Promise.all([Bun.write(u,R),Bun.write(c,`export * from "./client/index";
|
|
8593
8723
|
`),...qn,...$n,Bun.write(f,Tn),Bun.write(d,""),Bun.write(y,kn),Bun.write(w,`${JSON.stringify(Sn,null,2)}
|
|
8594
|
-
`),Bun.write(Nn,An)]);let
|
|
8724
|
+
`),Bun.write(Nn,An)]);let O=relative(o,f).replace(/\\/g,"/"),In=O.startsWith(".")?O:`./${O}`,j=relative(o,d).replace(/\\/g,"/"),Cn=j.startsWith(".")?j:`./${j}`,ee=await Bun.spawn(["npx","@better-auth/cli","generate","--config",In,"--output",Cn,"--yes"],{cwd:o,stdout:"inherit",stderr:"inherit"}).exited;if(ee!==0)throw new Error(`better-auth generation failed with exit code ${ee}`)}var dn=z$1.object({binding:z$1.string().min(1),databaseName:z$1.string().min(1),databaseId:z$1.string().min(1),previewDatabaseId:z$1.string().min(1).optional(),migrationsDir:z$1.string().min(1).optional()}).strict(),pn=z$1.object({binding:z$1.string().min(1),id:z$1.string().min(1),previewId:z$1.string().min(1).optional()}).strict(),mn=z$1.object({binding:z$1.string().min(1),bucketName:z$1.string().min(1),previewBucketName:z$1.string().min(1).optional(),jurisdiction:z$1.string().min(1).optional()}).strict(),gn=z$1.object({enabled:z$1.boolean().optional(),binding:z$1.string().min(1).optional(),queue:z$1.string().min(1).optional()}).strict(),Zr=z$1.object({enabled:z$1.boolean().optional(),binding:z$1.string().min(1).optional(),className:z$1.string().min(1).optional(),objectName:z$1.string().min(1).optional(),subscribePath:z$1.string().min(1).optional(),websocketPath:z$1.string().min(1).optional(),protocol:z$1.string().min(1).optional()}).strict(),Yr=z$1.object({scanDir:z$1.string().min(1),outDir:z$1.string().min(1),wranglerOutDir:z$1.string().min(1).optional(),wranglerOutPath:z$1.string().min(1).optional(),schema:z$1.array(z$1.string()).min(1),schemaDsl:z$1.object({entry:z$1.string().min(1),exportName:z$1.string().min(1).optional(),outFile:z$1.string().min(1).optional(),typesOutFile:z$1.string().min(1).optional(),zodOutFile:z$1.string().min(1).optional(),namingStrategy:z$1.literal("camelToSnake").optional()}).strict().optional(),database:z$1.union([dn,z$1.array(dn).min(1)]),kv:z$1.union([pn,z$1.array(pn)]).optional(),r2:z$1.union([mn,z$1.array(mn)]).optional(),auth:z$1.object({enabled:z$1.boolean(),basePath:z$1.string().min(1),options:z$1.custom(e=>typeof e=="object"&&e!==null),clientOptions:z$1.custom(e=>typeof e=="object"&&e!==null)}).strict(),scheduler:gn.optional(),realtime:Zr.optional(),wranglerOverrides:z$1.record(z$1.string(),z$1.unknown()).optional()}).strict();function fn(e){return typeof e=="object"&&e!==null}function Xr(e){let t=fn(e.wranglerOverrides)?e.wranglerOverrides.scheduler:void 0,n=gn.safeParse(t);return n.success?n.data:{}}function ea(e){if(!fn(e)||!("scheduler"in e))return e;let{scheduler:t,...n}=e;return n}function ta(e){let n={...Xr(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:ea(e.wranglerOverrides),wranglerOutDir:e.wranglerOutDir??e.wranglerOutPath??e.outDir}}async function q(e){let t=isAbsolute(e??"")?e:resolve(process.cwd(),e??"appflare.config.ts"),n=dirname(t),o=(await import(pathToFileURL(t).href)).default,i=Yr.parse(o),s=ta(i);return {configPath:t,configDir:n,scanDirAbs:resolve(n,s.scanDir),outDirAbs:resolve(n,s.outDir),wranglerOutDirAbs:resolve(n,s.wranglerOutDir),config:s}}function oa(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 F(e){let t=await q(e);if(await un(t),t.wranglerOutDirAbs===t.outDirAbs){process.stdout.write(`\u2705 Generated artifacts in ${t.outDirAbs}
|
|
8595
8725
|
`);return}process.stdout.write(`\u2705 Generated server/client in ${t.outDirAbs} and wrangler.json in ${t.wranglerOutDirAbs}
|
|
8596
|
-
`);}async function bn(e,t=false){if(await
|
|
8726
|
+
`);}async function bn(e,t=false){if(await F(e),!t)return;let n=await q(e),r=false,a=false,o=async()=>{if(r){a=true;return}r=true;try{await F(e);}catch(s){process.stderr.write(`\u274C Build failed: ${s.message}
|
|
8597
8727
|
`);}finally{r=false,a&&(a=false,await o());}};na.watch(n.scanDirAbs,{ignoreInitial:true}).on("all",async(s,l)=>{process.stdout.write(`\u{1F504} Change detected: ${l}
|
|
8598
8728
|
`),await o();}),process.stdout.write(`\u{1F440} Watching ${n.scanDirAbs}
|
|
8599
|
-
`);}async function yn(e,t={}){let n=await q(e),r=oa(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.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 wn(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 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").action(async e=>{await
|
|
8729
|
+
`);}async function yn(e,t={}){let n=await q(e),r=oa(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.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 wn(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 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").action(async e=>{await F(e.config);});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).action(async e=>{await bn(e.config,e.watch);});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 yn(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 wn(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);});
|