appflare 0.2.35 → 0.2.37
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Documentation.md +8 -8
- package/cli/commands/index.ts +1 -1
- package/cli/generate.ts +24 -0
- package/cli/index.ts +1 -1
- package/cli/schema-compiler.ts +180 -2
- package/cli/templates/core/README.md +1 -1
- package/cli/templates/core/client/handlers/index.ts +7 -0
- package/cli/templates/handlers/generators/handlers.ts +2 -2
- package/cli/templates/handlers/generators/registration/modules/realtime/utils.ts +4 -10
- package/cli/templates/handlers/generators/types/context.ts +8 -2
- package/cli/templates/handlers/generators/types/query-definitions/filter-and-where-types.ts +6 -16
- package/cli/templates/handlers/generators/types/query-definitions/query-helper-functions.ts +216 -17
- package/cli/templates/handlers/index.ts +2 -1
- package/cli/templates/handlers/types.ts +2 -2
- package/dist/cli/index.js +502 -301
- package/dist/cli/index.mjs +502 -301
- package/dist/index.d.mts +81 -2
- package/dist/index.d.ts +81 -2
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
- package/schema.ts +229 -3
package/Documentation.md
CHANGED
|
@@ -398,14 +398,14 @@ bun run build
|
|
|
398
398
|
|
|
399
399
|
What gets generated (core set):
|
|
400
400
|
|
|
401
|
-
- `_generated/server.
|
|
402
|
-
- `_generated/client.
|
|
403
|
-
- `_generated/auth.config.
|
|
404
|
-
- `_generated/drizzle.config.
|
|
405
|
-
- `_generated/handlers.
|
|
406
|
-
- `_generated/handlers.context.
|
|
407
|
-
- `_generated/handlers.execution.
|
|
408
|
-
- `_generated/handlers.routes.
|
|
401
|
+
- `_generated/server.js`
|
|
402
|
+
- `_generated/client.js`
|
|
403
|
+
- `_generated/auth.config.js`
|
|
404
|
+
- `_generated/drizzle.config.js`
|
|
405
|
+
- `_generated/handlers.js`
|
|
406
|
+
- `_generated/handlers.context.js`
|
|
407
|
+
- `_generated/handlers.execution.js`
|
|
408
|
+
- `_generated/handlers.routes.js`
|
|
409
409
|
- `_generated/client/**`
|
|
410
410
|
|
|
411
411
|
### Watch mode
|
package/cli/commands/index.ts
CHANGED
|
@@ -121,7 +121,7 @@ export async function runMigrate(
|
|
|
121
121
|
|
|
122
122
|
const drizzleConfigPath = resolve(
|
|
123
123
|
loadedConfig.outDirAbs,
|
|
124
|
-
"drizzle.config.
|
|
124
|
+
"drizzle.config.js",
|
|
125
125
|
);
|
|
126
126
|
const npxCmd = process.platform === "win32" ? "npx.cmd" : "npx";
|
|
127
127
|
const drizzleGenerate = Bun.spawn(
|
package/cli/generate.ts
CHANGED
|
@@ -15,6 +15,27 @@ import { discoverHandlerOperations } from "./utils/handler-discovery";
|
|
|
15
15
|
import { discoverSchema } from "./utils/schema-discovery";
|
|
16
16
|
import { ensureRelativeImportPath } from "./utils/path-utils";
|
|
17
17
|
|
|
18
|
+
function extractRolesFromConfig(config: LoadedAppflareConfig["config"]): string[] {
|
|
19
|
+
const plugins = (config.auth.options as Record<string, unknown>).plugins;
|
|
20
|
+
if (!Array.isArray(plugins)) return [];
|
|
21
|
+
|
|
22
|
+
for (const plugin of plugins) {
|
|
23
|
+
if (plugin && typeof plugin === "object") {
|
|
24
|
+
const pluginObj = plugin as Record<string, unknown>;
|
|
25
|
+
if (pluginObj.id === "admin" && "options" in pluginObj) {
|
|
26
|
+
const options = (pluginObj as Record<string, unknown>).options as Record<string, unknown> | undefined;
|
|
27
|
+
if (options && typeof options === "object" && "roles" in options) {
|
|
28
|
+
const rolesObj = options.roles as Record<string, unknown>;
|
|
29
|
+
if (rolesObj && typeof rolesObj === "object") {
|
|
30
|
+
return Object.keys(rolesObj);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return [];
|
|
37
|
+
}
|
|
38
|
+
|
|
18
39
|
function toConfigRelativePath(configDir: string, absolutePath: string): string {
|
|
19
40
|
const relativePath = relative(configDir, absolutePath).replace(/\\/g, "/");
|
|
20
41
|
return relativePath.startsWith(".") ? relativePath : `./${relativePath}`;
|
|
@@ -74,6 +95,8 @@ export async function generateArtifacts(
|
|
|
74
95
|
`🔍 ${discoveredHandlers.length} handler(s) (${(performance.now() - t0).toFixed(0)}ms)\n`,
|
|
75
96
|
);
|
|
76
97
|
|
|
98
|
+
const roles = extractRolesFromConfig(config);
|
|
99
|
+
|
|
77
100
|
const serverSource = generateServerSource(
|
|
78
101
|
config.auth.basePath,
|
|
79
102
|
config.database[0].binding,
|
|
@@ -94,6 +117,7 @@ export async function generateArtifacts(
|
|
|
94
117
|
schemaImport,
|
|
95
118
|
discoveredHandlers,
|
|
96
119
|
config.r2[0]?.binding,
|
|
120
|
+
roles,
|
|
97
121
|
);
|
|
98
122
|
const authConfigSource = generateAuthConfigSource(configImport);
|
|
99
123
|
const drizzleSchemaPaths = compiledSchema
|
package/cli/index.ts
CHANGED
|
@@ -13,7 +13,7 @@ program
|
|
|
13
13
|
program
|
|
14
14
|
.command("build")
|
|
15
15
|
.description(
|
|
16
|
-
"Generate server.ts, client.ts, auth.config.
|
|
16
|
+
"Generate server.ts, client.ts, auth.config.js, drizzle.config.js, and wrangler.json artifacts",
|
|
17
17
|
)
|
|
18
18
|
.option(
|
|
19
19
|
"-c, --config <path>",
|
package/cli/schema-compiler.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { pathToFileURL } from "node:url";
|
|
|
4
4
|
import type {
|
|
5
5
|
ColumnDefinition,
|
|
6
6
|
ColumnType,
|
|
7
|
+
JsonShape,
|
|
7
8
|
ManyRelationDefinition,
|
|
8
9
|
ManyToManyRelationDefinition,
|
|
9
10
|
OneRelationDefinition,
|
|
@@ -96,6 +97,11 @@ function cloneSchemaDefinition(definition: SchemaDefinition): SchemaDefinition {
|
|
|
96
97
|
];
|
|
97
98
|
}),
|
|
98
99
|
),
|
|
100
|
+
enums: Object.fromEntries(
|
|
101
|
+
Object.entries(definition.enums ?? {}).map(([name, enumDef]) => {
|
|
102
|
+
return [name, { ...enumDef }];
|
|
103
|
+
}),
|
|
104
|
+
),
|
|
99
105
|
};
|
|
100
106
|
}
|
|
101
107
|
|
|
@@ -658,6 +664,23 @@ function drizzleBaseColumn(
|
|
|
658
664
|
return 't.int({ mode: "timestamp_ms" })';
|
|
659
665
|
}
|
|
660
666
|
|
|
667
|
+
if (column.type === "enum" && column.enumValues && column.enumValues.length > 0) {
|
|
668
|
+
if (column.isArray) {
|
|
669
|
+
return needsExplicitName
|
|
670
|
+
? `t.text(${quote(resolvedSqlName)}).array()`
|
|
671
|
+
: "t.text().array()";
|
|
672
|
+
}
|
|
673
|
+
return needsExplicitName ? `t.text(${quote(resolvedSqlName)})` : "t.text()";
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
if (column.type === "json" && column.jsonShape) {
|
|
677
|
+
const tsType = jsonShapeToTypeScript(column.jsonShape);
|
|
678
|
+
const base = needsExplicitName
|
|
679
|
+
? `t.text(${quote(resolvedSqlName)}, { mode: "json" })`
|
|
680
|
+
: `t.text({ mode: "json" })`;
|
|
681
|
+
return `${base}.$type<${tsType}>()`;
|
|
682
|
+
}
|
|
683
|
+
|
|
661
684
|
if (strategy === "camelToSnake") {
|
|
662
685
|
return needsExplicitName ? `t.text(${quote(resolvedSqlName)})` : "t.text()";
|
|
663
686
|
}
|
|
@@ -730,6 +753,53 @@ function resolveColumnReference(
|
|
|
730
753
|
};
|
|
731
754
|
}
|
|
732
755
|
|
|
756
|
+
function emitJsonColumnsMetadata(definition: SchemaDefinition): string {
|
|
757
|
+
const tableEntries: string[] = [];
|
|
758
|
+
|
|
759
|
+
for (const [tableName, table] of Object.entries(definition.tables)) {
|
|
760
|
+
const columnEntries: string[] = [];
|
|
761
|
+
|
|
762
|
+
for (const [fieldName, column] of Object.entries(table.columns)) {
|
|
763
|
+
if (column.type !== "json" || !column.jsonShape) continue;
|
|
764
|
+
|
|
765
|
+
const shapeStr = jsonShapeToRuntimeLiteral(column.jsonShape);
|
|
766
|
+
columnEntries.push(
|
|
767
|
+
`${quote(fieldName)}: { shape: ${shapeStr} },`,
|
|
768
|
+
);
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
if (columnEntries.length === 0) continue;
|
|
772
|
+
|
|
773
|
+
tableEntries.push(
|
|
774
|
+
`${quote(tableName)}: {
|
|
775
|
+
${columnEntries.map((entry) => `\t\t${entry}`).join("\n")}
|
|
776
|
+
},`,
|
|
777
|
+
);
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
if (tableEntries.length === 0) {
|
|
781
|
+
return "export const __appflareJsonColumns = {} as const;\n";
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
return `export const __appflareJsonColumns = {
|
|
785
|
+
${tableEntries.map((entry) => `\t${entry}`).join("\n")}
|
|
786
|
+
} as const;
|
|
787
|
+
`;
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
function jsonShapeToRuntimeLiteral(shape: JsonShape): string {
|
|
791
|
+
if (shape.kind === "array") {
|
|
792
|
+
return `{ kind: "array", element: ${jsonShapeToRuntimeLiteral(shape.element)} }`;
|
|
793
|
+
}
|
|
794
|
+
if (shape.kind === "object") {
|
|
795
|
+
const fields = Object.entries(shape.shape)
|
|
796
|
+
.map(([key, fieldShape]) => `${quote(key)}: ${jsonShapeToRuntimeLiteral(fieldShape)}`)
|
|
797
|
+
.join(", ");
|
|
798
|
+
return `{ kind: "object", shape: { ${fields} } }`;
|
|
799
|
+
}
|
|
800
|
+
return `{ kind: ${quote(shape.kind)} }`;
|
|
801
|
+
}
|
|
802
|
+
|
|
733
803
|
function emitManyToManyRuntimeMetadata(definition: SchemaDefinition): string {
|
|
734
804
|
const tableEntries: string[] = [];
|
|
735
805
|
|
|
@@ -861,6 +931,33 @@ function emitDrizzleSchema(
|
|
|
861
931
|
}
|
|
862
932
|
}
|
|
863
933
|
|
|
934
|
+
const enumColumns = new Map<string, ColumnDefinition>();
|
|
935
|
+
for (const table of Object.values(definition.tables)) {
|
|
936
|
+
for (const [fieldName, column] of Object.entries(table.columns)) {
|
|
937
|
+
if (
|
|
938
|
+
column.type === "enum" &&
|
|
939
|
+
column.enumValues &&
|
|
940
|
+
column.enumValues.length > 0
|
|
941
|
+
) {
|
|
942
|
+
const key = column.enumRef ?? `${fieldName}`;
|
|
943
|
+
if (!enumColumns.has(key)) {
|
|
944
|
+
enumColumns.set(key, column);
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
const enumTypeLines: string[] = [];
|
|
951
|
+
const enumCustomTypeLines: string[] = [];
|
|
952
|
+
for (const [key, column] of enumColumns.entries()) {
|
|
953
|
+
const typeName = toPascalCase(key);
|
|
954
|
+
const valuesStr = column.enumValues!.map((v) => `"${v}"`).join(" | ");
|
|
955
|
+
enumTypeLines.push(`export type ${typeName} = ${valuesStr};`);
|
|
956
|
+
enumCustomTypeLines.push(
|
|
957
|
+
`export const ${typeName}Column = t.customType<{ data: ${typeName}; dataNotNull: ${typeName} }>({ dataType: () => "text" });`,
|
|
958
|
+
);
|
|
959
|
+
}
|
|
960
|
+
|
|
864
961
|
const tableBlocks: string[] = [];
|
|
865
962
|
const relationBlocks: string[] = [];
|
|
866
963
|
|
|
@@ -870,7 +967,25 @@ function emitDrizzleSchema(
|
|
|
870
967
|
const indexes: string[] = [];
|
|
871
968
|
|
|
872
969
|
for (const [fieldName, column] of Object.entries(table.columns)) {
|
|
873
|
-
let expr
|
|
970
|
+
let expr: string;
|
|
971
|
+
if (
|
|
972
|
+
column.type === "enum" &&
|
|
973
|
+
column.enumValues &&
|
|
974
|
+
column.enumValues.length > 0
|
|
975
|
+
) {
|
|
976
|
+
const enumKey = column.enumRef ?? fieldName;
|
|
977
|
+
const typeName = toPascalCase(enumKey);
|
|
978
|
+
const resolvedSqlName = column.sqlName ?? toSnakeCase(fieldName);
|
|
979
|
+
const needsExplicitName = resolvedSqlName !== fieldName;
|
|
980
|
+
expr = needsExplicitName
|
|
981
|
+
? `${typeName}Column(${quote(resolvedSqlName)})`
|
|
982
|
+
: `${typeName}Column()`;
|
|
983
|
+
if (column.isArray) {
|
|
984
|
+
expr += ".array()";
|
|
985
|
+
}
|
|
986
|
+
} else {
|
|
987
|
+
expr = drizzleBaseColumn(fieldName, column, strategy);
|
|
988
|
+
}
|
|
874
989
|
|
|
875
990
|
if (column.uuidPrimaryKey) {
|
|
876
991
|
expr += ".$defaultFn(() => crypto.randomUUID())";
|
|
@@ -987,16 +1102,38 @@ function emitDrizzleSchema(
|
|
|
987
1102
|
import { sqliteTable as table } from "drizzle-orm/sqlite-core";
|
|
988
1103
|
import { relations } from "drizzle-orm";
|
|
989
1104
|
${buildExternalTableImportLines(externalTables)}
|
|
1105
|
+
${enumTypeLines.join("\n")}
|
|
1106
|
+
${enumCustomTypeLines.join("\n")}
|
|
1107
|
+
|
|
990
1108
|
${tableBlocks.join("\n\n")}
|
|
991
1109
|
|
|
992
1110
|
${relationBlocks.join("\n\n")}
|
|
993
1111
|
|
|
1112
|
+
${emitJsonColumnsMetadata(definition)}
|
|
1113
|
+
|
|
994
1114
|
${emitManyToManyRuntimeMetadata(definition)}
|
|
995
1115
|
|
|
996
1116
|
${emitRuntimeRelationMetadata(definition)}
|
|
997
1117
|
`;
|
|
998
1118
|
}
|
|
999
1119
|
|
|
1120
|
+
function jsonShapeToZod(shape: JsonShape): string {
|
|
1121
|
+
if (shape.kind === "array") {
|
|
1122
|
+
return `z.array(${jsonShapeToZod(shape.element)})`;
|
|
1123
|
+
}
|
|
1124
|
+
if (shape.kind === "object") {
|
|
1125
|
+
const fields = Object.entries(shape.shape)
|
|
1126
|
+
.map(([key, fieldShape]) => `${quote(key)}: ${jsonShapeToZod(fieldShape)}`)
|
|
1127
|
+
.join(", ");
|
|
1128
|
+
return `z.object({ ${fields} })`;
|
|
1129
|
+
}
|
|
1130
|
+
if (shape.kind === "string") return "z.string()";
|
|
1131
|
+
if (shape.kind === "number") return "z.number()";
|
|
1132
|
+
if (shape.kind === "boolean") return "z.boolean()";
|
|
1133
|
+
if (shape.kind === "date") return "z.date()";
|
|
1134
|
+
return "z.unknown()";
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1000
1137
|
function zodSchemaExpression(
|
|
1001
1138
|
column: ColumnDefinition,
|
|
1002
1139
|
optional: boolean,
|
|
@@ -1014,6 +1151,12 @@ function zodSchemaExpression(
|
|
|
1014
1151
|
expr = "z.boolean()";
|
|
1015
1152
|
} else if (column.type === "date") {
|
|
1016
1153
|
expr = "z.date()";
|
|
1154
|
+
} else if (column.type === "enum" && column.enumValues && column.enumValues.length > 0) {
|
|
1155
|
+
const valuesStr = column.enumValues.map((v) => `"${v}"`).join(", ");
|
|
1156
|
+
const enumZod = `z.enum([${valuesStr}])`;
|
|
1157
|
+
expr = column.isArray ? `z.array(${enumZod})` : enumZod;
|
|
1158
|
+
} else if (column.type === "json" && column.jsonShape) {
|
|
1159
|
+
expr = jsonShapeToZod(column.jsonShape);
|
|
1017
1160
|
}
|
|
1018
1161
|
|
|
1019
1162
|
if (optional) {
|
|
@@ -1057,6 +1200,23 @@ export type ${pascal}Select = z.infer<typeof ${tableName}SelectSchema>;
|
|
|
1057
1200
|
${blocks.join("\n")}`;
|
|
1058
1201
|
}
|
|
1059
1202
|
|
|
1203
|
+
function jsonShapeToTypeScript(shape: JsonShape): string {
|
|
1204
|
+
if (shape.kind === "array") {
|
|
1205
|
+
return `Array<${jsonShapeToTypeScript(shape.element)}>`;
|
|
1206
|
+
}
|
|
1207
|
+
if (shape.kind === "object") {
|
|
1208
|
+
const fields = Object.entries(shape.shape)
|
|
1209
|
+
.map(([key, fieldShape]) => `${key}: ${jsonShapeToTypeScript(fieldShape)}`)
|
|
1210
|
+
.join("; ");
|
|
1211
|
+
return `{ ${fields} }`;
|
|
1212
|
+
}
|
|
1213
|
+
if (shape.kind === "string") return "string";
|
|
1214
|
+
if (shape.kind === "number") return "number";
|
|
1215
|
+
if (shape.kind === "boolean") return "boolean";
|
|
1216
|
+
if (shape.kind === "date") return "Date";
|
|
1217
|
+
return "unknown";
|
|
1218
|
+
}
|
|
1219
|
+
|
|
1060
1220
|
function toTypeScriptType(column: ColumnDefinition): string {
|
|
1061
1221
|
if (column.type === "int") {
|
|
1062
1222
|
return "number";
|
|
@@ -1070,10 +1230,27 @@ function toTypeScriptType(column: ColumnDefinition): string {
|
|
|
1070
1230
|
if (column.type === "date") {
|
|
1071
1231
|
return "Date";
|
|
1072
1232
|
}
|
|
1233
|
+
if (column.type === "enum" && column.enumValues && column.enumValues.length > 0) {
|
|
1234
|
+
const union = column.enumValues.map((v) => `"${v}"`).join(" | ");
|
|
1235
|
+
if (column.isArray) {
|
|
1236
|
+
return `Array<${union}>`;
|
|
1237
|
+
}
|
|
1238
|
+
return union;
|
|
1239
|
+
}
|
|
1240
|
+
if (column.type === "json" && column.jsonShape) {
|
|
1241
|
+
return jsonShapeToTypeScript(column.jsonShape);
|
|
1242
|
+
}
|
|
1073
1243
|
return "unknown";
|
|
1074
1244
|
}
|
|
1075
1245
|
|
|
1076
1246
|
function emitTypes(definition: SchemaDefinition): string {
|
|
1247
|
+
const enumTypeLines: string[] = [];
|
|
1248
|
+
for (const [name, enumDef] of Object.entries(definition.enums ?? {})) {
|
|
1249
|
+
const typeName = toPascalCase(name);
|
|
1250
|
+
const valuesStr = enumDef.values.map((v) => `"${v}"`).join(" | ");
|
|
1251
|
+
enumTypeLines.push(`export type ${typeName} = ${valuesStr};`);
|
|
1252
|
+
}
|
|
1253
|
+
|
|
1077
1254
|
const lines: string[] = [];
|
|
1078
1255
|
|
|
1079
1256
|
for (const [tableName, table] of Object.entries(definition.tables)) {
|
|
@@ -1097,7 +1274,8 @@ function emitTypes(definition: SchemaDefinition): string {
|
|
|
1097
1274
|
export type New${pascal} = {\n${insertFields.join("\n")}\n};`);
|
|
1098
1275
|
}
|
|
1099
1276
|
|
|
1100
|
-
return `${
|
|
1277
|
+
return `${enumTypeLines.join("\n")}
|
|
1278
|
+
${lines.join("\n\n")}
|
|
1101
1279
|
`;
|
|
1102
1280
|
}
|
|
1103
1281
|
|
|
@@ -12,7 +12,7 @@ The core template modules are responsible for generating:
|
|
|
12
12
|
|
|
13
13
|
1. **Worker server source** (`src/index.ts` style output)
|
|
14
14
|
2. **Cloudflare Wrangler config** (`wrangler.json` shape)
|
|
15
|
-
3. **Drizzle config source** (`drizzle.config.
|
|
15
|
+
3. **Drizzle config source** (`drizzle.config.js`)
|
|
16
16
|
4. **Typed Appflare client source** (Better Auth client wrapper)
|
|
17
17
|
5. **Generated handlers integration** (registering auto-generated route handlers)
|
|
18
18
|
|
|
@@ -111,6 +111,13 @@ function normalizeOperation(
|
|
|
111
111
|
.filter(Boolean)
|
|
112
112
|
.slice(1);
|
|
113
113
|
|
|
114
|
+
if (
|
|
115
|
+
segments.length >= 2 &&
|
|
116
|
+
segments[segments.length - 1] === segments[segments.length - 2]
|
|
117
|
+
) {
|
|
118
|
+
segments.pop();
|
|
119
|
+
}
|
|
120
|
+
|
|
114
121
|
if (segments.length === 0) {
|
|
115
122
|
return null;
|
|
116
123
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { generateTypes } from "../types";
|
|
2
2
|
|
|
3
|
-
export function generateHandlersSource(schemaImportPath: string): string {
|
|
3
|
+
export function generateHandlersSource(schemaImportPath: string, roles: string[] = []): string {
|
|
4
4
|
return `import type { Context } from "hono";
|
|
5
5
|
import type { D1Database } from "@cloudflare/workers-types";
|
|
6
6
|
import { drizzle } from "drizzle-orm/d1";
|
|
@@ -8,6 +8,6 @@ import { z, type ZodRawShape } from "zod";
|
|
|
8
8
|
import * as authSchema from "./auth.schema";
|
|
9
9
|
import * as schema from "${schemaImportPath}";
|
|
10
10
|
|
|
11
|
-
${generateTypes()}
|
|
11
|
+
${generateTypes(roles)}
|
|
12
12
|
`;
|
|
13
13
|
}
|
|
@@ -188,26 +188,20 @@ function compareOrderValues(
|
|
|
188
188
|
function hasKnownOperator(condition: Record<string, unknown>): boolean {
|
|
189
189
|
return [
|
|
190
190
|
"eq",
|
|
191
|
-
"$eq",
|
|
192
191
|
"ne",
|
|
193
|
-
"$ne",
|
|
194
192
|
"in",
|
|
195
|
-
"$in",
|
|
196
193
|
"nin",
|
|
197
|
-
"$nin",
|
|
198
194
|
"gt",
|
|
199
|
-
"$gt",
|
|
200
195
|
"gte",
|
|
201
|
-
"$gte",
|
|
202
196
|
"lt",
|
|
203
|
-
"$lt",
|
|
204
197
|
"lte",
|
|
205
|
-
"$lte",
|
|
206
198
|
"exists",
|
|
207
199
|
"regex",
|
|
208
|
-
"
|
|
200
|
+
"options",
|
|
209
201
|
"geoWithin",
|
|
210
|
-
"
|
|
202
|
+
"includes",
|
|
203
|
+
"includesAny",
|
|
204
|
+
"length",
|
|
211
205
|
].some((key) => key in condition);
|
|
212
206
|
}
|
|
213
207
|
|
|
@@ -1,7 +1,13 @@
|
|
|
1
|
-
export function generateTypesContextSection(): string {
|
|
1
|
+
export function generateTypesContextSection(roles: string[] = []): string {
|
|
2
|
+
const userTypeExtension =
|
|
3
|
+
roles.length > 0
|
|
4
|
+
? `type UserRole = ${roles.map((r) => `"${r}"`).join(" | ")};
|
|
5
|
+
type User = Omit<AuthSession['user'], 'role'> & { role: UserRole };`
|
|
6
|
+
: `type User = AuthSession['user']`;
|
|
7
|
+
|
|
2
8
|
return `type AuthSession = typeof auth.$Infer.Session;
|
|
3
9
|
type AuthAdapter = Awaited<typeof auth.$context>["internalAdapter"];
|
|
4
|
-
|
|
10
|
+
${userTypeExtension}
|
|
5
11
|
type Session = AuthSession['session']
|
|
6
12
|
|
|
7
13
|
export type StoragePutArgs = {
|
|
@@ -19,16 +19,12 @@ type GeoWithinOperand = {
|
|
|
19
19
|
$geometry: GeoPoint | GeoCoordinates;
|
|
20
20
|
latitudeField?: string;
|
|
21
21
|
longitudeField?: string;
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
minDistance?: number;
|
|
23
|
+
maxDistance?: number;
|
|
24
24
|
gt?: number;
|
|
25
25
|
gte?: number;
|
|
26
26
|
lt?: number;
|
|
27
27
|
lte?: number;
|
|
28
|
-
$gt?: number;
|
|
29
|
-
$gte?: number;
|
|
30
|
-
$lt?: number;
|
|
31
|
-
$lte?: number;
|
|
32
28
|
};
|
|
33
29
|
|
|
34
30
|
type GeoWithinOperandForField<TFieldKey extends string> = Omit<
|
|
@@ -41,25 +37,20 @@ type GeoWithinOperandForField<TFieldKey extends string> = Omit<
|
|
|
41
37
|
|
|
42
38
|
type FieldOperators<T, TFieldKey extends string = string> = {
|
|
43
39
|
eq?: Friendly<NonNil<T>>;
|
|
44
|
-
$eq?: Friendly<NonNil<T>>;
|
|
45
40
|
ne?: Friendly<NonNil<T>>;
|
|
46
|
-
$ne?: Friendly<NonNil<T>>;
|
|
47
41
|
in?: ReadonlyArray<Friendly<NonNil<T>>>;
|
|
48
|
-
$in?: ReadonlyArray<Friendly<NonNil<T>>>;
|
|
49
42
|
nin?: ReadonlyArray<Friendly<NonNil<T>>>;
|
|
50
|
-
$nin?: ReadonlyArray<Friendly<NonNil<T>>>;
|
|
51
43
|
gt?: Comparable<T>;
|
|
52
|
-
$gt?: Comparable<T>;
|
|
53
44
|
gte?: Comparable<T>;
|
|
54
|
-
$gte?: Comparable<T>;
|
|
55
45
|
lt?: Comparable<T>;
|
|
56
|
-
$lt?: Comparable<T>;
|
|
57
46
|
lte?: Comparable<T>;
|
|
58
|
-
$lte?: Comparable<T>;
|
|
59
47
|
exists?: boolean;
|
|
60
48
|
regex?: RegexOperand<T>;
|
|
61
|
-
|
|
49
|
+
options?: string;
|
|
62
50
|
geoWithin?: GeoWithinOperandForField<TFieldKey>;
|
|
51
|
+
includes?: T extends ReadonlyArray<infer E> ? ReadonlyArray<E> : never;
|
|
52
|
+
includesAny?: T extends ReadonlyArray<infer E> ? ReadonlyArray<E> : never;
|
|
53
|
+
length?: T extends ReadonlyArray<unknown> ? number : never;
|
|
63
54
|
};
|
|
64
55
|
|
|
65
56
|
type WhereFieldValue<T, TFieldKey extends string> =
|
|
@@ -72,7 +63,6 @@ type RelationWhereInput<TModel extends Record<string, unknown>, TName extends Ta
|
|
|
72
63
|
| (TModel[K] extends Record<string, unknown> ? RelationWhereInput<TModel[K]> : never);
|
|
73
64
|
} & {
|
|
74
65
|
geoWithin?: GeoWithinOperandForField<Extract<keyof TModel, string>>;
|
|
75
|
-
$geoWithin?: GeoWithinOperandForField<Extract<keyof TModel, string>>;
|
|
76
66
|
} & (TName extends TableName ? {
|
|
77
67
|
[TRelation in keyof NativeFindManyWith<TName>]?: NativeFindManyWith<TName>[TRelation] extends infer TRelationConfig
|
|
78
68
|
? TRelationConfig extends Record<string, unknown>
|