postgresdk 0.18.28 → 0.18.30

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
@@ -547,6 +547,8 @@ pnpm dlx postgresdk@latest pull
547
547
 
548
548
  The SDK files are written directly to your client project, giving you full TypeScript autocomplete and type safety.
549
549
 
550
+ **Stale file cleanup:** Both `generate` and `pull` automatically remove files that are no longer part of the SDK. In an interactive terminal you'll be prompted to confirm each deletion; use `--force` (or `-y`) to skip prompts. In non-interactive environments (CI), stale files are skipped with a warning unless `--force` is passed.
551
+
550
552
  ### Using the SDK
551
553
 
552
554
  #### CRUD Operations
@@ -1014,6 +1016,7 @@ Commands:
1014
1016
 
1015
1017
  Options:
1016
1018
  -c, --config <path> Path to config file (default: postgresdk.config.ts)
1019
+ --force, -y Delete stale files without prompting (generate & pull)
1017
1020
 
1018
1021
  Init subcommands/flags:
1019
1022
  init pull Generate pull-only config (alias for --sdk)
@@ -1026,7 +1029,9 @@ Examples:
1026
1029
  npx postgresdk@latest init --api # API-side config
1027
1030
  npx postgresdk@latest generate
1028
1031
  npx postgresdk@latest generate -c custom.config.ts
1032
+ npx postgresdk@latest generate --force # Skip stale file prompts
1029
1033
  npx postgresdk@latest pull --from=https://api.com --output=./src/sdk
1034
+ npx postgresdk@latest pull --from=https://api.com --output=./src/sdk --force
1030
1035
  ```
1031
1036
 
1032
1037
  ### Generated Tests
package/dist/cli.js CHANGED
@@ -1433,7 +1433,7 @@ function parseForceFlag(args) {
1433
1433
  async function confirmAndDeleteStaleFiles(staleFiles, force) {
1434
1434
  if (staleFiles.length === 0)
1435
1435
  return { deleted: 0, skipped: 0, filesDeleted: [] };
1436
- if (!force && !process.stdout.isTTY) {
1436
+ if (!force && !process.stdin.isTTY) {
1437
1437
  console.log(`⚠️ ${staleFiles.length} stale file(s) not deleted (non-interactive shell). Re-run with --force to delete.`);
1438
1438
  return { deleted: 0, skipped: staleFiles.length, filesDeleted: [] };
1439
1439
  }
@@ -2712,7 +2712,7 @@ function emitIncludeResolver(graph, useJsExtensions) {
2712
2712
  const edges = graph[table] || {};
2713
2713
  const edgeEntries = Object.entries(edges);
2714
2714
  if (edgeEntries.length === 0) {
2715
- out += `export type ${Type}WithIncludes<TInclude extends ${Type}IncludeSpec> = Select${Type};
2715
+ out += `export type ${Type}WithIncludes<_TInclude extends ${Type}IncludeSpec> = Select${Type};
2716
2716
 
2717
2717
  `;
2718
2718
  continue;
@@ -3343,15 +3343,19 @@ function emitClient(table, graph, opts, model) {
3343
3343
  skipJunctionTables: opts.skipJunctionTables ?? true
3344
3344
  }, allTables);
3345
3345
  const importedTypes = new Set;
3346
+ const usedIncludeSpecTypes = new Set([table.name]);
3346
3347
  importedTypes.add(table.name);
3347
3348
  for (const method of includeMethods) {
3348
3349
  for (const target of method.targets) {
3349
3350
  importedTypes.add(target);
3350
3351
  }
3352
+ const pattern = analyzeIncludeSpec(method.includeSpec);
3353
+ if (pattern.type === "nested" && method.targets[0]) {
3354
+ usedIncludeSpecTypes.add(method.targets[0]);
3355
+ }
3351
3356
  }
3352
3357
  const typeImports = `import type { Insert${Type}, Update${Type}, Select${Type} } from "./types/${table.name}${ext}";`;
3353
- const includeSpecTypes = [table.name, ...Array.from(importedTypes).filter((t) => t !== table.name)];
3354
- const includeSpecImport = `import type { ${includeSpecTypes.map((t) => `${pascal(t)}IncludeSpec`).join(", ")} } from "./include-spec${ext}";`;
3358
+ const includeSpecImport = `import type { ${Array.from(usedIncludeSpecTypes).map((t) => `${pascal(t)}IncludeSpec`).join(", ")} } from "./include-spec${ext}";`;
3355
3359
  const includeResolverImport = `import type { ${Type}WithIncludes } from "./include-resolver${ext}";`;
