postgresdk 0.18.25 → 0.18.27

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
@@ -515,6 +515,19 @@ async function ensureDirs(dirs) {
515
515
  for (const d of dirs)
516
516
  await mkdir(d, { recursive: true });
517
517
  }
518
+ async function collectDirsRecursively(root) {
519
+ if (!existsSync(root))
520
+ return [];
521
+ const dirs = [root];
522
+ const entries = await readdir(root, { withFileTypes: true });
523
+ for (const entry of entries) {
524
+ if (!entry.isDirectory())
525
+ continue;
526
+ const sub = join(root, entry.name);
527
+ dirs.push(...await collectDirsRecursively(sub));
528
+ }
529
+ return dirs;
530
+ }
518
531
  async function deleteStaleFiles(generatedPaths, dirsToScan) {
519
532
  let deleted = 0;
520
533
  const filesDeleted = [];
@@ -2328,8 +2341,9 @@ Options:`);
2328
2341
  let filesWritten = 0;
2329
2342
  let filesUnchanged = 0;
2330
2343
  const changedFiles = [];
2344
+ const resolvedOutput = resolve2(config.output);
2331
2345
  for (const [path, content] of Object.entries(sdk.files)) {
2332
- const fullPath = join3(config.output, path);
2346
+ const fullPath = join3(resolvedOutput, path);
2333
2347
  await mkdir2(dirname3(fullPath), { recursive: true });
2334
2348
  let shouldWrite = true;
2335
2349
  if (existsSync4(fullPath)) {
@@ -2346,7 +2360,13 @@ Options:`);
2346
2360
  console.log(` ✓ ${path}`);
2347
2361
  }
2348
2362
  }
2349
- const metadataPath = join3(config.output, ".postgresdk.json");
2363
+ const generatedPaths = new Set(Object.keys(sdk.files).map((p) => join3(resolvedOutput, p)));
2364
+ const dirsToScan = await collectDirsRecursively(resolvedOutput);
2365
+ const deleteResult = await deleteStaleFiles(generatedPaths, dirsToScan);
2366
+ for (const f of deleteResult.filesDeleted) {
2367
+ console.log(` ✗ ${f}`);
2368
+ }
2369
+ const metadataPath = join3(resolvedOutput, ".postgresdk.json");
2350
2370
  const metadata = {
2351
2371
  version: sdk.version,
2352
2372
  pulledFrom: config.from
@@ -2361,18 +2381,27 @@ Options:`);
2361
2381
  if (metadataChanged) {
2362
2382
  await writeFile2(metadataPath, JSON.stringify(metadata, null, 2));
2363
2383
  }
2364
- if (filesWritten === 0 && !metadataChanged) {
2384
+ if (filesWritten === 0 && !metadataChanged && deleteResult.deleted === 0) {
2365
2385
  console.log(`✅ SDK up-to-date (${filesUnchanged} files unchanged)`);
2366
2386
  } else {
2387
+ const parts = [];
2388
+ if (filesWritten > 0)
2389
+ parts.push(`updated ${filesWritten} files`);
2390
+ if (deleteResult.deleted > 0)
2391
+ parts.push(`deleted ${deleteResult.deleted} stale files`);
2392
+ if (filesUnchanged > 0)
2393
+ parts.push(`${filesUnchanged} unchanged`);
2367
2394
  console.log(`✅ SDK pulled successfully to ${config.output}`);
2368
- console.log(` Updated: ${filesWritten} files, Unchanged: ${filesUnchanged} files`);
2395
+ console.log(` ${parts.join(", ")}`);
2369
2396
  }
2370
2397
  } catch (err) {
2371
2398
  console.error(`❌ Pull failed:`, err);
2372
2399
  process.exit(1);
2373
2400
  }
2374
2401
  }
2375
- var init_cli_pull = () => {};
2402
+ var init_cli_pull = __esm(() => {
2403
+ init_utils();
2404
+ });
2376
2405
 
2377
2406
  // src/index.ts
2378
2407
  var import_config = __toESM(require_config(), 1);
@@ -3107,7 +3136,8 @@ ${hasAuth ? `
3107
3136
  result.data,
3108
3137
  result.includeSpec,
3109
3138
  deps.pg,
3110
- ${opts.includeMethodsDepth}
3139
+ ${opts.includeMethodsDepth},
3140
+ body.data.includeSoftDeleted ?? false
3111
3141
  );
