schemock 0.0.4-alpha.21 → 0.0.4-alpha.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +70 -25
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +70 -25
- package/dist/cli/index.mjs.map +1 -1
- package/dist/cli.js +70 -25
- package/package.json +2 -1
package/dist/cli/index.js
CHANGED
|
@@ -1844,7 +1844,7 @@ function generateEntityTypes(code, schema, allSchemas) {
|
|
|
1844
1844
|
for (const rel of relations) {
|
|
1845
1845
|
if (rel.type === "hasMany") {
|
|
1846
1846
|
code.line(`${rel.name}?: ${rel.targetPascal}Create[];`);
|
|
1847
|
-
} else if (rel.type === "hasOne") {
|
|
1847
|
+
} else if (rel.type === "hasOne" || rel.type === "belongsTo") {
|
|
1848
1848
|
code.line(`${rel.name}?: ${rel.targetPascal}Create;`);
|
|
1849
1849
|
}
|
|
1850
1850
|
}
|
|
@@ -3576,14 +3576,38 @@ function generateSupabaseClient(schemas, config) {
|
|
|
3576
3576
|
code.comment("Default Supabase client (for direct access if needed)");
|
|
3577
3577
|
code.line("export const supabase = createSupabaseClient(supabaseUrl, supabaseKey);");
|
|
3578
3578
|
code.line();
|
|
3579
|
-
|
|
3579
|
+
const schemaMap = new Map(schemas.map((s) => [s.name, s]));
|
|
3580
|
+
code.block("const relationMeta: Record<string, Record<string, { type: string; target: string }>> = {", () => {
|
|
3581
|
+
for (const schema of schemas) {
|
|
3582
|
+
if (schema.isJunctionTable) continue;
|
|
3583
|
+
if (schema.relations.length === 0) continue;
|
|
3584
|
+
code.block(`${schema.name}: {`, () => {
|
|
3585
|
+
for (const rel of schema.relations) {
|
|
3586
|
+
const targetSchema = schemaMap.get(rel.resolvedTarget);
|
|
3587
|
+
const targetTable = config.tableMap?.[rel.resolvedTarget] ?? targetSchema?.tableName ?? rel.resolvedTarget + "s";
|
|
3588
|
+
code.line(`${rel.name}: { type: '${rel.type}', target: '${targetTable}' },`);
|
|
3589
|
+
}
|
|
3590
|
+
}, "},");
|
|
3591
|
+
}
|
|
3592
|
+
}, "};");
|
|
3593
|
+
code.line();
|
|
3594
|
+
code.block("function buildSelect(entityName: string, include?: string[]): string {", () => {
|
|
3580
3595
|
code.line("if (!include?.length) return '*';");
|
|
3581
|
-
code.line("
|
|
3596
|
+
code.line("const meta = relationMeta[entityName] || {};");
|
|
3597
|
+
code.line("const selectParts = include.map(rel => {");
|
|
3598
|
+
code.line(" const relInfo = meta[rel];");
|
|
3599
|
+
code.line(" if (relInfo?.type === 'belongsTo') {");
|
|
3600
|
+
code.line(" // belongsTo needs explicit target: 'author:users(*)'");
|
|
3601
|
+
code.line(" return `${rel}:${relInfo.target}(*)`;");
|
|
3602
|
+
code.line(" }");
|
|
3603
|
+
code.line(" // hasMany/hasOne can use simple syntax: 'posts(*)'");
|
|
3604
|
+
code.line(" return `${rel}(*)`;");
|
|
3605
|
+
code.line("});");
|
|
3606
|
+
code.line("return `*, ${selectParts.join(', ')}`;");
|
|
3582
3607
|
});
|
|
3583
3608
|
code.line();
|
|
3584
3609
|
generateApiType2(code, schemas);
|
|
3585
3610
|
code.line();
|
|
3586
|
-
const schemaMap = new Map(schemas.map((s) => [s.name, s]));
|
|
3587
3611
|
generateCreateClientFactory2(code, schemas, config, schemaMap);
|
|
3588
3612
|
code.line();
|
|
3589
3613
|
code.multiDocComment([
|
|
@@ -3872,7 +3896,7 @@ function generateSupabaseEntityApiFactory(code, schema, config, schemaMap) {
|
|
|
3872
3896
|
code.indent();
|
|
3873
3897
|
code.line(`executeListRequest<Types.${pascalName}>('${name}.list', async (client) => {`);
|
|
3874
3898
|
code.indent();
|
|
3875
|
-
code.line(
|
|
3899
|
+
code.line(`const select = buildSelect('${name}', options?.include);`);
|
|
3876
3900
|
code.line(`let query = client.from('${tableName}').select(select, { count: 'exact' });`);
|
|
3877
3901
|
code.line();
|
|
3878
3902
|
code.block("if (options?.where) {", () => {
|
|
@@ -3926,7 +3950,7 @@ function generateSupabaseEntityApiFactory(code, schema, config, schemaMap) {
|
|
|
3926
3950
|
code.indent();
|
|
3927
3951
|
code.line(`executeRequest<Types.${pascalName}>('${name}.get', async (client) => {`);
|
|
3928
3952
|
code.indent();
|
|
3929
|
-
code.line(
|
|
3953
|
+
code.line(`const select = buildSelect('${name}', options?.include);`);
|
|
3930
3954
|
code.line(`return await client.from('${tableName}').select(select).eq('id', id).single();`);
|
|
3931
3955
|
code.dedent();
|
|
3932
3956
|
code.line(`}).then(data => ({ data: data as Types.${pascalName} })),`);
|
|
@@ -3956,32 +3980,53 @@ function generateSupabaseEntityApiFactory(code, schema, config, schemaMap) {
|
|
|
3956
3980
|
}
|
|
3957
3981
|
function generateSupabaseCreateMethodFactory(code, schema, config, schemaMap) {
|
|
3958
3982
|
const { name, pascalName, tableName, relations } = schema;
|
|
3959
|
-
const
|
|
3983
|
+
const childRels = relations.filter((r) => r.type === "hasMany" || r.type === "hasOne");
|
|
3984
|
+
const parentRels = relations.filter((r) => r.type === "belongsTo");
|
|
3985
|
+
const hasNestedRels = childRels.length > 0 || parentRels.length > 0;
|
|
3960
3986
|
code.line(`create: (input: Types.${pascalName}Create) =>`);
|
|
3961
3987
|
code.indent();
|
|
3962
3988
|
code.line(`executeRequest<Types.${pascalName}>('${name}.create', async (client) => {`);
|
|
3963
3989
|
code.indent();
|
|
3964
|
-
if (
|
|
3965
|
-
const
|
|
3966
|
-
code.line(`const { ${
|
|
3967
|
-
code.line();
|
|
3968
|
-
code.line(
|
|
3990
|
+
if (hasNestedRels) {
|
|
3991
|
+
const allRelNames = [...childRels, ...parentRels].map((r) => r.name).join(", ");
|
|
3992
|
+
code.line(`const { ${allRelNames}, ...data } = input;`);
|
|
3993
|
+
code.line("// eslint-disable-next-line @typescript-eslint/no-explicit-any");
|
|
3994
|
+
code.line("const insertData: Record<string, any> = { ...data };");
|
|
3995
|
+
code.line();
|
|
3996
|
+
if (parentRels.length > 0) {
|
|
3997
|
+
code.comment("Handle belongsTo relations - create parent first");
|
|
3998
|
+
for (const rel of parentRels) {
|
|
3999
|
+
const targetSchema = schemaMap.get(rel.resolvedTarget);
|
|
4000
|
+
const targetTable = config.tableMap?.[rel.resolvedTarget] ?? targetSchema?.tableName ?? rel.resolvedTarget + "s";
|
|
4001
|
+
const fkField = rel.localField || rel.foreignKey;
|
|
4002
|
+
code.block(`if (${rel.name}) {`, () => {
|
|
4003
|
+
code.line(`const parentResult = await client.from('${targetTable}').insert(${rel.name}).select().single();`);
|
|
4004
|
+
code.line("if (parentResult.error) return parentResult as { data: null; error: unknown };");
|
|
4005
|
+
code.line(`insertData.${fkField} = parentResult.data.id;`);
|
|
4006
|
+
});
|
|
4007
|
+
}
|
|
4008
|
+
code.line();
|
|
4009
|
+
}
|
|
4010
|
+
code.line(`const result = await client.from('${tableName}').insert(insertData).select().single();`);
|
|
3969
4011
|
code.line("if (result.error) return result;");
|
|
3970
4012
|
code.line("const item = result.data;");
|
|
3971
4013
|
code.line();
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
const
|
|
3975
|
-
|
|
3976
|
-
|
|
3977
|
-
|
|
3978
|
-
|
|
3979
|
-
|
|
3980
|
-
|
|
3981
|
-
|
|
3982
|
-
|
|
3983
|
-
|
|
3984
|
-
|
|
4014
|
+
if (childRels.length > 0) {
|
|
4015
|
+
code.comment("Handle hasMany/hasOne relations - create children after parent");
|
|
4016
|
+
for (const rel of childRels) {
|
|
4017
|
+
const targetSchema = schemaMap.get(rel.resolvedTarget);
|
|
4018
|
+
const targetTable = config.tableMap?.[rel.resolvedTarget] ?? targetSchema?.tableName ?? rel.resolvedTarget + "s";
|
|
4019
|
+
code.block(`if (${rel.name}) {`, () => {
|
|
4020
|
+
if (rel.type === "hasMany") {
|
|
4021
|
+
code.line(`const nestedData = ${rel.name}.map(nested => ({ ...nested, ${rel.foreignKey}: item.id }));`);
|
|
4022
|
+
code.line(`const nestedResult = await client.from('${targetTable}').insert(nestedData);`);
|
|
4023
|
+
code.line("if (nestedResult.error) return nestedResult as { data: null; error: unknown };");
|
|
4024
|
+
} else {
|
|
4025
|
+
code.line(`const nestedResult = await client.from('${targetTable}').insert({ ...${rel.name}, ${rel.foreignKey}: item.id });`);
|
|
4026
|
+
code.line("if (nestedResult.error) return nestedResult as { data: null; error: unknown };");
|
|
4027
|
+
}
|
|
4028
|
+
});
|
|
4029
|
+
}
|
|
3985
4030
|
}
|
|
3986
4031
|
code.line();
|
|
3987
4032
|
code.line("return { data: item, error: null };");
|