postgresdk 0.18.13 → 0.18.15
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.js +67 -13
- package/dist/emit-client.d.ts +4 -1
- package/dist/emit-include-methods.d.ts +2 -0
- package/dist/index.js +67 -13
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -605,12 +605,16 @@ function generateIncludeMethods(table, graph, opts, allTables) {
|
|
|
605
605
|
const newIsMany = [...isMany, edge.kind === "many"];
|
|
606
606
|
const newTargets = [...targets, edge.target];
|
|
607
607
|
const methodSuffix = pathToMethodSuffix(newPath);
|
|
608
|
+
const baseType = buildReturnType(baseTableName, newPath, newIsMany, newTargets, graph);
|
|
609
|
+
const typeName = `Select${pascal(baseTableName)}${methodSuffix}`;
|
|
608
610
|
methods.push({
|
|
609
611
|
name: `list${methodSuffix}`,
|
|
610
612
|
path: newPath,
|
|
611
613
|
isMany: newIsMany,
|
|
612
614
|
targets: newTargets,
|
|
613
|
-
returnType: `PaginatedResponse<${
|
|
615
|
+
returnType: `PaginatedResponse<${baseType}>`,
|
|
616
|
+
typeName,
|
|
617
|
+
baseType,
|
|
614
618
|
includeSpec: buildIncludeSpec(newPath)
|
|
615
619
|
});
|
|
616
620
|
methods.push({
|
|
@@ -618,7 +622,9 @@ function generateIncludeMethods(table, graph, opts, allTables) {
|
|
|
618
622
|
path: newPath,
|
|
619
623
|
isMany: newIsMany,
|
|
620
624
|
targets: newTargets,
|
|
621
|
-
returnType: `${
|
|
625
|
+
returnType: `${baseType} | null`,
|
|
626
|
+
typeName,
|
|
627
|
+
baseType,
|
|
622
628
|
includeSpec: buildIncludeSpec(newPath)
|
|
623
629
|
});
|
|
624
630
|
explore(edge.target, newPath, newIsMany, newTargets, new Set([...visited, edge.target]), depth + 1);
|
|
@@ -645,12 +651,16 @@ function generateIncludeMethods(table, graph, opts, allTables) {
|
|
|
645
651
|
const combinedSuffix = `With${pascal(key1)}And${pascal(key2)}`;
|
|
646
652
|
const type1 = `${key1}: ${edge1.kind === "many" ? `Select${pascal(edge1.target)}[]` : `Select${pascal(edge1.target)}`}`;
|
|
647
653
|
const type2 = `${key2}: ${edge2.kind === "many" ? `Select${pascal(edge2.target)}[]` : `Select${pascal(edge2.target)}`}`;
|
|
654
|
+
const combinedBaseType = `Select${pascal(baseTableName)} & { ${type1}; ${type2} }`;
|
|
655
|
+
const combinedTypeName = `Select${pascal(baseTableName)}${combinedSuffix}`;
|
|
648
656
|
methods.push({
|
|
649
657
|
name: `list${combinedSuffix}`,
|
|
650
658
|
path: combinedPath,
|
|
651
659
|
isMany: [edge1.kind === "many", edge2.kind === "many"],
|
|
652
660
|
targets: [edge1.target, edge2.target],
|
|
653
|
-
returnType: `PaginatedResponse
|
|
661
|
+
returnType: `PaginatedResponse<${combinedBaseType}>`,
|
|
662
|
+
typeName: combinedTypeName,
|
|
663
|
+
baseType: combinedBaseType,
|
|
654
664
|
includeSpec: { [key1]: true, [key2]: true }
|
|
655
665
|
});
|
|
656
666
|
methods.push({
|
|
@@ -658,7 +668,9 @@ function generateIncludeMethods(table, graph, opts, allTables) {
|
|
|
658
668
|
path: combinedPath,
|
|
659
669
|
isMany: [edge1.kind === "many", edge2.kind === "many"],
|
|
660
670
|
targets: [edge1.target, edge2.target],
|
|
661
|
-
returnType:
|
|
671
|
+
returnType: `${combinedBaseType} | null`,
|
|
672
|
+
typeName: combinedTypeName,
|
|
673
|
+
baseType: combinedBaseType,
|
|
662
674
|
includeSpec: { [key1]: true, [key2]: true }
|
|
663
675
|
});
|
|
664
676
|
}
|
|
@@ -2903,7 +2915,7 @@ function emitIncludeSpec(graph) {
|
|
|
2903
2915
|
out += ` ${relKey}?: boolean | { select?: string[]; exclude?: string[]; include?: ${toPascal(edge.target)}IncludeSpec; limit?: number; offset?: number; orderBy?: string; order?: "asc" | "desc"; };
|
|
2904
2916
|
`;
|
|
2905
2917
|
} else {
|
|
2906
|
-
out += ` ${relKey}?: boolean | { select?: string[]; exclude?: string[];
|
|
2918
|
+
out += ` ${relKey}?: boolean | { select?: string[]; exclude?: string[]; include?: ${toPascal(edge.target)}IncludeSpec; };
|
|
2907
2919
|
`;
|
|
2908
2920
|
}
|
|
2909
2921
|
}
|
|
@@ -3560,6 +3572,15 @@ function emitClient(table, graph, opts, model) {
|
|
|
3560
3572
|
otherTableImports.push(`import type { Select${pascal(target)} } from "./types/${target}${ext}";`);
|
|
3561
3573
|
}
|
|
3562
3574
|
}
|
|
3575
|
+
const seenTypeNames = new Set;
|
|
3576
|
+
let typeAliasesCode = "";
|
|
3577
|
+
for (const method of includeMethods) {
|
|
3578
|
+
if (!seenTypeNames.has(method.typeName)) {
|
|
3579
|
+
seenTypeNames.add(method.typeName);
|
|
3580
|
+
typeAliasesCode += `export type ${method.typeName} = ${method.baseType};
|
|
3581
|
+
`;
|
|
3582
|
+
}
|
|
3583
|
+
}
|
|
3563
3584
|
let includeMethodsCode = "";
|
|
3564
3585
|
for (const method of includeMethods) {
|
|
3565
3586
|
const isGetByPk = method.name.startsWith("getByPk");
|
|
@@ -3644,7 +3665,7 @@ function emitClient(table, graph, opts, model) {
|
|
|
3644
3665
|
}
|
|
3645
3666
|
if (isGetByPk) {
|
|
3646
3667
|
const pkWhere = hasCompositePk ? `{ ${safePk.map((col) => `${col}: pk.${col}`).join(", ")} }` : `{ ${safePk[0] || "id"}: pk }`;
|
|
3647
|
-
const baseReturnType = method.
|
|
3668
|
+
const baseReturnType = method.typeName;
|
|
3648
3669
|
let transformCode = "";
|
|
3649
3670
|
if (includeParamNames.length > 0) {
|
|
3650
3671
|
const destructure = includeParamNames.map((name) => name).join(", ");
|
|
@@ -3665,9 +3686,13 @@ function emitClient(table, graph, opts, model) {
|
|
|
3665
3686
|
} else if (pattern.type === "nested" && pattern.nestedKey) {
|
|
3666
3687
|
const key = pattern.nestedKey;
|
|
3667
3688
|
const paramName = includeParamNames[0];
|
|
3689
|
+
const nestedValue = pattern.nestedValue;
|
|
3690
|
+
const requiredIncludes = Object.entries(nestedValue).map(([k, v]) => `${k}: ${JSON.stringify(v)}`).join(", ");
|
|
3668
3691
|
transformCode = `
|
|
3669
3692
|
const { ${destructure} } = params ?? {};
|
|
3670
|
-
const includeSpec =
|
|
3693
|
+
const includeSpec = { ${key}: ${paramName}
|
|
3694
|
+
? { ...${paramName}, include: { ${requiredIncludes}, ...${paramName}.include } }
|
|
3695
|
+
: ${JSON.stringify(nestedValue)} };`;
|
|
3671
3696
|
}
|
|
3672
3697
|
} else {
|
|
3673
3698
|
transformCode = `
|
|
@@ -3680,7 +3705,7 @@ function emitClient(table, graph, opts, model) {
|
|
|
3680
3705
|
* @param params - Optional include options (including select/exclude for base and nested tables)
|
|
3681
3706
|
* @returns The record with nested ${method.path.join(" and ")} if found, null otherwise
|
|
3682
3707
|
*/
|
|
3683
|
-
async ${method.name}(pk: ${pkType}, params?: ${paramsType}): Promise<${method.
|
|
3708
|
+
async ${method.name}(pk: ${pkType}, params?: ${paramsType}): Promise<${method.typeName} | null> {${transformCode}
|
|
3684
3709
|
const results = await this.post<PaginatedResponse<${baseReturnType}>>(\`\${this.resource}/list\`, {
|
|
3685
3710
|
where: ${pkWhere},
|
|
3686
3711
|
select: params?.select,
|
|
@@ -3714,9 +3739,13 @@ function emitClient(table, graph, opts, model) {
|
|
|
3714
3739
|
} else if (pattern.type === "nested" && pattern.nestedKey) {
|
|
3715
3740
|
const key = pattern.nestedKey;
|
|
3716
3741
|
const paramName = includeParamNames[0];
|
|
3742
|
+
const nestedValue = pattern.nestedValue;
|
|
3743
|
+
const requiredIncludes = Object.entries(nestedValue).map(([k, v]) => `${k}: ${JSON.stringify(v)}`).join(", ");
|
|
3717
3744
|
transformCode = `
|
|
3718
3745
|
const { ${destructure}, ...baseParams } = params ?? {};
|
|
3719
|
-
const includeSpec =
|
|
3746
|
+
const includeSpec = { ${key}: ${paramName}
|
|
3747
|
+
? { ...${paramName}, include: { ${requiredIncludes}, ...${paramName}.include } }
|
|
3748
|
+
: ${JSON.stringify(nestedValue)} };
|
|
3720
3749
|
return this.post<${method.returnType}>(\`\${this.resource}/list\`, { ...baseParams, include: includeSpec });`;
|
|
3721
3750
|
}
|
|
3722
3751
|
} else {
|
|
@@ -3729,7 +3758,7 @@ function emitClient(table, graph, opts, model) {
|
|
|
3729
3758
|
* @param params - Query parameters (where, orderBy, order, limit, offset) and include options
|
|
3730
3759
|
* @returns Paginated results with nested ${method.path.join(" and ")} included
|
|
3731
3760
|
*/
|
|
3732
|
-
async ${method.name}(params?: ${paramsType}): Promise<${method.
|
|
3761
|
+
async ${method.name}(params?: ${paramsType}): Promise<PaginatedResponse<${method.typeName}>> {${transformCode}
|
|
3733
3762
|
}
|
|
3734
3763
|
`;
|
|
3735
3764
|
}
|
|
@@ -3751,6 +3780,7 @@ ${includeResolverImport}
|
|
|
3751
3780
|
${otherTableImports.join(`
|
|
3752
3781
|
`)}
|
|
3753
3782
|
|
|
3783
|
+
${typeAliasesCode}
|
|
3754
3784
|
/**
|
|
3755
3785
|
* Client for ${table.name} table operations
|
|
3756
3786
|
*/
|
|
@@ -4206,7 +4236,7 @@ ${hasJsonbColumns ? ` /**
|
|
|
4206
4236
|
${includeMethodsCode}}
|
|
4207
4237
|
`;
|
|
4208
4238
|
}
|
|
4209
|
-
function emitClientIndex(tables, useJsExtensions) {
|
|
4239
|
+
function emitClientIndex(tables, useJsExtensions, graph, includeOpts) {
|
|
4210
4240
|
const ext = useJsExtensions ? ".js" : "";
|
|
4211
4241
|
let out = `/**
|
|
4212
4242
|
* AUTO-GENERATED FILE - DO NOT EDIT
|
|
@@ -4296,6 +4326,24 @@ export type { AuthConfig, HeaderMap, AuthHeadersProvider } from "./base-client${
|
|
|
4296
4326
|
`;
|
|
4297
4327
|
out += `export type { PaginatedResponse } from "./types/shared${ext}";
|
|
4298
4328
|
`;
|
|
4329
|
+
if (graph && includeOpts) {
|
|
4330
|
+
const opts = { maxDepth: includeOpts.maxDepth, skipJunctionTables: includeOpts.skipJunctionTables };
|
|
4331
|
+
for (const t of tables) {
|
|
4332
|
+
const methods = generateIncludeMethods(t, graph, opts, tables);
|
|
4333
|
+
const seenTypeNames = new Set;
|
|
4334
|
+
const typeNames = [];
|
|
4335
|
+
for (const method of methods) {
|
|
4336
|
+
if (!seenTypeNames.has(method.typeName)) {
|
|
4337
|
+
seenTypeNames.add(method.typeName);
|
|
4338
|
+
typeNames.push(method.typeName);
|
|
4339
|
+
}
|
|
4340
|
+
}
|
|
4341
|
+
if (typeNames.length > 0) {
|
|
4342
|
+
out += `export type { ${typeNames.join(", ")} } from "./${t.name}${ext}";
|
|
4343
|
+
`;
|
|
4344
|
+
}
|
|
4345
|
+
}
|
|
4346
|
+
}
|
|
4299
4347
|
return out;
|
|
4300
4348
|
}
|
|
4301
4349
|
|
|
@@ -4722,9 +4770,15 @@ export async function loadIncludes(
|
|
|
4722
4770
|
// Could be belongs-to (current has FK to target) OR has-one (target unique-FK to current)
|
|
4723
4771
|
const specValue = s[key];
|
|
4724
4772
|
const options: RelationOptions = {};
|
|
4773
|
+
let childSpec: any = undefined;
|
|
4774
|
+
|
|
4725
4775
|
if (specValue && typeof specValue === "object" && specValue !== true) {
|
|
4726
4776
|
if (specValue.select !== undefined) options.select = specValue.select;
|
|
4727
4777
|
if (specValue.exclude !== undefined) options.exclude = specValue.exclude;
|
|
4778
|
+
// Support { include: TargetIncludeSpec } — mirrors the many/via handler
|
|
4779
|
+
if (specValue.include !== undefined) {
|
|
4780
|
+
childSpec = specValue.include;
|
|
4781
|
+
}
|
|
4728
4782
|
}
|
|
4729
4783
|
|
|
4730
4784
|
const currFks = (FK_INDEX as any)[table] as Array<{from:string[];toTable:string;to:string[]}>;
|
|
@@ -4744,7 +4798,7 @@ export async function loadIncludes(
|
|
|
4744
4798
|
for (const r of rows) r[key] = null;
|
|
4745
4799
|
}
|
|
4746
4800
|
}
|
|
4747
|
-
|
|
4801
|
+
|
|
4748
4802
|
if (childSpec) {
|
|
4749
4803
|
const children = rows.map(r => r[key]).filter(Boolean);
|
|
4750
4804
|
try {
|
|
@@ -7277,7 +7331,7 @@ async function generate(configPath) {
|
|
|
7277
7331
|
}
|
|
7278
7332
|
files.push({
|
|
7279
7333
|
path: join(clientDir, "index.ts"),
|
|
7280
|
-
content: emitClientIndex(Object.values(model.tables), cfg.useJsExtensionsClient)
|
|
7334
|
+
content: emitClientIndex(Object.values(model.tables), cfg.useJsExtensionsClient, graph, { maxDepth: cfg.includeMethodsDepth ?? 2, skipJunctionTables: cfg.skipJunctionTables ?? true })
|
|
7281
7335
|
});
|
|
7282
7336
|
if (serverFramework === "hono") {
|
|
7283
7337
|
files.push({
|
package/dist/emit-client.d.ts
CHANGED
|
@@ -5,4 +5,7 @@ export declare function emitClient(table: Table, graph: Graph, opts: {
|
|
|
5
5
|
includeMethodsDepth?: number;
|
|
6
6
|
skipJunctionTables?: boolean;
|
|
7
7
|
}, model?: Model): string;
|
|
8
|
-
export declare function emitClientIndex(tables: Table[], useJsExtensions?: boolean
|
|
8
|
+
export declare function emitClientIndex(tables: Table[], useJsExtensions?: boolean, graph?: Graph, includeOpts?: {
|
|
9
|
+
maxDepth: number;
|
|
10
|
+
skipJunctionTables: boolean;
|
|
11
|
+
}): string;
|
package/dist/index.js
CHANGED
|
@@ -604,12 +604,16 @@ function generateIncludeMethods(table, graph, opts, allTables) {
|
|
|
604
604
|
const newIsMany = [...isMany, edge.kind === "many"];
|
|
605
605
|
const newTargets = [...targets, edge.target];
|
|
606
606
|
const methodSuffix = pathToMethodSuffix(newPath);
|
|
607
|
+
const baseType = buildReturnType(baseTableName, newPath, newIsMany, newTargets, graph);
|
|
608
|
+
const typeName = `Select${pascal(baseTableName)}${methodSuffix}`;
|
|
607
609
|
methods.push({
|
|
608
610
|
name: `list${methodSuffix}`,
|
|
609
611
|
path: newPath,
|
|
610
612
|
isMany: newIsMany,
|
|
611
613
|
targets: newTargets,
|
|
612
|
-
returnType: `PaginatedResponse<${
|
|
614
|
+
returnType: `PaginatedResponse<${baseType}>`,
|
|
615
|
+
typeName,
|
|
616
|
+
baseType,
|
|
613
617
|
includeSpec: buildIncludeSpec(newPath)
|
|
614
618
|
});
|
|
615
619
|
methods.push({
|
|
@@ -617,7 +621,9 @@ function generateIncludeMethods(table, graph, opts, allTables) {
|
|
|
617
621
|
path: newPath,
|
|
618
622
|
isMany: newIsMany,
|
|
619
623
|
targets: newTargets,
|
|
620
|
-
returnType: `${
|
|
624
|
+
returnType: `${baseType} | null`,
|
|
625
|
+
typeName,
|
|
626
|
+
baseType,
|
|
621
627
|
includeSpec: buildIncludeSpec(newPath)
|
|
622
628
|
});
|
|
623
629
|
explore(edge.target, newPath, newIsMany, newTargets, new Set([...visited, edge.target]), depth + 1);
|
|
@@ -644,12 +650,16 @@ function generateIncludeMethods(table, graph, opts, allTables) {
|
|
|
644
650
|
const combinedSuffix = `With${pascal(key1)}And${pascal(key2)}`;
|
|
645
651
|
const type1 = `${key1}: ${edge1.kind === "many" ? `Select${pascal(edge1.target)}[]` : `Select${pascal(edge1.target)}`}`;
|
|
646
652
|
const type2 = `${key2}: ${edge2.kind === "many" ? `Select${pascal(edge2.target)}[]` : `Select${pascal(edge2.target)}`}`;
|
|
653
|
+
const combinedBaseType = `Select${pascal(baseTableName)} & { ${type1}; ${type2} }`;
|
|
654
|
+
const combinedTypeName = `Select${pascal(baseTableName)}${combinedSuffix}`;
|
|
647
655
|
methods.push({
|
|
648
656
|
name: `list${combinedSuffix}`,
|
|
649
657
|
path: combinedPath,
|
|
650
658
|
isMany: [edge1.kind === "many", edge2.kind === "many"],
|
|
651
659
|
targets: [edge1.target, edge2.target],
|
|
652
|
-
returnType: `PaginatedResponse
|
|
660
|
+
returnType: `PaginatedResponse<${combinedBaseType}>`,
|
|
661
|
+
typeName: combinedTypeName,
|
|
662
|
+
baseType: combinedBaseType,
|
|
653
663
|
includeSpec: { [key1]: true, [key2]: true }
|
|
654
664
|
});
|
|
655
665
|
methods.push({
|
|
@@ -657,7 +667,9 @@ function generateIncludeMethods(table, graph, opts, allTables) {
|
|
|
657
667
|
path: combinedPath,
|
|
658
668
|
isMany: [edge1.kind === "many", edge2.kind === "many"],
|
|
659
669
|
targets: [edge1.target, edge2.target],
|
|
660
|
-
returnType:
|
|
670
|
+
returnType: `${combinedBaseType} | null`,
|
|
671
|
+
typeName: combinedTypeName,
|
|
672
|
+
baseType: combinedBaseType,
|
|
661
673
|
includeSpec: { [key1]: true, [key2]: true }
|
|
662
674
|
});
|
|
663
675
|
}
|
|
@@ -1942,7 +1954,7 @@ function emitIncludeSpec(graph) {
|
|
|
1942
1954
|
out += ` ${relKey}?: boolean | { select?: string[]; exclude?: string[]; include?: ${toPascal(edge.target)}IncludeSpec; limit?: number; offset?: number; orderBy?: string; order?: "asc" | "desc"; };
|
|
1943
1955
|
`;
|
|
1944
1956
|
} else {
|
|
1945
|
-
out += ` ${relKey}?: boolean | { select?: string[]; exclude?: string[];
|
|
1957
|
+
out += ` ${relKey}?: boolean | { select?: string[]; exclude?: string[]; include?: ${toPascal(edge.target)}IncludeSpec; };
|
|
1946
1958
|
`;
|
|
1947
1959
|
}
|
|
1948
1960
|
}
|
|
@@ -2599,6 +2611,15 @@ function emitClient(table, graph, opts, model) {
|
|
|
2599
2611
|
otherTableImports.push(`import type { Select${pascal(target)} } from "./types/${target}${ext}";`);
|
|
2600
2612
|
}
|
|
2601
2613
|
}
|
|
2614
|
+
const seenTypeNames = new Set;
|
|
2615
|
+
let typeAliasesCode = "";
|
|
2616
|
+
for (const method of includeMethods) {
|
|
2617
|
+
if (!seenTypeNames.has(method.typeName)) {
|
|
2618
|
+
seenTypeNames.add(method.typeName);
|
|
2619
|
+
typeAliasesCode += `export type ${method.typeName} = ${method.baseType};
|
|
2620
|
+
`;
|
|
2621
|
+
}
|
|
2622
|
+
}
|
|
2602
2623
|
let includeMethodsCode = "";
|
|
2603
2624
|
for (const method of includeMethods) {
|
|
2604
2625
|
const isGetByPk = method.name.startsWith("getByPk");
|
|
@@ -2683,7 +2704,7 @@ function emitClient(table, graph, opts, model) {
|
|
|
2683
2704
|
}
|
|
2684
2705
|
if (isGetByPk) {
|
|
2685
2706
|
const pkWhere = hasCompositePk ? `{ ${safePk.map((col) => `${col}: pk.${col}`).join(", ")} }` : `{ ${safePk[0] || "id"}: pk }`;
|
|
2686
|
-
const baseReturnType = method.
|
|
2707
|
+
const baseReturnType = method.typeName;
|
|
2687
2708
|
let transformCode = "";
|
|
2688
2709
|
if (includeParamNames.length > 0) {
|
|
2689
2710
|
const destructure = includeParamNames.map((name) => name).join(", ");
|
|
@@ -2704,9 +2725,13 @@ function emitClient(table, graph, opts, model) {
|
|
|
2704
2725
|
} else if (pattern.type === "nested" && pattern.nestedKey) {
|
|
2705
2726
|
const key = pattern.nestedKey;
|
|
2706
2727
|
const paramName = includeParamNames[0];
|
|
2728
|
+
const nestedValue = pattern.nestedValue;
|
|
2729
|
+
const requiredIncludes = Object.entries(nestedValue).map(([k, v]) => `${k}: ${JSON.stringify(v)}`).join(", ");
|
|
2707
2730
|
transformCode = `
|
|
2708
2731
|
const { ${destructure} } = params ?? {};
|
|
2709
|
-
const includeSpec =
|
|
2732
|
+
const includeSpec = { ${key}: ${paramName}
|
|
2733
|
+
? { ...${paramName}, include: { ${requiredIncludes}, ...${paramName}.include } }
|
|
2734
|
+
: ${JSON.stringify(nestedValue)} };`;
|
|
2710
2735
|
}
|
|
2711
2736
|
} else {
|
|
2712
2737
|
transformCode = `
|
|
@@ -2719,7 +2744,7 @@ function emitClient(table, graph, opts, model) {
|
|
|
2719
2744
|
* @param params - Optional include options (including select/exclude for base and nested tables)
|
|
2720
2745
|
* @returns The record with nested ${method.path.join(" and ")} if found, null otherwise
|
|
2721
2746
|
*/
|
|
2722
|
-
async ${method.name}(pk: ${pkType}, params?: ${paramsType}): Promise<${method.
|
|
2747
|
+
async ${method.name}(pk: ${pkType}, params?: ${paramsType}): Promise<${method.typeName} | null> {${transformCode}
|
|
2723
2748
|
const results = await this.post<PaginatedResponse<${baseReturnType}>>(\`\${this.resource}/list\`, {
|
|
2724
2749
|
where: ${pkWhere},
|
|
2725
2750
|
select: params?.select,
|
|
@@ -2753,9 +2778,13 @@ function emitClient(table, graph, opts, model) {
|
|
|
2753
2778
|
} else if (pattern.type === "nested" && pattern.nestedKey) {
|
|
2754
2779
|
const key = pattern.nestedKey;
|
|
2755
2780
|
const paramName = includeParamNames[0];
|
|
2781
|
+
const nestedValue = pattern.nestedValue;
|
|
2782
|
+
const requiredIncludes = Object.entries(nestedValue).map(([k, v]) => `${k}: ${JSON.stringify(v)}`).join(", ");
|
|
2756
2783
|
transformCode = `
|
|
2757
2784
|
const { ${destructure}, ...baseParams } = params ?? {};
|
|
2758
|
-
const includeSpec =
|
|
2785
|
+
const includeSpec = { ${key}: ${paramName}
|
|
2786
|
+
? { ...${paramName}, include: { ${requiredIncludes}, ...${paramName}.include } }
|
|
2787
|
+
: ${JSON.stringify(nestedValue)} };
|
|
2759
2788
|
return this.post<${method.returnType}>(\`\${this.resource}/list\`, { ...baseParams, include: includeSpec });`;
|
|
2760
2789
|
}
|
|
2761
2790
|
} else {
|
|
@@ -2768,7 +2797,7 @@ function emitClient(table, graph, opts, model) {
|
|
|
2768
2797
|
* @param params - Query parameters (where, orderBy, order, limit, offset) and include options
|
|
2769
2798
|
* @returns Paginated results with nested ${method.path.join(" and ")} included
|
|
2770
2799
|
*/
|
|
2771
|
-
async ${method.name}(params?: ${paramsType}): Promise<${method.
|
|
2800
|
+
async ${method.name}(params?: ${paramsType}): Promise<PaginatedResponse<${method.typeName}>> {${transformCode}
|
|
2772
2801
|
}
|
|
2773
2802
|
`;
|
|
2774
2803
|
}
|
|
@@ -2790,6 +2819,7 @@ ${includeResolverImport}
|
|
|
2790
2819
|
${otherTableImports.join(`
|
|
2791
2820
|
`)}
|
|
2792
2821
|
|
|
2822
|
+
${typeAliasesCode}
|
|
2793
2823
|
/**
|
|
2794
2824
|
* Client for ${table.name} table operations
|
|
2795
2825
|
*/
|
|
@@ -3245,7 +3275,7 @@ ${hasJsonbColumns ? ` /**
|
|
|
3245
3275
|
${includeMethodsCode}}
|
|
3246
3276
|
`;
|
|
3247
3277
|
}
|
|
3248
|
-
function emitClientIndex(tables, useJsExtensions) {
|
|
3278
|
+
function emitClientIndex(tables, useJsExtensions, graph, includeOpts) {
|
|
3249
3279
|
const ext = useJsExtensions ? ".js" : "";
|
|
3250
3280
|
let out = `/**
|
|
3251
3281
|
* AUTO-GENERATED FILE - DO NOT EDIT
|
|
@@ -3335,6 +3365,24 @@ export type { AuthConfig, HeaderMap, AuthHeadersProvider } from "./base-client${
|
|
|
3335
3365
|
`;
|
|
3336
3366
|
out += `export type { PaginatedResponse } from "./types/shared${ext}";
|
|
3337
3367
|
`;
|
|
3368
|
+
if (graph && includeOpts) {
|
|
3369
|
+
const opts = { maxDepth: includeOpts.maxDepth, skipJunctionTables: includeOpts.skipJunctionTables };
|
|
3370
|
+
for (const t of tables) {
|
|
3371
|
+
const methods = generateIncludeMethods(t, graph, opts, tables);
|
|
3372
|
+
const seenTypeNames = new Set;
|
|
3373
|
+
const typeNames = [];
|
|
3374
|
+
for (const method of methods) {
|
|
3375
|
+
if (!seenTypeNames.has(method.typeName)) {
|
|
3376
|
+
seenTypeNames.add(method.typeName);
|
|
3377
|
+
typeNames.push(method.typeName);
|
|
3378
|
+
}
|
|
3379
|
+
}
|
|
3380
|
+
if (typeNames.length > 0) {
|
|
3381
|
+
out += `export type { ${typeNames.join(", ")} } from "./${t.name}${ext}";
|
|
3382
|
+
`;
|
|
3383
|
+
}
|
|
3384
|
+
}
|
|
3385
|
+
}
|
|
3338
3386
|
return out;
|
|
3339
3387
|
}
|
|
3340
3388
|
|
|
@@ -3761,9 +3809,15 @@ export async function loadIncludes(
|
|
|
3761
3809
|
// Could be belongs-to (current has FK to target) OR has-one (target unique-FK to current)
|
|
3762
3810
|
const specValue = s[key];
|
|
3763
3811
|
const options: RelationOptions = {};
|
|
3812
|
+
let childSpec: any = undefined;
|
|
3813
|
+
|
|
3764
3814
|
if (specValue && typeof specValue === "object" && specValue !== true) {
|
|
3765
3815
|
if (specValue.select !== undefined) options.select = specValue.select;
|
|
3766
3816
|
if (specValue.exclude !== undefined) options.exclude = specValue.exclude;
|
|
3817
|
+
// Support { include: TargetIncludeSpec } — mirrors the many/via handler
|
|
3818
|
+
if (specValue.include !== undefined) {
|
|
3819
|
+
childSpec = specValue.include;
|
|
3820
|
+
}
|
|
3767
3821
|
}
|
|
3768
3822
|
|
|
3769
3823
|
const currFks = (FK_INDEX as any)[table] as Array<{from:string[];toTable:string;to:string[]}>;
|
|
@@ -3783,7 +3837,7 @@ export async function loadIncludes(
|
|
|
3783
3837
|
for (const r of rows) r[key] = null;
|
|
3784
3838
|
}
|
|
3785
3839
|
}
|
|
3786
|
-
|
|
3840
|
+
|
|
3787
3841
|
if (childSpec) {
|
|
3788
3842
|
const children = rows.map(r => r[key]).filter(Boolean);
|
|
3789
3843
|
try {
|
|
@@ -6316,7 +6370,7 @@ async function generate(configPath) {
|
|
|
6316
6370
|
}
|
|
6317
6371
|
files.push({
|
|
6318
6372
|
path: join(clientDir, "index.ts"),
|
|
6319
|
-
content: emitClientIndex(Object.values(model.tables), cfg.useJsExtensionsClient)
|
|
6373
|
+
content: emitClientIndex(Object.values(model.tables), cfg.useJsExtensionsClient, graph, { maxDepth: cfg.includeMethodsDepth ?? 2, skipJunctionTables: cfg.skipJunctionTables ?? true })
|
|
6320
6374
|
});
|
|
6321
6375
|
if (serverFramework === "hono") {
|
|
6322
6376
|
files.push({
|