3112
3142
  return c.json({
3113
3143
  data: stitched,
@@ -4430,7 +4460,8 @@ export async function loadIncludes(
4430
4460
  parents: any[],
4431
4461
  spec: IncludeSpec | undefined,
4432
4462
  pg: { query: (text: string, params?: any[]) => Promise<{ rows: any[] }> },
4433
- maxDepth: number = ${maxDepth}
4463
+ maxDepth: number = ${maxDepth},
4464
+ includeSoftDeleted: boolean = false
4434
4465
  ) {
4435
4466
  try {
4436
4467
  if (!spec || !parents.length) return parents;
@@ -4550,7 +4581,7 @@ export async function loadIncludes(
4550
4581
  const pkCols = pkOf(target);
4551
4582
  const where = buildOrAndPredicate(pkCols, tuples.length, 1);
4552
4583
  const params = tuples.flat();
4553
- const sql = \`SELECT * FROM "\${target}" WHERE (\${where})\${softDeleteFilter(target)}\`;
4584
+ const sql = \`SELECT * FROM "\${target}" WHERE (\${where})\${includeSoftDeleted ? "" : softDeleteFilter(target)}\`;
4554
4585
  log.debug("belongsTo SQL", { curr, target, key, sql, paramsCount: params.length });
4555
4586
  const { rows: targets } = await pg.query(sql, params);
4556
4587
 
@@ -4577,7 +4608,7 @@ export async function loadIncludes(
4577
4608
  // SELECT target WHERE fk IN tuples
4578
4609
  const where = buildOrAndPredicate(fk.from, tuples.length, 1);
4579
4610
  const params = tuples.flat();
4580
- const sql = \`SELECT * FROM "\${target}" WHERE (\${where})\${softDeleteFilter(target)}\`;
4611
+ const sql = \`SELECT * FROM "\${target}" WHERE (\${where})\${includeSoftDeleted ? "" : softDeleteFilter(target)}\`;
4581
4612
  log.debug("hasOne SQL", { curr, target, key, sql, paramsCount: params.length });
4582
4613
  const { rows: targets } = await pg.query(sql, params);
4583
4614
 
@@ -4604,7 +4635,7 @@ export async function loadIncludes(
4604
4635
  const params = tuples.flat();
4605
4636
 
4606
4637
  // Build SQL with optional ORDER BY, LIMIT, OFFSET
4607
- let sql = \`SELECT * FROM "\${target}" WHERE (\${where})\${softDeleteFilter(target)}\`;
4638
+ let sql = \`SELECT * FROM "\${target}" WHERE (\${where})\${includeSoftDeleted ? "" : softDeleteFilter(target)}\`;
4608
4639
 
4609
4640
  // If limit/offset are needed, use window functions to limit per parent
4610
4641
  if (options.limit !== undefined || options.offset !== undefined) {
@@ -4620,7 +4651,7 @@ export async function loadIncludes(
4620
4651
  SELECT * FROM (
4621
4652
  SELECT *, ROW_NUMBER() OVER (PARTITION BY \${partitionCols} \${orderByClause}) as __rn
4622
4653
  FROM "\${target}"
4623
- WHERE (\${where})\${softDeleteFilter(target)}
4654
+ WHERE (\${where})\${includeSoftDeleted ? "" : softDeleteFilter(target)}
4624
4655
  ) __sub
4625
4656
  WHERE __rn > \${offset} AND __rn <= \${offset + limit}
4626
4657
  \`;
@@ -4684,7 +4715,7 @@ export async function loadIncludes(
4684
4715
  \${toCurr.from.map((c: string) => \`j."\${c}"\`).join(' || \\',\\' || ')} as __parent_fk
4685
4716
  FROM "\${via}" j
4686
4717
  INNER JOIN "\${target}" t ON \${joinConditions}
4687
- WHERE (\${whereVia})\${softDeleteFilter(target, "t")}
4718
+ WHERE (\${whereVia})\${includeSoftDeleted ? "" : softDeleteFilter(target, "t")}
4688
4719
  ) __numbered
4689
4720
  WHERE __numbered.__rn > \${offset} AND __numbered.__rn <= \${offset + limit}
4690
4721
  \`;
@@ -4728,7 +4759,7 @@ export async function loadIncludes(
4728
4759
  // 2) Load targets by distinct target fk tuples in junction
4729
4760
  const tTuples = distinctTuples(jrows, toTarget.from);
4730
4761
  const whereT = buildOrAndPredicate(pkOf(target), tTuples.length, 1);
4731
- const sqlT = \`SELECT * FROM "\${target}" WHERE (\${whereT})\${softDeleteFilter(target)}\`;
4762
+ const sqlT = \`SELECT * FROM "\${target}" WHERE (\${whereT})\${includeSoftDeleted ? "" : softDeleteFilter(target)}\`;
4732
4763
  const paramsT = tTuples.flat();
4733
4764
  log.debug("manyToMany target SQL", { curr, target, via, key, sql: sqlT, paramsCount: paramsT.length });
4734
4765
  const { rows: targets } = await pg.query(sqlT, paramsT);
package/dist/index.js CHANGED
@@ -514,6 +514,19 @@ async function ensureDirs(dirs) {
514
514
  for (const d of dirs)
515
515
  await mkdir(d, { recursive: true });
516
516
  }
517
+ async function collectDirsRecursively(root) {
518
+ if (!existsSync(root))
519
+ return [];
520
+ const dirs = [root];
521
+ const entries = await readdir(root, { withFileTypes: true });
522
+ for (const entry of entries) {
523
+ if (!entry.isDirectory())
524
+ continue;
525
+ const sub = join(root, entry.name);
526
+ dirs.push(...await collectDirsRecursively(sub));
527
+ }
528
+ return dirs;
529
+ }
517
530
  async function deleteStaleFiles(generatedPaths, dirsToScan) {
518
531
  let deleted = 0;
519
532
  const filesDeleted = [];
@@ -2146,7 +2159,8 @@ ${hasAuth ? `
2146
2159
  result.data,
2147
2160
  result.includeSpec,
2148
2161
  deps.pg,
2149
- ${opts.includeMethodsDepth}
2162
+ ${opts.includeMethodsDepth},
2163
+ body.data.includeSoftDeleted ?? false
2150
2164
  );
2151
2165
  return c.json({
2152
2166
  data: stitched,
@@ -3469,7 +3483,8 @@ export async function loadIncludes(
3469
3483
  parents: any[],
3470
3484
  spec: IncludeSpec | undefined,
3471
3485
  pg: { query: (text: string, params?: any[]) => Promise<{ rows: any[] }> },
3472
- maxDepth: number = ${maxDepth}
3486
+ maxDepth: number = ${maxDepth},
3487
+ includeSoftDeleted: boolean = false
3473
3488
  ) {
3474
3489
  try {
3475
3490
  if (!spec || !parents.length) return parents;
@@ -3589,7 +3604,7 @@ export async function loadIncludes(
3589
3604
  const pkCols = pkOf(target);
3590
3605
  const where = buildOrAndPredicate(pkCols, tuples.length, 1);
3591
3606
  const params = tuples.flat();
3592
- const sql = \`SELECT * FROM "\${target}" WHERE (\${where})\${softDeleteFilter(target)}\`;
3607
+ const sql = \`SELECT * FROM "\${target}" WHERE (\${where})\${includeSoftDeleted ? "" : softDeleteFilter(target)}\`;
3593
3608
  log.debug("belongsTo SQL", { curr, target, key, sql, paramsCount: params.length });
3594
3609
  const { rows: targets } = await pg.query(sql, params);
3595
3610
 
@@ -3616,7 +3631,7 @@ export async function loadIncludes(
3616
3631
  // SELECT target WHERE fk IN tuples
3617
3632
  const where = buildOrAndPredicate(fk.from, tuples.length, 1);
3618
3633
  const params = tuples.flat();
3619
- const sql = \`SELECT * FROM "\${target}" WHERE (\${where})\${softDeleteFilter(target)}\`;
3634
+ const sql = \`SELECT * FROM "\${target}" WHERE (\${where})\${includeSoftDeleted ? "" : softDeleteFilter(target)}\`;
3620
3635
  log.debug("hasOne SQL", { curr, target, key, sql, paramsCount: params.length });
3621
3636
  const { rows: targets } = await pg.query(sql, params);
3622
3637
 
@@ -3643,7 +3658,7 @@ export async function loadIncludes(
3643
3658
  const params = tuples.flat();
3644
3659
 
3645
3660
  // Build SQL with optional ORDER BY, LIMIT, OFFSET
3646
- let sql = \`SELECT * FROM "\${target}" WHERE (\${where})\${softDeleteFilter(target)}\`;
3661
+ let sql = \`SELECT * FROM "\${target}" WHERE (\${where})\${includeSoftDeleted ? "" : softDeleteFilter(target)}\`;
3647
3662
 
3648
3663
  // If limit/offset are needed, use window functions to limit per parent
3649
3664
  if (options.limit !== undefined || options.offset !== undefined) {
@@ -3659,7 +3674,7 @@ export async function loadIncludes(
3659
3674
  SELECT * FROM (
3660
3675
  SELECT *, ROW_NUMBER() OVER (PARTITION BY \${partitionCols} \${orderByClause}) as __rn
3661
3676
  FROM "\${target}"
3662
- WHERE (\${where})\${softDeleteFilter(target)}
3677
+ WHERE (\${where})\${includeSoftDeleted ? "" : softDeleteFilter(target)}
3663
3678
  ) __sub
3664
3679
  WHERE __rn > \${offset} AND __rn <= \${offset + limit}
3665
3680
  \`;
@@ -3723,7 +3738,7 @@ export async function loadIncludes(
3723
3738
  \${toCurr.from.map((c: string) => \`j."\${c}"\`).join(' || \\',\\' || ')} as __parent_fk
3724
3739
  FROM "\${via}" j
3725
3740
  INNER JOIN "\${target}" t ON \${joinConditions}
3726
- WHERE (\${whereVia})\${softDeleteFilter(target, "t")}
3741
+ WHERE (\${whereVia})\${includeSoftDeleted ? "" : softDeleteFilter(target, "t")}
3727
3742
  ) __numbered
3728
3743
  WHERE __numbered.__rn > \${offset} AND __numbered.__rn <= \${offset + limit}
3729
3744
  \`;
@@ -3767,7 +3782,7 @@ export async function loadIncludes(
3767
3782
  // 2) Load targets by distinct target fk tuples in junction
3768
3783
  const tTuples = distinctTuples(jrows, toTarget.from);
3769
3784
  const whereT = buildOrAndPredicate(pkOf(target), tTuples.length, 1);
3770
- const sqlT = \`SELECT * FROM "\${target}" WHERE (\${whereT})\${softDeleteFilter(target)}\`;
3785
+ const sqlT = \`SELECT * FROM "\${target}" WHERE (\${whereT})\${includeSoftDeleted ? "" : softDeleteFilter(target)}\`;
3771
3786
  const paramsT = tTuples.flat();
3772
3787
  log.debug("manyToMany target SQL", { curr, target, via, key, sql: sqlT, paramsCount: paramsT.length });
3773
3788
  const { rows: targets } = await pg.query(sqlT, paramsT);
package/dist/utils.d.ts CHANGED
@@ -20,6 +20,11 @@ export declare function writeFilesIfChanged(files: Array<{
20
20
  */
21
21
  export declare function hashContent(content: string): string;
22
22
  export declare function ensureDirs(dirs: string[]): Promise<void>;
23
+ /**
24
+ * Recursively collect all subdirectory paths under `root`, including root itself.
25
+ * Returns an empty array if `root` does not exist.
26
+ */
27
+ export declare function collectDirsRecursively(root: string): Promise<string[]>;
23
28
  /**
24
29
  * Delete files in the given directories that are not in the set of generated paths.
25
30
  * Used to remove stale files for tables that no longer exist in the schema.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "postgresdk",
3
- "version": "0.18.25",
3
+ "version": "0.18.27",
4
4
  "description": "Generate a typed server/client SDK from a Postgres schema (includes, Zod, Hono).",
5
5
  "type": "module",
6
6
  "bin": {