postgresdk 0.19.3 → 0.19.4

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/README.md CHANGED
@@ -154,6 +154,7 @@ export default {
154
154
  },
155
155
  },
156
156
  numericMode: "auto", // "auto" | "number" | "string" - How to type numeric columns
157
+ maxLimit: 1000, // Max allowed `limit` value (0 = no cap)
157
158
  includeMethodsDepth: 2, // Max depth for nested includes
158
159
  dateType: "date", // "date" | "string" - How to handle timestamps
159
160
  serverFramework: "hono", // Currently only hono is supported
@@ -715,15 +716,15 @@ const result = await sdk.users.list({
715
716
  // Access results
716
717
  result.data; // User[] - array of records
717
718
  result.total; // number - total matching records
718
- result.limit; // number - page size used
719
+ result.limit; // number | undefined - page size used (absent when no limit specified)
719
720
  result.offset; // number - offset used
720
- result.hasMore; // boolean - more pages available
721
+ result.hasMore; // boolean - more pages available (false when no limit)
721
722
 
722
- // Note: Maximum limit is 1000 records per request
723
+ // Note: Omitting `limit` returns all matching records. Max limit is controlled by `maxLimit` config (default: 1000).
723
724
 
724
- // Calculate pagination info
725
- const totalPages = Math.ceil(result.total / result.limit);
726
- const currentPage = Math.floor(result.offset / result.limit) + 1;
725
+ // Calculate pagination info (when using explicit limit)
726
+ const totalPages = result.limit ? Math.ceil(result.total / result.limit) : 1;
727
+ const currentPage = result.limit ? Math.floor(result.offset / result.limit) + 1 : 1;
727
728
 
728
729
  // Multi-column sorting
729
730
  const sorted = await sdk.users.list({
package/dist/cli.js CHANGED
@@ -1221,7 +1221,7 @@ function generateExampleValue(column) {
1221
1221
  }
1222
1222
  function generateQueryParams(table, enums) {
1223
1223
  const params = {
1224
- limit: "number - Max records to return (default: 50)",
1224
+ limit: "number - Max records to return (omit for all)",
1225
1225
  offset: "number - Records to skip",
1226
1226
  orderBy: "string | string[] - Field(s) to sort by",
1227
1227
  order: "'asc' | 'desc' | ('asc' | 'desc')[] - Sort direction(s)"
@@ -2920,7 +2920,7 @@ export const Upsert${Type}Schema = z.object({
2920
2920
 
2921
2921
  // src/emit-params-zod.ts
2922
2922
  init_utils();
2923
- function emitParamsZod(table, graph) {
2923
+ function emitParamsZod(table, graph, opts) {
2924
2924
  const Type = pascal(table.name);
2925
2925
  const columnNames = table.columns.map((c) => `"${c.name}"`).join(", ");
2926
2926
  const pkCols = Array.isArray(table.pk) ? table.pk : table.pk ? [table.pk] : [];
@@ -2937,7 +2937,7 @@ export const ${Type}PkSchema = ${pkSchema};
2937
2937
  // Schema for list query parameters
2938
2938
  export const ${Type}ListParamsSchema = z.object({
2939
2939
  include: ${includeSpecSchema}.optional(),
2940
- limit: z.number().int().positive().max(1000).optional(),
2940
+ limit: z.number().int().positive()${opts.maxLimit > 0 ? `.max(${opts.maxLimit})` : ""}.optional(),
2941
2941
  offset: z.number().int().nonnegative().optional(),
2942
2942
  where: z.any().optional(),
2943
2943
  vector: VectorSearchParamsSchema.optional(),
@@ -2959,12 +2959,12 @@ export type ${Type}OrderParams = z.infer<typeof ${Type}OrderParamsSchema>;
2959
2959
  }
2960
2960
 
2961
2961
  // src/emit-shared-params-zod.ts
2962
- function emitSharedParamsZod() {
2962
+ function emitSharedParamsZod(opts) {
2963
2963
  return `import { z } from "zod";
2964
2964
 
2965
2965
  // Shared pagination schema (used across all tables)
2966
2966
  export const PaginationParamsSchema = z.object({
2967
- limit: z.number().int().positive().max(1000).optional(),
2967
+ limit: z.number().int().positive()${opts.maxLimit > 0 ? `.max(${opts.maxLimit})` : ""}.optional(),
2968
2968
  offset: z.number().int().nonnegative().optional()
2969
2969
  }).strict();
2970
2970
 
@@ -2996,8 +2996,8 @@ export interface PaginatedResponse<T> {
2996
2996
  data: T[];
2997
2997
  /** Total number of records matching the query (across all pages) */
2998
2998
  total: number;
2999
- /** Maximum number of records per page */
3000
- limit: number;
2999
+ /** Maximum number of records per page (absent when no limit was specified) */
3000
+ limit?: number;
3001
3001
  /** Number of records skipped (for pagination) */
3002
3002
  offset: number;
3003
3003
  /** Whether there are more records available after this page */
@@ -3072,7 +3072,7 @@ const listSchema = z.object({
3072
3072
  include: z.any().optional(),
3073
3073
  select: z.array(z.string()).min(1).optional(),
3074
3074
  exclude: z.array(z.string()).min(1).optional(),
3075
- limit: z.number().int().positive().max(1000).optional(),
3075
+ limit: z.number().int().positive()${opts.maxLimit > 0 ? `.max(${opts.maxLimit})` : ""}.optional(),
3076
3076
  offset: z.number().int().min(0).optional(),
3077
3077
  orderBy: z.union([columnEnum, z.array(columnEnum)]).optional(),
3078
3078
  order: z.union([z.enum(["asc", "desc"]), z.array(z.enum(["asc", "desc"]))]).optional(),
@@ -3985,7 +3985,7 @@ ${hasJsonbColumns ? ` /**
3985
3985
  * @param params.where - Filter conditions using operators like $eq, $gt, $in, $like, etc.
3986
3986
  * @param params.orderBy - Column(s) to sort by
3987
3987
  * @param params.order - Sort direction(s): "asc" or "desc"
3988
- * @param params.limit - Maximum number of records to return (default: 50, max: 1000)
3988
+ * @param params.limit - Maximum number of records to return${opts.maxLimit > 0 ? ` (max: ${opts.maxLimit})` : ""}. Omit to return all matching records.
3989
3989
  * @param params.offset - Number of records to skip for pagination
3990
3990
  * @param params.include - Related records to include (return type automatically infers included relations)
3991
3991
  * @returns Paginated results with all fields (and included relations if specified)
@@ -4085,7 +4085,7 @@ ${hasJsonbColumns ? ` /**
4085
4085
  * @param params.where - Filter conditions using operators like $eq, $gt, $in, $like, etc.
4086
4086
  * @param params.orderBy - Column(s) to sort by
4087
4087
  * @param params.order - Sort direction(s): "asc" or "desc"
4088
- * @param params.limit - Maximum number of records to return (default: 50, max: 1000)
4088
+ * @param params.limit - Maximum number of records to return${opts.maxLimit > 0 ? ` (max: ${opts.maxLimit})` : ""}. Omit to return all matching records.
4089
4089
  * @param params.offset - Number of records to skip for pagination
4090
4090
  * @param params.include - Related records to include (return type automatically infers included relations)
4091
4091
  * @returns Paginated results with all fields (and included relations if specified)
@@ -6579,7 +6579,7 @@ export async function listRecords(
6579
6579
  }
6580
6580
  ): Promise<{ data?: any; total?: number; limit?: number; offset?: number; hasMore?: boolean; error?: string; issues?: any; needsIncludes?: boolean; includeSpec?: any; status: number }> {
6581
6581
  try {
6582
- const { where: whereClause, limit = 50, offset = 0, include, orderBy, order, vector, trigram, distinctOn, includeSoftDeleted } = params;
6582
+ const { where: whereClause, limit, offset = 0, include, orderBy, order, vector, trigram, distinctOn, includeSoftDeleted } = params;
6583
6583
 
6584
6584
  // DISTINCT ON support
6585
6585
  const distinctCols: string[] | null = distinctOn ? (Array.isArray(distinctOn) ? distinctOn : [distinctOn]) : null;
@@ -6715,10 +6715,22 @@ export async function listRecords(
6715
6715
  orderBySQL = buildOrderBySQL(userOrderCols, userDirs);
6716
6716
  }
6717
6717
 
6718
- // Add limit and offset params
6719
- const limitParam = \`$\${paramIndex}\`;
6720
- const offsetParam = \`$\${paramIndex + 1}\`;
6721
- const allParams = [...queryParams, ...whereParams, limit, offset];
6718
+ // Add limit and offset params (conditional — omit LIMIT clause when limit is undefined)
6719
+ let limitOffsetSQL: string;
6720
+ let allParams: any[];
6721
+ if (limit !== undefined) {
6722
+ const limitParam = \`$\${paramIndex}\`;
6723
+ const offsetParam = \`$\${paramIndex + 1}\`;
6724
+ limitOffsetSQL = \`LIMIT \${limitParam} OFFSET \${offsetParam}\`;
6725
+ allParams = [...queryParams, ...whereParams, limit, offset];
6726
+ } else if (offset > 0) {
6727
+ const offsetParam = \`$\${paramIndex}\`;
6728
+ limitOffsetSQL = \`OFFSET \${offsetParam}\`;
6729
+ allParams = [...queryParams, ...whereParams, offset];
6730
+ } else {
6731
+ limitOffsetSQL = '';
6732
+ allParams = [...queryParams, ...whereParams];
6733
+ }
6722
6734
 
6723
6735
  // Get total count for pagination
6724
6736
  const countText = distinctCols
@@ -6734,9 +6746,9 @@ export async function listRecords(
6734
6746
  // Inner query: DISTINCT ON with only the distinctCols ORDER BY prefix (PG requirement).
6735
6747
  // Outer query: free ORDER BY from the user's full orderBy list, plus LIMIT/OFFSET.
6736
6748
  const innerQuery = \`SELECT DISTINCT ON (\${_distinctOnColsSQL}) \${baseColumns} FROM "\${ctx.table}" \${whereSQL} ORDER BY \${_distinctOnColsSQL}\`;
6737
- text = \`SELECT * FROM (\${innerQuery}) __distinct \${orderBySQL} LIMIT \${limitParam} OFFSET \${offsetParam}\`;
6749
+ text = \`SELECT * FROM (\${innerQuery}) __distinct \${orderBySQL} \${limitOffsetSQL}\`.trim();
6738
6750
  } else {
6739
- text = \`SELECT \${selectClause} FROM "\${ctx.table}" \${whereSQL} \${orderBySQL} LIMIT \${limitParam} OFFSET \${offsetParam}\`;
6751
+ text = \`SELECT \${selectClause} FROM "\${ctx.table}" \${whereSQL} \${orderBySQL} \${limitOffsetSQL}\`.trim();
6740
6752
  }
6741
6753
  log.debug(\`LIST \${ctx.table} SQL:\`, text, "params:", allParams);
6742
6754
 
@@ -6744,7 +6756,7 @@ export async function listRecords(
6744
6756
  const parsedRows = parseVectorColumns(rows, ctx.vectorColumns);
6745
6757
 
6746
6758
  // Calculate hasMore
6747
- const hasMore = offset + limit < total;
6759
+ const hasMore = limit !== undefined ? offset + limit < total : false;
6748
6760
 
6749
6761
  const metadata = {
6750
6762
  data: parsedRows,
@@ -7784,6 +7796,7 @@ async function generate(configPath, options) {
7784
7796
  clientDir = join2(originalClientDir, "sdk");
7785
7797
  }
7786
7798
  const serverFramework = cfg.serverFramework || "hono";
7799
+ const maxLimit = cfg.maxLimit ?? 1000;
7787
7800
  const generateTests = cfg.tests?.generate ?? false;
7788
7801
  const originalTestDir = cfg.tests?.output || "./api/tests";
7789
7802
  let testDir = originalTestDir;
@@ -7812,7 +7825,7 @@ async function generate(configPath, options) {
7812
7825
  files.push({ path: join2(clientDir, "include-spec.ts"), content: includeSpec });
7813
7826
  const includeResolver = emitIncludeResolver(graph, cfg.useJsExtensions);
7814
7827
  files.push({ path: join2(clientDir, "include-resolver.ts"), content: includeResolver });
7815
- files.push({ path: join2(clientDir, "params", "shared.ts"), content: emitSharedParamsZod() });
7828
+ files.push({ path: join2(clientDir, "params", "shared.ts"), content: emitSharedParamsZod({ maxLimit }) });
7816
7829
  files.push({ path: join2(clientDir, "types", "shared.ts"), content: emitSharedTypes() });
7817
7830
  files.push({ path: join2(clientDir, "base-client.ts"), content: emitBaseClient() });
7818
7831
  files.push({ path: join2(clientDir, "where-types.ts"), content: emitWhereTypes() });
@@ -7849,7 +7862,7 @@ async function generate(configPath, options) {
7849
7862
  const zodSrc = emitZod(table, { numericMode }, model.enums);
7850
7863
  files.push({ path: join2(serverDir, "zod", `${table.name}.ts`), content: zodSrc });
7851
7864
  files.push({ path: join2(clientDir, "zod", `${table.name}.ts`), content: zodSrc });
7852
- const paramsZodSrc = emitParamsZod(table, graph);
7865
+ const paramsZodSrc = emitParamsZod(table, graph, { maxLimit });
7853
7866
  files.push({ path: join2(clientDir, "params", `${table.name}.ts`), content: paramsZodSrc });
7854
7867
  let routeContent;
7855
7868
  if (serverFramework === "hono") {
@@ -7859,7 +7872,8 @@ async function generate(configPath, options) {
7859
7872
  includeMethodsDepth: cfg.includeMethodsDepth || 2,
7860
7873
  authStrategy: getAuthStrategy(normalizedAuth),
7861
7874
  useJsExtensions: cfg.useJsExtensions,
7862
- apiPathPrefix: cfg.apiPathPrefix || "/v1"
7875
+ apiPathPrefix: cfg.apiPathPrefix || "/v1",
7876
+ maxLimit
7863
7877
  });
7864
7878
  } else {
7865
7879
  throw new Error(`Framework "${serverFramework}" is not yet supported. Currently only "hono" is available.`);
@@ -7875,7 +7889,8 @@ async function generate(configPath, options) {
7875
7889
  exposeHardDelete,
7876
7890
  useJsExtensions: cfg.useJsExtensionsClient,
7877
7891
  includeMethodsDepth: cfg.includeMethodsDepth ?? 2,
7878
- skipJunctionTables: cfg.skipJunctionTables ?? true
7892
+ skipJunctionTables: cfg.skipJunctionTables ?? true,
7893
+ maxLimit
7879
7894
  }, model)
7880
7895
  });
7881
7896
  }
@@ -6,6 +6,7 @@ export declare function emitClient(table: Table, graph: Graph, opts: {
6
6
  useJsExtensions?: boolean;
7
7
  includeMethodsDepth?: number;
8
8
  skipJunctionTables?: boolean;
9
+ maxLimit: number;
9
10
  }, model?: Model): string;
10
11
  export declare function emitClientIndex(tables: Table[], useJsExtensions?: boolean, graph?: Graph, includeOpts?: {
11
12
  maxDepth: number;
@@ -1,3 +1,5 @@
1
1
  import type { Table } from "./introspect";
2
2
  import type { Graph } from "./rel-classify";
3
- export declare function emitParamsZod(table: Table, graph: Graph): string;
3
+ export declare function emitParamsZod(table: Table, graph: Graph, opts: {
4
+ maxLimit: number;
5
+ }): string;
@@ -10,4 +10,5 @@ export declare function emitHonoRoutes(table: Table, _graph: Graph, opts: {
10
10
  authStrategy?: string;
11
11
  useJsExtensions?: boolean;
12
12
  apiPathPrefix: string;
13
+ maxLimit: number;
13
14
  }): string;
@@ -18,4 +18,5 @@ export declare function emitRoutes(table: Table, _graph: Graph, opts: {
18
18
  softDeleteColumn: string | null;
19
19
  includeMethodsDepth: number;
20
20
  authStrategy?: string;
21
+ maxLimit: number;
21
22
  }): string;
@@ -1 +1,3 @@
1
- export declare function emitSharedParamsZod(): string;
1
+ export declare function emitSharedParamsZod(opts: {
2
+ maxLimit: number;
3
+ }): string;
package/dist/index.js CHANGED
@@ -1220,7 +1220,7 @@ function generateExampleValue(column) {
1220
1220
  }
1221
1221
  function generateQueryParams(table, enums) {
1222
1222
  const params = {
1223
- limit: "number - Max records to return (default: 50)",
1223
+ limit: "number - Max records to return (omit for all)",
1224
1224
  offset: "number - Records to skip",
1225
1225
  orderBy: "string | string[] - Field(s) to sort by",
1226
1226
  order: "'asc' | 'desc' | ('asc' | 'desc')[] - Sort direction(s)"
@@ -1960,7 +1960,7 @@ export const Upsert${Type}Schema = z.object({
1960
1960
 
1961
1961
  // src/emit-params-zod.ts
1962
1962
  init_utils();
1963
- function emitParamsZod(table, graph) {
1963
+ function emitParamsZod(table, graph, opts) {
1964
1964
  const Type = pascal(table.name);
1965
1965
  const columnNames = table.columns.map((c) => `"${c.name}"`).join(", ");
1966
1966
  const pkCols = Array.isArray(table.pk) ? table.pk : table.pk ? [table.pk] : [];
@@ -1977,7 +1977,7 @@ export const ${Type}PkSchema = ${pkSchema};
1977
1977
  // Schema for list query parameters
1978
1978
  export const ${Type}ListParamsSchema = z.object({
1979
1979
  include: ${includeSpecSchema}.optional(),
1980
- limit: z.number().int().positive().max(1000).optional(),
1980
+ limit: z.number().int().positive()${opts.maxLimit > 0 ? `.max(${opts.maxLimit})` : ""}.optional(),
1981
1981
  offset: z.number().int().nonnegative().optional(),
1982
1982
  where: z.any().optional(),
1983
1983
  vector: VectorSearchParamsSchema.optional(),
@@ -1999,12 +1999,12 @@ export type ${Type}OrderParams = z.infer<typeof ${Type}OrderParamsSchema>;
1999
1999
  }
2000
2000
 
2001
2001
  // src/emit-shared-params-zod.ts
2002
- function emitSharedParamsZod() {
2002
+ function emitSharedParamsZod(opts) {
2003
2003
  return `import { z } from "zod";
2004
2004
 
2005
2005
  // Shared pagination schema (used across all tables)
2006
2006
  export const PaginationParamsSchema = z.object({
2007
- limit: z.number().int().positive().max(1000).optional(),
2007
+ limit: z.number().int().positive()${opts.maxLimit > 0 ? `.max(${opts.maxLimit})` : ""}.optional(),
2008
2008
  offset: z.number().int().nonnegative().optional()
2009
2009
  }).strict();
2010
2010
 
@@ -2036,8 +2036,8 @@ export interface PaginatedResponse<T> {
2036
2036
  data: T[];
2037
2037
  /** Total number of records matching the query (across all pages) */
2038
2038
  total: number;
2039
- /** Maximum number of records per page */
2040
- limit: number;
2039
+ /** Maximum number of records per page (absent when no limit was specified) */
2040
+ limit?: number;
2041
2041
  /** Number of records skipped (for pagination) */
2042
2042
  offset: number;
2043
2043
  /** Whether there are more records available after this page */
@@ -2112,7 +2112,7 @@ const listSchema = z.object({
2112
2112
  include: z.any().optional(),
2113
2113
  select: z.array(z.string()).min(1).optional(),
2114
2114
  exclude: z.array(z.string()).min(1).optional(),
2115
- limit: z.number().int().positive().max(1000).optional(),
2115
+ limit: z.number().int().positive()${opts.maxLimit > 0 ? `.max(${opts.maxLimit})` : ""}.optional(),
2116
2116
  offset: z.number().int().min(0).optional(),
2117
2117
  orderBy: z.union([columnEnum, z.array(columnEnum)]).optional(),
2118
2118
  order: z.union([z.enum(["asc", "desc"]), z.array(z.enum(["asc", "desc"]))]).optional(),
@@ -3025,7 +3025,7 @@ ${hasJsonbColumns ? ` /**
3025
3025
  * @param params.where - Filter conditions using operators like $eq, $gt, $in, $like, etc.
3026
3026
  * @param params.orderBy - Column(s) to sort by
3027
3027
  * @param params.order - Sort direction(s): "asc" or "desc"
3028
- * @param params.limit - Maximum number of records to return (default: 50, max: 1000)
3028
+ * @param params.limit - Maximum number of records to return${opts.maxLimit > 0 ? ` (max: ${opts.maxLimit})` : ""}. Omit to return all matching records.
3029
3029
  * @param params.offset - Number of records to skip for pagination
3030
3030
  * @param params.include - Related records to include (return type automatically infers included relations)
3031
3031
  * @returns Paginated results with all fields (and included relations if specified)
@@ -3125,7 +3125,7 @@ ${hasJsonbColumns ? ` /**
3125
3125
  * @param params.where - Filter conditions using operators like $eq, $gt, $in, $like, etc.
3126
3126
  * @param params.orderBy - Column(s) to sort by
3127
3127
  * @param params.order - Sort direction(s): "asc" or "desc"
3128
- * @param params.limit - Maximum number of records to return (default: 50, max: 1000)
3128
+ * @param params.limit - Maximum number of records to return${opts.maxLimit > 0 ? ` (max: ${opts.maxLimit})` : ""}. Omit to return all matching records.
3129
3129
  * @param params.offset - Number of records to skip for pagination
3130
3130
  * @param params.include - Related records to include (return type automatically infers included relations)
3131
3131
  * @returns Paginated results with all fields (and included relations if specified)
@@ -5619,7 +5619,7 @@ export async function listRecords(
5619
5619
  }
5620
5620
  ): Promise<{ data?: any; total?: number; limit?: number; offset?: number; hasMore?: boolean; error?: string; issues?: any; needsIncludes?: boolean; includeSpec?: any; status: number }> {
5621
5621
  try {
5622
- const { where: whereClause, limit = 50, offset = 0, include, orderBy, order, vector, trigram, distinctOn, includeSoftDeleted } = params;
5622
+ const { where: whereClause, limit, offset = 0, include, orderBy, order, vector, trigram, distinctOn, includeSoftDeleted } = params;
5623
5623
 
5624
5624
  // DISTINCT ON support
5625
5625
  const distinctCols: string[] | null = distinctOn ? (Array.isArray(distinctOn) ? distinctOn : [distinctOn]) : null;
@@ -5755,10 +5755,22 @@ export async function listRecords(
5755
5755
  orderBySQL = buildOrderBySQL(userOrderCols, userDirs);
5756
5756
  }
5757
5757
 
5758
- // Add limit and offset params
5759
- const limitParam = \`$\${paramIndex}\`;
5760
- const offsetParam = \`$\${paramIndex + 1}\`;
5761
- const allParams = [...queryParams, ...whereParams, limit, offset];
5758
+ // Add limit and offset params (conditional — omit LIMIT clause when limit is undefined)
5759
+ let limitOffsetSQL: string;
5760
+ let allParams: any[];
5761
+ if (limit !== undefined) {
5762
+ const limitParam = \`$\${paramIndex}\`;
5763
+ const offsetParam = \`$\${paramIndex + 1}\`;
5764
+ limitOffsetSQL = \`LIMIT \${limitParam} OFFSET \${offsetParam}\`;
5765
+ allParams = [...queryParams, ...whereParams, limit, offset];
5766
+ } else if (offset > 0) {
5767
+ const offsetParam = \`$\${paramIndex}\`;
5768
+ limitOffsetSQL = \`OFFSET \${offsetParam}\`;
5769
+ allParams = [...queryParams, ...whereParams, offset];
5770
+ } else {
5771
+ limitOffsetSQL = '';
5772
+ allParams = [...queryParams, ...whereParams];
5773
+ }
5762
5774
 
5763
5775
  // Get total count for pagination
5764
5776
  const countText = distinctCols
@@ -5774,9 +5786,9 @@ export async function listRecords(
5774
5786
  // Inner query: DISTINCT ON with only the distinctCols ORDER BY prefix (PG requirement).
5775
5787
  // Outer query: free ORDER BY from the user's full orderBy list, plus LIMIT/OFFSET.
5776
5788
  const innerQuery = \`SELECT DISTINCT ON (\${_distinctOnColsSQL}) \${baseColumns} FROM "\${ctx.table}" \${whereSQL} ORDER BY \${_distinctOnColsSQL}\`;
5777
- text = \`SELECT * FROM (\${innerQuery}) __distinct \${orderBySQL} LIMIT \${limitParam} OFFSET \${offsetParam}\`;
5789
+ text = \`SELECT * FROM (\${innerQuery}) __distinct \${orderBySQL} \${limitOffsetSQL}\`.trim();
5778
5790
  } else {
5779
- text = \`SELECT \${selectClause} FROM "\${ctx.table}" \${whereSQL} \${orderBySQL} LIMIT \${limitParam} OFFSET \${offsetParam}\`;
5791
+ text = \`SELECT \${selectClause} FROM "\${ctx.table}" \${whereSQL} \${orderBySQL} \${limitOffsetSQL}\`.trim();
5780
5792
  }
5781
5793
  log.debug(\`LIST \${ctx.table} SQL:\`, text, "params:", allParams);
5782
5794
 
@@ -5784,7 +5796,7 @@ export async function listRecords(
5784
5796
  const parsedRows = parseVectorColumns(rows, ctx.vectorColumns);
5785
5797
 
5786
5798
  // Calculate hasMore
5787
- const hasMore = offset + limit < total;
5799
+ const hasMore = limit !== undefined ? offset + limit < total : false;
5788
5800
 
5789
5801
  const metadata = {
5790
5802
  data: parsedRows,
@@ -6824,6 +6836,7 @@ async function generate(configPath, options) {
6824
6836
  clientDir = join2(originalClientDir, "sdk");
6825
6837
  }
6826
6838
  const serverFramework = cfg.serverFramework || "hono";
6839
+ const maxLimit = cfg.maxLimit ?? 1000;
6827
6840
  const generateTests = cfg.tests?.generate ?? false;
6828
6841
  const originalTestDir = cfg.tests?.output || "./api/tests";
6829
6842
  let testDir = originalTestDir;
@@ -6852,7 +6865,7 @@ async function generate(configPath, options) {
6852
6865
  files.push({ path: join2(clientDir, "include-spec.ts"), content: includeSpec });
6853
6866
  const includeResolver = emitIncludeResolver(graph, cfg.useJsExtensions);
6854
6867
  files.push({ path: join2(clientDir, "include-resolver.ts"), content: includeResolver });
6855
- files.push({ path: join2(clientDir, "params", "shared.ts"), content: emitSharedParamsZod() });
6868
+ files.push({ path: join2(clientDir, "params", "shared.ts"), content: emitSharedParamsZod({ maxLimit }) });
6856
6869
  files.push({ path: join2(clientDir, "types", "shared.ts"), content: emitSharedTypes() });
6857
6870
  files.push({ path: join2(clientDir, "base-client.ts"), content: emitBaseClient() });
6858
6871
  files.push({ path: join2(clientDir, "where-types.ts"), content: emitWhereTypes() });
@@ -6889,7 +6902,7 @@ async function generate(configPath, options) {
6889
6902
  const zodSrc = emitZod(table, { numericMode }, model.enums);
6890
6903
  files.push({ path: join2(serverDir, "zod", `${table.name}.ts`), content: zodSrc });
6891
6904
  files.push({ path: join2(clientDir, "zod", `${table.name}.ts`), content: zodSrc });
6892
- const paramsZodSrc = emitParamsZod(table, graph);
6905
+ const paramsZodSrc = emitParamsZod(table, graph, { maxLimit });
6893
6906
  files.push({ path: join2(clientDir, "params", `${table.name}.ts`), content: paramsZodSrc });
6894
6907
  let routeContent;
6895
6908
  if (serverFramework === "hono") {
@@ -6899,7 +6912,8 @@ async function generate(configPath, options) {
6899
6912
  includeMethodsDepth: cfg.includeMethodsDepth || 2,
6900
6913
  authStrategy: getAuthStrategy(normalizedAuth),
6901
6914
  useJsExtensions: cfg.useJsExtensions,
6902
- apiPathPrefix: cfg.apiPathPrefix || "/v1"
6915
+ apiPathPrefix: cfg.apiPathPrefix || "/v1",
6916
+ maxLimit
6903
6917
  });
6904
6918
  } else {
6905
6919
  throw new Error(`Framework "${serverFramework}" is not yet supported. Currently only "hono" is available.`);
@@ -6915,7 +6929,8 @@ async function generate(configPath, options) {
6915
6929
  exposeHardDelete,
6916
6930
  useJsExtensions: cfg.useJsExtensionsClient,
6917
6931
  includeMethodsDepth: cfg.includeMethodsDepth ?? 2,
6918
- skipJunctionTables: cfg.skipJunctionTables ?? true
6932
+ skipJunctionTables: cfg.skipJunctionTables ?? true,
6933
+ maxLimit
6919
6934
  }, model)
6920
6935
  });
6921
6936
  }
package/dist/types.d.ts CHANGED
@@ -38,6 +38,8 @@ export interface Config {
38
38
  skipJunctionTables?: boolean;
39
39
  serverFramework?: "hono" | "express" | "fastify";
40
40
  apiPathPrefix?: string;
41
+ /** Maximum allowed value for the `limit` parameter in list operations (default: 1000). Set to 0 to disable. */
42
+ maxLimit?: number;
41
43
  auth?: AuthConfigInput;
42
44
  pullToken?: string;
43
45
  pull?: PullConfig;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "postgresdk",
3
- "version": "0.19.3",
3
+ "version": "0.19.4",
4
4
  "description": "Generate a typed server/client SDK from a Postgres schema (includes, Zod, Hono).",
5
5
  "type": "module",
6
6
  "bin": {
@@ -22,7 +22,7 @@
22
22
  },
23
23
  "scripts": {
24
24
  "build": "bun build src/cli.ts src/index.ts --outdir dist --target node --format esm --external=pg --external=zod --external=hono --external=prompts --external=node:* && tsc -p tsconfig.build.json --emitDeclarationOnly",
25
- "test": "bun test:write-files && bun test:init && bun test:gen && bun test test/test-where-clause.test.ts && bun test test/test-where-or-and.test.ts && bun test test/test-nested-include-options.test.ts && bun test test/test-include-methods-with-options.test.ts && bun test:gen-with-tests && bun test:pull && bun test:enums && bun test:typecheck && bun test:drizzle-e2e && bun test test/test-numeric-mode-integration.test.ts && bun test test/test-jsonb-array-serialization.test.ts && bun test test/test-trigram-search.test.ts && bun test test/test-soft-delete-config.test.ts && bun test test/test-soft-delete-include-loader.test.ts && bun test test/test-soft-delete-nested-include.test.ts && bun test test/test-transaction.test.ts && bun test test/test-nullable-belongs-to.test.ts",
25
+ "test": "bun test:write-files && bun test:init && bun test:gen && bun test test/test-where-clause.test.ts && bun test test/test-where-or-and.test.ts && bun test test/test-nested-include-options.test.ts && bun test test/test-include-methods-with-options.test.ts && bun test:gen-with-tests && bun test:pull && bun test:enums && bun test:typecheck && bun test:drizzle-e2e && bun test test/test-numeric-mode-integration.test.ts && bun test test/test-jsonb-array-serialization.test.ts && bun test test/test-trigram-search.test.ts && bun test test/test-soft-delete-config.test.ts && bun test test/test-soft-delete-include-loader.test.ts && bun test test/test-soft-delete-nested-include.test.ts && bun test test/test-transaction.test.ts && bun test test/test-nullable-belongs-to.test.ts && bun test test/test-no-default-limit.test.ts",
26
26
  "test:write-files": "bun test/test-write-files-if-changed.ts",
27
27
  "test:init": "bun test/test-init.ts",
28
28
  "test:gen": "bun test/test-gen.ts",