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 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<${buildReturnType(baseTableName, newPath, newIsMany, newTargets, graph)}>`,
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: `${buildReturnType(baseTableName, newPath, newIsMany, newTargets, graph)} | null`,
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<Select${pascal(baseTableName)} & { ${type1}; ${type2} }>`,
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: `(Select${pascal(baseTableName)} & { ${type1}; ${type2} }) | null`,
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[]; } | ${toPascal(edge.target)}IncludeSpec;
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.returnType.replace(" | null", "");
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 = ${paramName} ? { ${key}: ${paramName} } : ${JSON.stringify(method.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.returnType}> {${transformCode}
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 = ${paramName} ? { ${key}: ${paramName} } : ${JSON.stringify(method.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.returnType}> {${transformCode}
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
- const childSpec = s[key] && typeof s[key] === "object" ? s[key] : undefined;
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({
@@ -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): string;
8
+ export declare function emitClientIndex(tables: Table[], useJsExtensions?: boolean, graph?: Graph, includeOpts?: {
9
+ maxDepth: number;
10
+ skipJunctionTables: boolean;
11
+ }): string;
@@ -6,6 +6,8 @@ export type IncludeMethod = {
6
6
  isMany: boolean[];
7
7
  targets: string[];
8
8
  returnType: string;
9
+ typeName: string;
10
+ baseType: string;
9
11
  includeSpec: any;
10
12
  };
11
13
  /**
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<${buildReturnType(baseTableName, newPath, newIsMany, newTargets, graph)}>`,
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: `${buildReturnType(baseTableName, newPath, newIsMany, newTargets, graph)} | null`,
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<Select${pascal(baseTableName)} & { ${type1}; ${type2} }>`,
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: `(Select${pascal(baseTableName)} & { ${type1}; ${type2} }) | null`,
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[]; } | ${toPascal(edge.target)}IncludeSpec;
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.returnType.replace(" | null", "");
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 = ${paramName} ? { ${key}: ${paramName} } : ${JSON.stringify(method.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.returnType}> {${transformCode}
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 = ${paramName} ? { ${key}: ${paramName} } : ${JSON.stringify(method.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.returnType}> {${transformCode}
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
- const childSpec = s[key] && typeof s[key] === "object" ? s[key] : undefined;
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({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "postgresdk",
3
- "version": "0.18.13",
3
+ "version": "0.18.15",
4
4
  "description": "Generate a typed server/client SDK from a Postgres schema (includes, Zod, Hono).",
5
5
  "type": "module",
6
6
  "bin": {