3356
3360
  const otherTableImports = [];
3357
3361
  for (const target of Array.from(importedTypes)) {
@@ -5566,8 +5570,6 @@ function emitCoreOperations() {
5566
5570
  * These functions handle the actual database logic and can be used by any framework adapter.
5567
5571
  */
5568
5572
 
5569
- import type { z } from "zod";
5570
-
5571
5573
  export interface DatabaseClient {
5572
5574
  query: (text: string, params?: any[]) => Promise<{ rows: any[] }>;
5573
5575
  }
package/dist/index.js CHANGED
@@ -1432,7 +1432,7 @@ function parseForceFlag(args) {
1432
1432
  async function confirmAndDeleteStaleFiles(staleFiles, force) {
1433
1433
  if (staleFiles.length === 0)
1434
1434
  return { deleted: 0, skipped: 0, filesDeleted: [] };
1435
- if (!force && !process.stdout.isTTY) {
1435
+ if (!force && !process.stdin.isTTY) {
1436
1436
  console.log(`⚠️ ${staleFiles.length} stale file(s) not deleted (non-interactive shell). Re-run with --force to delete.`);
1437
1437
  return { deleted: 0, skipped: staleFiles.length, filesDeleted: [] };
1438
1438
  }
@@ -1733,7 +1733,7 @@ function emitIncludeResolver(graph, useJsExtensions) {
1733
1733
  const edges = graph[table] || {};
1734
1734
  const edgeEntries = Object.entries(edges);
1735
1735
  if (edgeEntries.length === 0) {
1736
- out += `export type ${Type}WithIncludes<TInclude extends ${Type}IncludeSpec> = Select${Type};
1736
+ out += `export type ${Type}WithIncludes<_TInclude extends ${Type}IncludeSpec> = Select${Type};
1737
1737
 
1738
1738
  `;
1739
1739
  continue;
@@ -2364,15 +2364,19 @@ function emitClient(table, graph, opts, model) {
2364
2364
  skipJunctionTables: opts.skipJunctionTables ?? true
2365
2365
  }, allTables);
2366
2366
  const importedTypes = new Set;
2367
+ const usedIncludeSpecTypes = new Set([table.name]);
2367
2368
  importedTypes.add(table.name);
2368
2369
  for (const method of includeMethods) {
2369
2370
  for (const target of method.targets) {
2370
2371
  importedTypes.add(target);
2371
2372
  }
2373
+ const pattern = analyzeIncludeSpec(method.includeSpec);
2374
+ if (pattern.type === "nested" && method.targets[0]) {
2375
+ usedIncludeSpecTypes.add(method.targets[0]);
2376
+ }
2372
2377
  }
2373
2378
  const typeImports = `import type { Insert${Type}, Update${Type}, Select${Type} } from "./types/${table.name}${ext}";`;
2374
- const includeSpecTypes = [table.name, ...Array.from(importedTypes).filter((t) => t !== table.name)];
2375
- const includeSpecImport = `import type { ${includeSpecTypes.map((t) => `${pascal(t)}IncludeSpec`).join(", ")} } from "./include-spec${ext}";`;
2379
+ const includeSpecImport = `import type { ${Array.from(usedIncludeSpecTypes).map((t) => `${pascal(t)}IncludeSpec`).join(", ")} } from "./include-spec${ext}";`;
2376
2380
  const includeResolverImport = `import type { ${Type}WithIncludes } from "./include-resolver${ext}";`;
2377
2381
  const otherTableImports = [];
2378
2382
  for (const target of Array.from(importedTypes)) {
@@ -4587,8 +4591,6 @@ function emitCoreOperations() {
4587
4591
  * These functions handle the actual database logic and can be used by any framework adapter.
4588
4592
  */
4589
4593
 
4590
- import type { z } from "zod";
4591
-
4592
4594
  export interface DatabaseClient {
4593
4595
  query: (text: string, params?: any[]) => Promise<{ rows: any[] }>;
4594
4596
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "postgresdk",
3
- "version": "0.18.28",
3
+ "version": "0.18.30",
4
4
  "description": "Generate a typed server/client SDK from a Postgres schema (includes, Zod, Hono).",
5
5
  "type": "module",
6
6
  "bin": {