@deepagents/text2sql 7.0.1 → 7.1.0

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.
Files changed (162) hide show
  1. package/README.md +3 -2
  2. package/dist/bin/sql.js +57 -32
  3. package/dist/index.js +793 -498
  4. package/dist/index.js.map +4 -4
  5. package/dist/lib/adapters/adapter.d.ts +23 -1
  6. package/dist/lib/adapters/adapter.d.ts.map +1 -1
  7. package/dist/lib/adapters/bigquery/bigquery-fk.d.ts +0 -11
  8. package/dist/lib/adapters/bigquery/bigquery-fk.d.ts.map +1 -1
  9. package/dist/lib/adapters/bigquery/bigquery-rows.d.ts +22 -0
  10. package/dist/lib/adapters/bigquery/bigquery-rows.d.ts.map +1 -0
  11. package/dist/lib/adapters/bigquery/bigquery.d.ts +1 -1
  12. package/dist/lib/adapters/bigquery/bigquery.d.ts.map +1 -1
  13. package/dist/lib/adapters/bigquery/constraint.bigquery.grounding.d.ts.map +1 -1
  14. package/dist/lib/adapters/bigquery/index.d.ts +6 -13
  15. package/dist/lib/adapters/bigquery/index.d.ts.map +1 -1
  16. package/dist/lib/adapters/bigquery/index.js +244 -51
  17. package/dist/lib/adapters/bigquery/index.js.map +4 -4
  18. package/dist/lib/adapters/bigquery/indexes.bigquery.grounding.d.ts.map +1 -1
  19. package/dist/lib/adapters/bigquery/row-count.bigquery.grounding.d.ts.map +1 -1
  20. package/dist/lib/adapters/bigquery/table.bigquery.grounding.d.ts.map +1 -1
  21. package/dist/lib/adapters/bigquery/view.bigquery.grounding.d.ts.map +1 -1
  22. package/dist/lib/adapters/clickhouse/clickhouse-rows.d.ts +7 -0
  23. package/dist/lib/adapters/clickhouse/clickhouse-rows.d.ts.map +1 -0
  24. package/dist/lib/adapters/clickhouse/clickhouse.d.ts +1 -1
  25. package/dist/lib/adapters/clickhouse/clickhouse.d.ts.map +1 -1
  26. package/dist/lib/adapters/clickhouse/constraint.clickhouse.grounding.d.ts.map +1 -1
  27. package/dist/lib/adapters/clickhouse/index.js +133 -44
  28. package/dist/lib/adapters/clickhouse/index.js.map +4 -4
  29. package/dist/lib/adapters/clickhouse/indexes.clickhouse.grounding.d.ts.map +1 -1
  30. package/dist/lib/adapters/clickhouse/info.clickhouse.grounding.d.ts.map +1 -1
  31. package/dist/lib/adapters/clickhouse/row-count.clickhouse.grounding.d.ts.map +1 -1
  32. package/dist/lib/adapters/clickhouse/table.clickhouse.grounding.d.ts.map +1 -1
  33. package/dist/lib/adapters/clickhouse/view.clickhouse.grounding.d.ts.map +1 -1
  34. package/dist/lib/adapters/duckdb/duckdb.d.ts +1 -1
  35. package/dist/lib/adapters/duckdb/duckdb.d.ts.map +1 -1
  36. package/dist/lib/adapters/duckdb/duckdb.groundings.d.ts.map +1 -1
  37. package/dist/lib/adapters/duckdb/index.d.ts +8 -10
  38. package/dist/lib/adapters/duckdb/index.d.ts.map +1 -1
  39. package/dist/lib/adapters/duckdb/index.js +1549 -1412
  40. package/dist/lib/adapters/duckdb/index.js.map +4 -4
  41. package/dist/lib/adapters/groundings/index.js.map +1 -1
  42. package/dist/lib/adapters/groundings/rows.d.ts +32 -0
  43. package/dist/lib/adapters/groundings/rows.d.ts.map +1 -0
  44. package/dist/lib/adapters/mysql/column-stats.mysql.grounding.d.ts.map +1 -1
  45. package/dist/lib/adapters/mysql/column-values.mysql.grounding.d.ts.map +1 -1
  46. package/dist/lib/adapters/mysql/constraint.mysql.grounding.d.ts.map +1 -1
  47. package/dist/lib/adapters/mysql/index.d.ts +2 -4
  48. package/dist/lib/adapters/mysql/index.d.ts.map +1 -1
  49. package/dist/lib/adapters/mysql/index.js +230 -76
  50. package/dist/lib/adapters/mysql/index.js.map +4 -4
  51. package/dist/lib/adapters/mysql/indexes.mysql.grounding.d.ts.map +1 -1
  52. package/dist/lib/adapters/mysql/info.mysql.grounding.d.ts.map +1 -1
  53. package/dist/lib/adapters/mysql/mysql-rows.d.ts +11 -0
  54. package/dist/lib/adapters/mysql/mysql-rows.d.ts.map +1 -0
  55. package/dist/lib/adapters/mysql/mysql.d.ts +1 -1
  56. package/dist/lib/adapters/mysql/mysql.d.ts.map +1 -1
  57. package/dist/lib/adapters/mysql/row-count.mysql.grounding.d.ts.map +1 -1
  58. package/dist/lib/adapters/mysql/table.mysql.grounding.d.ts +3 -2
  59. package/dist/lib/adapters/mysql/table.mysql.grounding.d.ts.map +1 -1
  60. package/dist/lib/adapters/mysql/view.mysql.grounding.d.ts +2 -2
  61. package/dist/lib/adapters/mysql/view.mysql.grounding.d.ts.map +1 -1
  62. package/dist/lib/adapters/postgres/column-stats.postgres.grounding.d.ts.map +1 -1
  63. package/dist/lib/adapters/postgres/column-values.postgres.grounding.d.ts.map +1 -1
  64. package/dist/lib/adapters/postgres/constraint.postgres.grounding.d.ts.map +1 -1
  65. package/dist/lib/adapters/postgres/index.d.ts +2 -4
  66. package/dist/lib/adapters/postgres/index.d.ts.map +1 -1
  67. package/dist/lib/adapters/postgres/index.js +266 -487
  68. package/dist/lib/adapters/postgres/index.js.map +4 -4
  69. package/dist/lib/adapters/postgres/indexes.postgres.grounding.d.ts +1 -5
  70. package/dist/lib/adapters/postgres/indexes.postgres.grounding.d.ts.map +1 -1
  71. package/dist/lib/adapters/postgres/info.postgres.grounding.d.ts.map +1 -1
  72. package/dist/lib/adapters/postgres/postgres-rows.d.ts +7 -0
  73. package/dist/lib/adapters/postgres/postgres-rows.d.ts.map +1 -0
  74. package/dist/lib/adapters/postgres/postgres.d.ts +6 -1
  75. package/dist/lib/adapters/postgres/postgres.d.ts.map +1 -1
  76. package/dist/lib/adapters/postgres/row-count.postgres.grounding.d.ts.map +1 -1
  77. package/dist/lib/adapters/postgres/table.postgres.grounding.d.ts +5 -4
  78. package/dist/lib/adapters/postgres/table.postgres.grounding.d.ts.map +1 -1
  79. package/dist/lib/adapters/postgres/view.postgres.grounding.d.ts +3 -3
  80. package/dist/lib/adapters/postgres/view.postgres.grounding.d.ts.map +1 -1
  81. package/dist/lib/adapters/posthog/definitions.posthog.grounding.d.ts.map +1 -1
  82. package/dist/lib/adapters/posthog/index.d.ts +4 -5
  83. package/dist/lib/adapters/posthog/index.d.ts.map +1 -1
  84. package/dist/lib/adapters/posthog/index.js +349 -287
  85. package/dist/lib/adapters/posthog/index.js.map +4 -4
  86. package/dist/lib/adapters/posthog/posthog.d.ts +2 -2
  87. package/dist/lib/adapters/posthog/posthog.d.ts.map +1 -1
  88. package/dist/lib/adapters/posthog/posthog.sql-policy.d.ts.map +1 -1
  89. package/dist/lib/adapters/posthog/schema.posthog.grounding.d.ts.map +1 -1
  90. package/dist/lib/adapters/posthog/transport.d.ts.map +1 -1
  91. package/dist/lib/adapters/posthog/types.d.ts +16 -6
  92. package/dist/lib/adapters/posthog/types.d.ts.map +1 -1
  93. package/dist/lib/adapters/spreadsheet/index.js +113 -34
  94. package/dist/lib/adapters/spreadsheet/index.js.map +4 -4
  95. package/dist/lib/adapters/sqlite/column-stats.sqlite.grounding.d.ts.map +1 -1
  96. package/dist/lib/adapters/sqlite/column-values.sqlite.grounding.d.ts.map +1 -1
  97. package/dist/lib/adapters/sqlite/constraint.sqlite.grounding.d.ts.map +1 -1
  98. package/dist/lib/adapters/sqlite/index.js +136 -49
  99. package/dist/lib/adapters/sqlite/index.js.map +4 -4
  100. package/dist/lib/adapters/sqlite/indexes.sqlite.grounding.d.ts.map +1 -1
  101. package/dist/lib/adapters/sqlite/info.sqlite.grounding.d.ts.map +1 -1
  102. package/dist/lib/adapters/sqlite/row-count.sqlite.grounding.d.ts.map +1 -1
  103. package/dist/lib/adapters/sqlite/sqlite-rows.d.ts +41 -0
  104. package/dist/lib/adapters/sqlite/sqlite-rows.d.ts.map +1 -0
  105. package/dist/lib/adapters/sqlite/sqlite.d.ts +1 -1
  106. package/dist/lib/adapters/sqlite/sqlite.d.ts.map +1 -1
  107. package/dist/lib/adapters/sqlite/table.sqlite.grounding.d.ts.map +1 -1
  108. package/dist/lib/adapters/sqlite/view.sqlite.grounding.d.ts.map +1 -1
  109. package/dist/lib/adapters/sqlserver/column-stats.sqlserver.grounding.d.ts.map +1 -1
  110. package/dist/lib/adapters/sqlserver/column-values.sqlserver.grounding.d.ts.map +1 -1
  111. package/dist/lib/adapters/sqlserver/constraint.sqlserver.grounding.d.ts.map +1 -1
  112. package/dist/lib/adapters/sqlserver/index.d.ts +2 -4
  113. package/dist/lib/adapters/sqlserver/index.d.ts.map +1 -1
  114. package/dist/lib/adapters/sqlserver/index.js +223 -455
  115. package/dist/lib/adapters/sqlserver/index.js.map +4 -4
  116. package/dist/lib/adapters/sqlserver/indexes.sqlserver.grounding.d.ts +1 -5
  117. package/dist/lib/adapters/sqlserver/indexes.sqlserver.grounding.d.ts.map +1 -1
  118. package/dist/lib/adapters/sqlserver/info.sqlserver.grounding.d.ts.map +1 -1
  119. package/dist/lib/adapters/sqlserver/row-count.sqlserver.grounding.d.ts.map +1 -1
  120. package/dist/lib/adapters/sqlserver/sqlserver-rows.d.ts +7 -0
  121. package/dist/lib/adapters/sqlserver/sqlserver-rows.d.ts.map +1 -0
  122. package/dist/lib/adapters/sqlserver/sqlserver.d.ts +6 -1
  123. package/dist/lib/adapters/sqlserver/sqlserver.d.ts.map +1 -1
  124. package/dist/lib/adapters/sqlserver/table.sqlserver.grounding.d.ts +4 -3
  125. package/dist/lib/adapters/sqlserver/table.sqlserver.grounding.d.ts.map +1 -1
  126. package/dist/lib/adapters/sqlserver/view.sqlserver.grounding.d.ts +3 -3
  127. package/dist/lib/adapters/sqlserver/view.sqlserver.grounding.d.ts.map +1 -1
  128. package/dist/lib/agents/sql-transform-plugins.d.ts.map +1 -1
  129. package/dist/lib/checkpoint.d.ts +34 -21
  130. package/dist/lib/checkpoint.d.ts.map +1 -1
  131. package/dist/lib/file-cache.d.ts +6 -1
  132. package/dist/lib/file-cache.d.ts.map +1 -1
  133. package/dist/lib/fs/columns.d.ts +14 -0
  134. package/dist/lib/fs/columns.d.ts.map +1 -0
  135. package/dist/lib/fs/mssql/mssql-fs.d.ts +4 -4
  136. package/dist/lib/fs/mssql/mssql-fs.d.ts.map +1 -1
  137. package/dist/lib/fs/postgres/postgres-fs.d.ts +4 -4
  138. package/dist/lib/fs/postgres/postgres-fs.d.ts.map +1 -1
  139. package/dist/lib/fs/sqlite/sqlite-fs.d.ts +4 -4
  140. package/dist/lib/fs/sqlite/sqlite-fs.d.ts.map +1 -1
  141. package/dist/lib/index-cache.d.ts +4 -3
  142. package/dist/lib/index-cache.d.ts.map +1 -1
  143. package/dist/lib/sql.d.ts.map +1 -1
  144. package/dist/lib/synthesis/decorators/deduplicated-producer.d.ts +1 -2
  145. package/dist/lib/synthesis/decorators/deduplicated-producer.d.ts.map +1 -1
  146. package/dist/lib/synthesis/decorators/filtered-producer.d.ts +0 -2
  147. package/dist/lib/synthesis/decorators/filtered-producer.d.ts.map +1 -1
  148. package/dist/lib/synthesis/decorators/validated-producer.d.ts +1 -3
  149. package/dist/lib/synthesis/decorators/validated-producer.d.ts.map +1 -1
  150. package/dist/lib/synthesis/extractors/base-contextual-extractor.d.ts.map +1 -1
  151. package/dist/lib/synthesis/extractors/message-extractor.d.ts.map +1 -1
  152. package/dist/lib/synthesis/extractors/tool-input.d.ts +6 -0
  153. package/dist/lib/synthesis/extractors/tool-input.d.ts.map +1 -0
  154. package/dist/lib/synthesis/index.js +124 -114
  155. package/dist/lib/synthesis/index.js.map +4 -4
  156. package/dist/lib/synthesis/synthesizers/breadth-evolver.d.ts +0 -2
  157. package/dist/lib/synthesis/synthesizers/breadth-evolver.d.ts.map +1 -1
  158. package/dist/lib/synthesis/synthesizers/depth-evolver.d.ts +0 -3
  159. package/dist/lib/synthesis/synthesizers/depth-evolver.d.ts.map +1 -1
  160. package/dist/lib/synthesis/synthesizers/schema-synthesizer.d.ts +0 -2
  161. package/dist/lib/synthesis/synthesizers/schema-synthesizer.d.ts.map +1 -1
  162. package/package.json +8 -8
package/dist/index.js CHANGED
@@ -20,6 +20,7 @@ function validateAdapterNames(names) {
20
20
 
21
21
  // packages/text2sql/src/lib/adapters/adapter.ts
22
22
  import { format as formatSql } from "sql-formatter";
23
+ import { z } from "zod";
23
24
 
24
25
  // packages/text2sql/src/lib/agents/exceptions.ts
25
26
  var sqlValidationMarker = /* @__PURE__ */ Symbol("SQLValidationError");
@@ -192,6 +193,16 @@ function createGroundingContext(options = {}) {
192
193
  }
193
194
 
194
195
  // packages/text2sql/src/lib/adapters/adapter.ts
196
+ function groundingFor(adapterType, create) {
197
+ return (adapter) => {
198
+ if (!(adapter instanceof adapterType)) {
199
+ throw new Error(
200
+ `A ${adapterType.name} grounding needs a ${adapterType.name} adapter, not ${adapter.constructor.name}.`
201
+ );
202
+ }
203
+ return create(adapter);
204
+ };
205
+ }
195
206
  var Adapter = class {
196
207
  #policyAnalyzer;
197
208
  /**
@@ -452,6 +463,40 @@ var Adapter = class {
452
463
  }
453
464
  return decoded;
454
465
  }
466
+ /**
467
+ * Run an introspection query and check every row against `row`, the shape
468
+ * the driver returns for that query. A row of any other shape throws.
469
+ */
470
+ async runQuery(sql, row) {
471
+ const rows = z.array(row).safeParse(await this.queryRows(sql));
472
+ if (!rows.success) {
473
+ throw new Error(
474
+ `${this.constructor.name} introspection query returned rows of an unexpected shape:
475
+ ${z.prettifyError(rows.error)}
476
+ SQL: ${sql.trim()}`,
477
+ { cause: rows.error }
478
+ );
479
+ }
480
+ return rows.data;
481
+ }
482
+ /**
483
+ * The rows in a driver's execute() result: the result itself when it is an
484
+ * array, otherwise the first array found at one of `paths` (dot-separated,
485
+ * so `recordsets.0` reads `result.recordsets[0]`).
486
+ */
487
+ rowsFrom(result, paths) {
488
+ if (Array.isArray(result)) return result;
489
+ for (const path7 of paths) {
490
+ const rows = path7.split(".").reduce(
491
+ (value, key) => typeof value === "object" && value !== null ? Reflect.get(value, key) : void 0,
492
+ result
493
+ );
494
+ if (Array.isArray(rows)) return rows;
495
+ }
496
+ throw new Error(
497
+ `${this.constructor.name} execute() must return an array of rows or an object holding one at ${paths.map((path7) => `result.${path7}`).join(", ")}.`
498
+ );
499
+ }
455
500
  /**
456
501
  * Convert unknown database value to number.
457
502
  * Handles number, bigint, and string types.
@@ -586,7 +631,7 @@ import {
586
631
  } from "ai";
587
632
  import dedent from "dedent";
588
633
  import pRetry from "p-retry";
589
- import z from "zod";
634
+ import z2 from "zod";
590
635
  import "@deepagents/agent";
591
636
  import {
592
637
  ContextEngine,
@@ -878,14 +923,14 @@ Question: ${options.input}
878
923
  const sqlOutput = structuredOutput({
879
924
  model,
880
925
  context,
881
- schema: z.object({
882
- result: z.union([
883
- z.object({
884
- sql: z.string().describe("The SQL query that answers the question"),
885
- reasoning: z.string().describe("The reasoning steps taken to generate the SQL")
926
+ schema: z2.object({
927
+ result: z2.union([
928
+ z2.object({
929
+ sql: z2.string().describe("The SQL query that answers the question"),
930
+ reasoning: z2.string().describe("The reasoning steps taken to generate the SQL")
886
931
  }),
887
- z.object({
888
- error: z.string().describe(
932
+ z2.object({
933
+ error: z2.string().describe(
889
934
  "Error message explaining why the question cannot be answered with the given schema"
890
935
  )
891
936
  })
@@ -936,11 +981,11 @@ Question: ${options.input}
936
981
  const forcedSqlOutput = structuredOutput({
937
982
  model,
938
983
  context,
939
- schema: z.object({
940
- sql: z.string().describe(
984
+ schema: z2.object({
985
+ sql: z2.string().describe(
941
986
  "Best-effort SQL query that answers the core intent using only available schema entities."
942
987
  ),
943
- reasoning: z.string().describe("Reasoning steps for best-effort schema mapping.")
988
+ reasoning: z2.string().describe("Reasoning steps for best-effort schema mapping.")
944
989
  })
945
990
  });
946
991
  try {
@@ -1025,17 +1070,17 @@ async function withRetry(computation, options = { retries: 3 }) {
1025
1070
  // packages/text2sql/src/lib/agents/suggestions.agents.ts
1026
1071
  import { groq as groq2 } from "@ai-sdk/groq";
1027
1072
  import dedent2 from "dedent";
1028
- import z2 from "zod";
1073
+ import z3 from "zod";
1029
1074
  import { agent, thirdPersonPrompt } from "@deepagents/agent";
1030
1075
  var suggestionsAgent = agent({
1031
1076
  name: "text2sql-suggestions",
1032
1077
  model: groq2("openai/gpt-oss-20b"),
1033
- output: z2.object({
1034
- suggestions: z2.array(
1035
- z2.object({
1036
- question: z2.string().describe("A complex, high-impact business question."),
1037
- sql: z2.string().describe("The SQL statement needed to answer the question."),
1038
- businessValue: z2.string().describe("Why the question matters to stakeholders.")
1078
+ output: z3.object({
1079
+ suggestions: z3.array(
1080
+ z3.object({
1081
+ question: z3.string().describe("A complex, high-impact business question."),
1082
+ sql: z3.string().describe("The SQL statement needed to answer the question."),
1083
+ businessValue: z3.string().describe("Why the question matters to stakeholders.")
1039
1084
  })
1040
1085
  ).min(1).max(5).describe("A set of up to two advanced question + SQL pairs.")
1041
1086
  }),
@@ -1077,6 +1122,12 @@ var suggestionsAgent = agent({
1077
1122
  // packages/text2sql/src/lib/adapter-index.ts
1078
1123
  import { fragment as fragment2 } from "@deepagents/context";
1079
1124
 
1125
+ // packages/text2sql/src/lib/index-cache.ts
1126
+ import {
1127
+ isFragment,
1128
+ isFragmentData
1129
+ } from "@deepagents/context";
1130
+
1080
1131
  // packages/text2sql/src/lib/file-cache.ts
1081
1132
  import { createHash, randomUUID } from "node:crypto";
1082
1133
  import { existsSync } from "node:fs";
@@ -1103,8 +1154,14 @@ var FileCache = class {
1103
1154
  }
1104
1155
  };
1105
1156
  var JsonCache = class extends FileCache {
1106
- constructor(watermark, baseDir) {
1157
+ #isValid;
1158
+ /**
1159
+ * @param isValid - Checks that a parsed cache file holds a T; a file that
1160
+ * fails it is read as a miss.
1161
+ */
1162
+ constructor(watermark, isValid, baseDir) {
1107
1163
  super(watermark, ".json", baseDir);
1164
+ this.#isValid = isValid;
1108
1165
  }
1109
1166
  async read() {
1110
1167
  const content = await this.get();
@@ -1112,7 +1169,8 @@ var JsonCache = class extends FileCache {
1112
1169
  return null;
1113
1170
  }
1114
1171
  try {
1115
- return JSON.parse(content);
1172
+ const value = JSON.parse(content);
1173
+ return this.#isValid(value) ? value : null;
1116
1174
  } catch {
1117
1175
  return null;
1118
1176
  }
@@ -1138,9 +1196,12 @@ var FileIndexCache = class {
1138
1196
  }
1139
1197
  #cacheFor(key) {
1140
1198
  const watermark = this.#namespace ? `${this.#namespace}-${key}` : key;
1141
- return new JsonCache(watermark, this.#dir);
1199
+ return new JsonCache(watermark, isFragmentList, this.#dir);
1142
1200
  }
1143
1201
  };
1202
+ function isFragmentList(value) {
1203
+ return Array.isArray(value) && value.every((item) => isFragment(item) && isFragmentData(item));
1204
+ }
1144
1205
 
1145
1206
  // packages/text2sql/src/lib/index-lock.ts
1146
1207
  import { createHash as createHash2 } from "node:crypto";
@@ -1371,6 +1432,20 @@ function errorMessage(error) {
1371
1432
  import { createHash as createHash3 } from "node:crypto";
1372
1433
  import { existsSync as existsSync2, readFileSync, renameSync, writeFileSync } from "node:fs";
1373
1434
  import pLimit from "p-limit";
1435
+ import z4 from "zod";
1436
+ function jsonCodec(schema) {
1437
+ return { encode: (value) => value, decode: (stored) => schema.parse(stored) };
1438
+ }
1439
+ var pointData = z4.object({
1440
+ committed: z4.boolean(),
1441
+ entries: z4.array(
1442
+ z4.object({ inputHash: z4.string(), output: z4.unknown().optional() })
1443
+ )
1444
+ });
1445
+ var checkpointFile = z4.object({
1446
+ configHash: z4.string().optional(),
1447
+ points: z4.record(z4.string(), pointData)
1448
+ });
1374
1449
  var Checkpoint = class _Checkpoint {
1375
1450
  points;
1376
1451
  path;
@@ -1389,12 +1464,12 @@ var Checkpoint = class _Checkpoint {
1389
1464
  if (existsSync2(path7)) {
1390
1465
  try {
1391
1466
  const content = readFileSync(path7, "utf-8");
1392
- const file = JSON.parse(content);
1467
+ const file = checkpointFile.parse(JSON.parse(content));
1393
1468
  if (configHash && file.configHash && file.configHash !== configHash) {
1394
1469
  console.log("\u26A0 Config changed, starting fresh");
1395
1470
  return new _Checkpoint(path7, configHash, {});
1396
1471
  }
1397
- const points = file.points ?? {};
1472
+ const points = file.points;
1398
1473
  const totalEntries = Object.values(points).reduce(
1399
1474
  (sum, p) => sum + p.entries.length,
1400
1475
  0
@@ -1415,27 +1490,20 @@ var Checkpoint = class _Checkpoint {
1415
1490
  *
1416
1491
  * @param key - Unique identifier for this computation
1417
1492
  * @param computation - Async function that produces the value
1418
- * @param codec - Optional codec for encoding/decoding non-primitive values
1493
+ * @param codec - Codec that stores the value and restores it on resume
1419
1494
  */
1420
1495
  async run(key, computation, codec) {
1421
- const point = this.point(key);
1422
- return point.through(
1423
- "single",
1424
- async () => {
1425
- const result = await computation();
1426
- return codec ? codec.encode(result) : result;
1427
- },
1428
- codec
1429
- );
1496
+ return this.point(key, codec).through("single", computation);
1430
1497
  }
1431
1498
  /**
1432
1499
  * Create a resumable checkpoint point for iterative operations.
1433
1500
  *
1434
1501
  * @param step - Unique identifier for this checkpoint point
1502
+ * @param codec - Codec that stores each output and restores it on resume
1435
1503
  */
1436
- point(step) {
1504
+ point(step, codec) {
1437
1505
  this.points[step] ??= { committed: false, entries: [] };
1438
- return new Point(this.points[step], () => this.save());
1506
+ return new Point(this.points[step], codec, () => this.save());
1439
1507
  }
1440
1508
  /**
1441
1509
  * Process each input with automatic checkpointing and concurrency.
@@ -1443,11 +1511,12 @@ var Checkpoint = class _Checkpoint {
1443
1511
  * @param step - Unique identifier for this checkpoint
1444
1512
  * @param inputs - Items to process
1445
1513
  * @param process - Function to process each input
1514
+ * @param codec - Codec that stores each output and restores it on resume
1446
1515
  * @param options - Optional settings like concurrency
1447
1516
  * @returns All outputs (use `.flat()` if outputs are arrays)
1448
1517
  */
1449
- async each(step, inputs, process, options) {
1450
- const point = this.point(step);
1518
+ async each(step, inputs, process, codec, options) {
1519
+ const point = this.point(step, codec);
1451
1520
  const limit = pLimit(options?.concurrency ?? 1);
1452
1521
  const inputArray = Array.from(inputs);
1453
1522
  await Promise.all(
@@ -1464,11 +1533,11 @@ var Checkpoint = class _Checkpoint {
1464
1533
  */
1465
1534
  getOutput() {
1466
1535
  const output = {};
1467
- for (const [key, pointData] of Object.entries(this.points)) {
1468
- if (pointData.entries.length === 1) {
1469
- output[key] = pointData.entries[0].output;
1536
+ for (const [key, pointData2] of Object.entries(this.points)) {
1537
+ if (pointData2.entries.length === 1) {
1538
+ output[key] = pointData2.entries[0].output;
1470
1539
  } else {
1471
- output[key] = pointData.entries.map((e) => e.output);
1540
+ output[key] = pointData2.entries.map((e) => e.output);
1472
1541
  }
1473
1542
  }
1474
1543
  return output;
@@ -1492,31 +1561,32 @@ function hash(value) {
1492
1561
  return createHash3("md5").update(JSON.stringify(value)).digest("hex");
1493
1562
  }
1494
1563
  var Point = class {
1495
- #cache;
1564
+ #stored;
1496
1565
  data;
1566
+ codec;
1497
1567
  persist;
1498
- constructor(data, persist) {
1499
- this.#cache = new Map(
1500
- data.entries.map((e) => [e.inputHash, e.output])
1501
- );
1568
+ constructor(data, codec, persist) {
1569
+ this.#stored = new Map(data.entries.map((e) => [e.inputHash, e.output]));
1502
1570
  this.data = data;
1571
+ this.codec = codec;
1503
1572
  this.persist = persist;
1504
1573
  }
1505
1574
  /**
1506
1575
  * Execute computation if input wasn't processed before.
1507
- * Returns cached output if input hash exists, otherwise executes, saves, and returns.
1576
+ * Returns the decoded stored output if input hash exists, otherwise
1577
+ * executes, saves the encoded output, and returns the computed value.
1508
1578
  */
1509
- async through(input, compute, codec) {
1579
+ async through(input, compute) {
1510
1580
  const inputHash = hash(input);
1511
- if (this.#cache.has(inputHash)) {
1512
- const cached = this.#cache.get(inputHash);
1513
- return codec ? codec.decode(cached) : cached;
1581
+ if (this.#stored.has(inputHash)) {
1582
+ return this.codec.decode(this.#stored.get(inputHash));
1514
1583
  }
1515
- const output = await compute();
1584
+ const value = await compute();
1585
+ const output = this.codec.encode(value);
1516
1586
  this.data.entries.push({ inputHash, output });
1517
- this.#cache.set(inputHash, output);
1587
+ this.#stored.set(inputHash, output);
1518
1588
  await this.persist();
1519
- return codec ? codec.decode(output) : output;
1589
+ return value;
1520
1590
  }
1521
1591
  /** Mark this point as complete. */
1522
1592
  async commit() {
@@ -1529,7 +1599,7 @@ var Point = class {
1529
1599
  }
1530
1600
  /** Get all outputs from this point. */
1531
1601
  values() {
1532
- return this.data.entries.map((e) => e.output);
1602
+ return this.data.entries.map((e) => this.codec.decode(e.output));
1533
1603
  }
1534
1604
  };
1535
1605
  function hashConfig(config) {
@@ -1539,11 +1609,40 @@ function hashConfig(config) {
1539
1609
  // packages/text2sql/src/lib/fs/sqlite/sqlite-fs.ts
1540
1610
  import * as path3 from "node:path";
1541
1611
  import { DatabaseSync } from "node:sqlite";
1612
+ import z6 from "zod";
1613
+
1614
+ // packages/text2sql/src/lib/fs/columns.ts
1615
+ import z5 from "zod";
1616
+ var entryType = z5.enum(["file", "directory", "symlink"]);
1617
+ var bigintColumn = z5.union([z5.number(), z5.string().regex(/^-?\d+$/)]).transform(Number);
1542
1618
 
1543
1619
  // packages/text2sql/src/lib/fs/sqlite/ddl.sqlite-fs.sql
1544
1620
  var ddl_sqlite_fs_default = "-- SQLite-based filesystem schema for artifact storage\n-- Tables: fs_entries (file/directory metadata), fs_chunks (file content)\n\n-- Performance PRAGMAs (session-level, run on each connection)\nPRAGMA journal_mode = WAL;\nPRAGMA synchronous = NORMAL;\nPRAGMA cache_size = -64000;\nPRAGMA temp_store = MEMORY;\nPRAGMA mmap_size = 268435456;\n\n-- Integrity\nPRAGMA foreign_keys = ON;\n\n-- Filesystem entries table (files, directories, symlinks)\nCREATE TABLE IF NOT EXISTS fs_entries (\n path TEXT PRIMARY KEY, -- Normalized absolute path (e.g., '/results/uuid.json')\n type TEXT NOT NULL, -- 'file' | 'directory' | 'symlink'\n mode INTEGER NOT NULL, -- Unix permissions (e.g., 0o644 = 420)\n size INTEGER NOT NULL, -- File size in bytes (0 for directories)\n mtime INTEGER NOT NULL, -- Modified time (milliseconds since epoch)\n symlinkTarget TEXT -- Target path for symlinks (NULL for files/dirs)\n);\n\nCREATE INDEX IF NOT EXISTS idx_fs_entries_type ON fs_entries(type);\n\n-- File content chunks table (for handling large files)\n-- Files are split into 1MB chunks to avoid SQLite BLOB performance issues\nCREATE TABLE IF NOT EXISTS fs_chunks (\n path TEXT NOT NULL, -- Reference to fs_entries.path\n chunkIndex INTEGER NOT NULL, -- 0-based chunk sequence\n data BLOB NOT NULL, -- Chunk content (up to 1MB default)\n PRIMARY KEY (path, chunkIndex),\n FOREIGN KEY (path) REFERENCES fs_entries(path) ON DELETE CASCADE ON UPDATE CASCADE\n);\n";
1545
1621
 
1546
1622
  // packages/text2sql/src/lib/fs/sqlite/sqlite-fs.ts
1623
+ var entryRow = z6.object({
1624
+ path: z6.string(),
1625
+ type: entryType,
1626
+ mode: z6.number(),
1627
+ size: z6.number(),
1628
+ mtime: z6.number(),
1629
+ symlinkTarget: z6.string().nullable()
1630
+ });
1631
+ var typeRow = entryRow.pick({ type: true });
1632
+ var pathRow = entryRow.pick({ path: true });
1633
+ var pathTypeRow = entryRow.pick({ path: true, type: true });
1634
+ var linkRow = z6.discriminatedUnion("type", [
1635
+ z6.object({ type: z6.literal("symlink"), symlinkTarget: z6.string() }),
1636
+ z6.object({
1637
+ type: z6.enum(["file", "directory"]),
1638
+ symlinkTarget: z6.string().nullable()
1639
+ })
1640
+ ]);
1641
+ var chunkRow = z6.object({
1642
+ chunkIndex: z6.number(),
1643
+ data: z6.instanceof(Uint8Array)
1644
+ });
1645
+ var dataRow = chunkRow.pick({ data: true });
1547
1646
  var SqliteFs = class {
1548
1647
  #db;
1549
1648
  #statements = /* @__PURE__ */ new Map();
@@ -1651,8 +1750,8 @@ var SqliteFs = class {
1651
1750
  const parent = this.#dirname(filePath);
1652
1751
  const rootPath = this.#root || "/";
1653
1752
  if (parent === rootPath || parent === "/") return;
1654
- const entry = this.#stmt("SELECT type FROM fs_entries WHERE path = ?").get(
1655
- parent
1753
+ const entry = typeRow.optional().parse(
1754
+ this.#stmt("SELECT type FROM fs_entries WHERE path = ?").get(parent)
1656
1755
  );
1657
1756
  if (!entry) {
1658
1757
  this.#ensureParentExists(parent);
@@ -1676,10 +1775,19 @@ var SqliteFs = class {
1676
1775
  ).run(filePath, Math.floor(i / this.#chunkSize), chunk);
1677
1776
  }
1678
1777
  }
1778
+ #chunks(filePath) {
1779
+ return z6.array(chunkRow).parse(
1780
+ this.#stmt("SELECT chunkIndex, data FROM fs_chunks WHERE path = ?").all(
1781
+ filePath
1782
+ )
1783
+ );
1784
+ }
1679
1785
  #readChunks(filePath) {
1680
- const rows = this.#stmt(
1681
- "SELECT data FROM fs_chunks WHERE path = ? ORDER BY chunkIndex"
1682
- ).all(filePath);
1786
+ const rows = z6.array(dataRow).parse(
1787
+ this.#stmt(
1788
+ "SELECT data FROM fs_chunks WHERE path = ? ORDER BY chunkIndex"
1789
+ ).all(filePath)
1790
+ );
1683
1791
  if (rows.length === 0) {
1684
1792
  return new Uint8Array(0);
1685
1793
  }
@@ -1696,9 +1804,11 @@ var SqliteFs = class {
1696
1804
  if (seen.has(p)) {
1697
1805
  throw new Error(`readFile: circular symlink: ${p}`);
1698
1806
  }
1699
- const entry = this.#stmt(
1700
- "SELECT type, symlinkTarget FROM fs_entries WHERE path = ?"
1701
- ).get(p);
1807
+ const entry = linkRow.optional().parse(
1808
+ this.#stmt(
1809
+ "SELECT type, symlinkTarget FROM fs_entries WHERE path = ?"
1810
+ ).get(p)
1811
+ );
1702
1812
  if (!entry) {
1703
1813
  throw new Error(`ENOENT: no such file or directory: ${p}`);
1704
1814
  }
@@ -1715,8 +1825,7 @@ var SqliteFs = class {
1715
1825
  if (content instanceof Uint8Array) {
1716
1826
  return content;
1717
1827
  }
1718
- const enc = encoding ?? "utf8";
1719
- return new Uint8Array(Buffer.from(content, enc));
1828
+ return new Uint8Array(Buffer.from(content, encoding ?? "utf8"));
1720
1829
  }
1721
1830
  // ============================================================================
1722
1831
  // IFileSystem Implementation
@@ -1725,8 +1834,8 @@ var SqliteFs = class {
1725
1834
  const normalized = this.#normalizePath(filePath);
1726
1835
  const prefixed = this.#prefixPath(normalized);
1727
1836
  const resolved = this.#resolveSymlink(prefixed);
1728
- const entry = this.#stmt("SELECT type FROM fs_entries WHERE path = ?").get(
1729
- resolved
1837
+ const entry = typeRow.optional().parse(
1838
+ this.#stmt("SELECT type FROM fs_entries WHERE path = ?").get(resolved)
1730
1839
  );
1731
1840
  if (!entry) {
1732
1841
  throw new Error(`ENOENT: no such file or directory: ${filePath}`);
@@ -1742,8 +1851,8 @@ var SqliteFs = class {
1742
1851
  const normalized = this.#normalizePath(filePath);
1743
1852
  const prefixed = this.#prefixPath(normalized);
1744
1853
  const resolved = this.#resolveSymlink(prefixed);
1745
- const entry = this.#stmt("SELECT type FROM fs_entries WHERE path = ?").get(
1746
- resolved
1854
+ const entry = typeRow.optional().parse(
1855
+ this.#stmt("SELECT type FROM fs_entries WHERE path = ?").get(resolved)
1747
1856
  );
1748
1857
  if (!entry) {
1749
1858
  throw new Error(`ENOENT: no such file or directory: ${filePath}`);
@@ -1778,9 +1887,11 @@ var SqliteFs = class {
1778
1887
  const newData = this.#toUint8Array(content, encoding);
1779
1888
  this.#useTransaction(() => {
1780
1889
  this.#ensureParentExists(prefixed);
1781
- const entry = this.#stmt(
1782
- "SELECT type FROM fs_entries WHERE path = ?"
1783
- ).get(prefixed);
1890
+ const entry = typeRow.optional().parse(
1891
+ this.#stmt("SELECT type FROM fs_entries WHERE path = ?").get(
1892
+ prefixed
1893
+ )
1894
+ );
1784
1895
  if (entry && entry.type !== "file") {
1785
1896
  throw new Error(`appendFile: not a file: ${filePath}`);
1786
1897
  }
@@ -1810,8 +1921,8 @@ var SqliteFs = class {
1810
1921
  const normalized = this.#normalizePath(filePath);
1811
1922
  const prefixed = this.#prefixPath(normalized);
1812
1923
  const resolved = this.#resolveSymlink(prefixed);
1813
- const entry = this.#stmt("SELECT * FROM fs_entries WHERE path = ?").get(
1814
- resolved
1924
+ const entry = entryRow.optional().parse(
1925
+ this.#stmt("SELECT * FROM fs_entries WHERE path = ?").get(resolved)
1815
1926
  );
1816
1927
  if (!entry) {
1817
1928
  throw new Error(`ENOENT: no such file or directory: ${filePath}`);
@@ -1829,8 +1940,8 @@ var SqliteFs = class {
1829
1940
  async lstat(filePath) {
1830
1941
  const normalized = this.#normalizePath(filePath);
1831
1942
  const prefixed = this.#prefixPath(normalized);
1832
- const entry = this.#stmt("SELECT * FROM fs_entries WHERE path = ?").get(
1833
- prefixed
1943
+ const entry = entryRow.optional().parse(
1944
+ this.#stmt("SELECT * FROM fs_entries WHERE path = ?").get(prefixed)
1834
1945
  );
1835
1946
  if (!entry) {
1836
1947
  throw new Error(`ENOENT: no such file or directory: ${filePath}`);
@@ -1847,9 +1958,9 @@ var SqliteFs = class {
1847
1958
  async mkdir(dirPath, options) {
1848
1959
  const normalized = this.#normalizePath(dirPath);
1849
1960
  const prefixed = this.#prefixPath(normalized);
1850
- const existing = this.#stmt(
1851
- "SELECT type FROM fs_entries WHERE path = ?"
1852
- ).get(prefixed);
1961
+ const existing = typeRow.optional().parse(
1962
+ this.#stmt("SELECT type FROM fs_entries WHERE path = ?").get(prefixed)
1963
+ );
1853
1964
  if (existing) {
1854
1965
  if (options?.recursive) {
1855
1966
  return;
@@ -1864,9 +1975,11 @@ var SqliteFs = class {
1864
1975
  let currentPath = rootPath;
1865
1976
  for (const segment of segments) {
1866
1977
  currentPath = path3.posix.join(currentPath, segment);
1867
- const exists = this.#stmt(
1868
- "SELECT type FROM fs_entries WHERE path = ?"
1869
- ).get(currentPath);
1978
+ const exists = typeRow.optional().parse(
1979
+ this.#stmt("SELECT type FROM fs_entries WHERE path = ?").get(
1980
+ currentPath
1981
+ )
1982
+ );
1870
1983
  if (!exists) {
1871
1984
  this.#stmt(
1872
1985
  `INSERT INTO fs_entries (path, type, mode, size, mtime)
@@ -1878,9 +1991,11 @@ var SqliteFs = class {
1878
1991
  }
1879
1992
  } else {
1880
1993
  const parent = this.#dirname(prefixed);
1881
- const parentEntry = this.#stmt(
1882
- "SELECT type FROM fs_entries WHERE path = ?"
1883
- ).get(parent);
1994
+ const parentEntry = typeRow.optional().parse(
1995
+ this.#stmt("SELECT type FROM fs_entries WHERE path = ?").get(
1996
+ parent
1997
+ )
1998
+ );
1884
1999
  if (!parentEntry) {
1885
2000
  throw new Error(`mkdir: parent does not exist: ${parent}`);
1886
2001
  }
@@ -1898,8 +2013,8 @@ var SqliteFs = class {
1898
2013
  const normalized = this.#normalizePath(dirPath);
1899
2014
  const prefixed = this.#prefixPath(normalized);
1900
2015
  const resolved = this.#resolveSymlink(prefixed);
1901
- const entry = this.#stmt("SELECT type FROM fs_entries WHERE path = ?").get(
1902
- resolved
2016
+ const entry = typeRow.optional().parse(
2017
+ this.#stmt("SELECT type FROM fs_entries WHERE path = ?").get(resolved)
1903
2018
  );
1904
2019
  if (!entry) {
1905
2020
  throw new Error(`ENOENT: no such file or directory: ${dirPath}`);
@@ -1908,20 +2023,22 @@ var SqliteFs = class {
1908
2023
  throw new Error(`ENOTDIR: not a directory: ${dirPath}`);
1909
2024
  }
1910
2025
  const prefix = resolved === "/" ? "/" : resolved + "/";
1911
- const rows = this.#stmt(
1912
- `SELECT path FROM fs_entries
2026
+ const rows = z6.array(pathRow).parse(
2027
+ this.#stmt(
2028
+ `SELECT path FROM fs_entries
1913
2029
  WHERE path LIKE ? || '%'
1914
2030
  AND path != ?
1915
2031
  AND path NOT LIKE ? || '%/%'`
1916
- ).all(prefix, resolved, prefix);
2032
+ ).all(prefix, resolved, prefix)
2033
+ );
1917
2034
  return rows.map((row) => path3.posix.basename(row.path));
1918
2035
  }
1919
2036
  async readdirWithFileTypes(dirPath) {
1920
2037
  const normalized = this.#normalizePath(dirPath);
1921
2038
  const prefixed = this.#prefixPath(normalized);
1922
2039
  const resolved = this.#resolveSymlink(prefixed);
1923
- const entry = this.#stmt("SELECT type FROM fs_entries WHERE path = ?").get(
1924
- resolved
2040
+ const entry = typeRow.optional().parse(
2041
+ this.#stmt("SELECT type FROM fs_entries WHERE path = ?").get(resolved)
1925
2042
  );
1926
2043
  if (!entry) {
1927
2044
  throw new Error(`ENOENT: no such file or directory: ${dirPath}`);
@@ -1930,12 +2047,14 @@ var SqliteFs = class {
1930
2047
  throw new Error(`ENOTDIR: not a directory: ${dirPath}`);
1931
2048
  }
1932
2049
  const prefix = resolved === "/" ? "/" : resolved + "/";
1933
- const rows = this.#stmt(
1934
- `SELECT path, type FROM fs_entries
2050
+ const rows = z6.array(pathTypeRow).parse(
2051
+ this.#stmt(
2052
+ `SELECT path, type FROM fs_entries
1935
2053
  WHERE path LIKE ? || '%'
1936
2054
  AND path != ?
1937
2055
  AND path NOT LIKE ? || '%/%'`
1938
- ).all(prefix, resolved, prefix);
2056
+ ).all(prefix, resolved, prefix)
2057
+ );
1939
2058
  return rows.map((row) => ({
1940
2059
  name: path3.posix.basename(row.path),
1941
2060
  isFile: row.type === "file",
@@ -1946,8 +2065,8 @@ var SqliteFs = class {
1946
2065
  async rm(filePath, options) {
1947
2066
  const normalized = this.#normalizePath(filePath);
1948
2067
  const prefixed = this.#prefixPath(normalized);
1949
- const entry = this.#stmt("SELECT type FROM fs_entries WHERE path = ?").get(
1950
- prefixed
2068
+ const entry = typeRow.optional().parse(
2069
+ this.#stmt("SELECT type FROM fs_entries WHERE path = ?").get(prefixed)
1951
2070
  );
1952
2071
  if (!entry) {
1953
2072
  if (options?.force) {
@@ -1976,8 +2095,8 @@ var SqliteFs = class {
1976
2095
  const destNormalized = this.#normalizePath(dest);
1977
2096
  const srcPrefixed = this.#prefixPath(srcNormalized);
1978
2097
  const destPrefixed = this.#prefixPath(destNormalized);
1979
- const srcEntry = this.#stmt("SELECT * FROM fs_entries WHERE path = ?").get(
1980
- srcPrefixed
2098
+ const srcEntry = entryRow.optional().parse(
2099
+ this.#stmt("SELECT * FROM fs_entries WHERE path = ?").get(srcPrefixed)
1981
2100
  );
1982
2101
  if (!srcEntry) {
1983
2102
  throw new Error(`ENOENT: no such file or directory: ${src}`);
@@ -1988,9 +2107,11 @@ var SqliteFs = class {
1988
2107
  this.#useTransaction(() => {
1989
2108
  this.#ensureParentExists(destPrefixed);
1990
2109
  if (srcEntry.type === "directory") {
1991
- const allEntries = this.#stmt(
1992
- `SELECT * FROM fs_entries WHERE path = ? OR path LIKE ? || '/%'`
1993
- ).all(srcPrefixed, srcPrefixed);
2110
+ const allEntries = z6.array(entryRow).parse(
2111
+ this.#stmt(
2112
+ `SELECT * FROM fs_entries WHERE path = ? OR path LIKE ? || '/%'`
2113
+ ).all(srcPrefixed, srcPrefixed)
2114
+ );
1994
2115
  for (const entry of allEntries) {
1995
2116
  const relativePath = path3.posix.relative(srcPrefixed, entry.path);
1996
2117
  const newPath = path3.posix.join(destPrefixed, relativePath);
@@ -2006,9 +2127,7 @@ var SqliteFs = class {
2006
2127
  entry.symlinkTarget
2007
2128
  );
2008
2129
  if (entry.type === "file") {
2009
- const chunks = this.#stmt(
2010
- "SELECT chunkIndex, data FROM fs_chunks WHERE path = ?"
2011
- ).all(entry.path);
2130
+ const chunks = this.#chunks(entry.path);
2012
2131
  for (const chunk of chunks) {
2013
2132
  this.#stmt(
2014
2133
  "INSERT INTO fs_chunks (path, chunkIndex, data) VALUES (?, ?, ?)"
@@ -2029,9 +2148,7 @@ var SqliteFs = class {
2029
2148
  srcEntry.symlinkTarget
2030
2149
  );
2031
2150
  if (srcEntry.type === "file") {
2032
- const chunks = this.#stmt(
2033
- "SELECT chunkIndex, data FROM fs_chunks WHERE path = ?"
2034
- ).all(srcPrefixed);
2151
+ const chunks = this.#chunks(srcPrefixed);
2035
2152
  this.#stmt("DELETE FROM fs_chunks WHERE path = ?").run(destPrefixed);
2036
2153
  for (const chunk of chunks) {
2037
2154
  this.#stmt(
@@ -2047,8 +2164,8 @@ var SqliteFs = class {
2047
2164
  const destNormalized = this.#normalizePath(dest);
2048
2165
  const srcPrefixed = this.#prefixPath(srcNormalized);
2049
2166
  const destPrefixed = this.#prefixPath(destNormalized);
2050
- const srcEntry = this.#stmt("SELECT * FROM fs_entries WHERE path = ?").get(
2051
- srcPrefixed
2167
+ const srcEntry = entryRow.optional().parse(
2168
+ this.#stmt("SELECT * FROM fs_entries WHERE path = ?").get(srcPrefixed)
2052
2169
  );
2053
2170
  if (!srcEntry) {
2054
2171
  throw new Error(`ENOENT: no such file or directory: ${src}`);
@@ -2056,9 +2173,11 @@ var SqliteFs = class {
2056
2173
  this.#useTransaction(() => {
2057
2174
  this.#ensureParentExists(destPrefixed);
2058
2175
  if (srcEntry.type === "directory") {
2059
- const allEntries = this.#stmt(
2060
- `SELECT * FROM fs_entries WHERE path = ? OR path LIKE ? || '/%' ORDER BY path DESC`
2061
- ).all(srcPrefixed, srcPrefixed);
2176
+ const allEntries = z6.array(entryRow).parse(
2177
+ this.#stmt(
2178
+ `SELECT * FROM fs_entries WHERE path = ? OR path LIKE ? || '/%' ORDER BY path DESC`
2179
+ ).all(srcPrefixed, srcPrefixed)
2180
+ );
2062
2181
  for (const entry of [...allEntries].reverse()) {
2063
2182
  const relativePath = path3.posix.relative(srcPrefixed, entry.path);
2064
2183
  const newPath = path3.posix.join(destPrefixed, relativePath);
@@ -2074,9 +2193,7 @@ var SqliteFs = class {
2074
2193
  entry.symlinkTarget
2075
2194
  );
2076
2195
  if (entry.type === "file") {
2077
- const chunks = this.#stmt(
2078
- "SELECT chunkIndex, data FROM fs_chunks WHERE path = ?"
2079
- ).all(entry.path);
2196
+ const chunks = this.#chunks(entry.path);
2080
2197
  for (const chunk of chunks) {
2081
2198
  this.#stmt(
2082
2199
  "INSERT INTO fs_chunks (path, chunkIndex, data) VALUES (?, ?, ?)"
@@ -2100,9 +2217,7 @@ var SqliteFs = class {
2100
2217
  srcEntry.symlinkTarget
2101
2218
  );
2102
2219
  if (srcEntry.type === "file") {
2103
- const chunks = this.#stmt(
2104
- "SELECT chunkIndex, data FROM fs_chunks WHERE path = ?"
2105
- ).all(srcPrefixed);
2220
+ const chunks = this.#chunks(srcPrefixed);
2106
2221
  for (const chunk of chunks) {
2107
2222
  this.#stmt(
2108
2223
  "INSERT INTO fs_chunks (path, chunkIndex, data) VALUES (?, ?, ?)"
@@ -2117,9 +2232,7 @@ var SqliteFs = class {
2117
2232
  return path3.posix.resolve(base, relativePath);
2118
2233
  }
2119
2234
  getAllPaths() {
2120
- const rows = this.#stmt(
2121
- "SELECT path FROM fs_entries ORDER BY path"
2122
- ).all();
2235
+ const rows = z6.array(pathRow).parse(this.#stmt("SELECT path FROM fs_entries ORDER BY path").all());
2123
2236
  return rows.map((row) => row.path);
2124
2237
  }
2125
2238
  async realpath(filePath) {
@@ -2177,8 +2290,8 @@ var SqliteFs = class {
2177
2290
  const destNormalized = this.#normalizePath(newPath);
2178
2291
  const srcPrefixed = this.#prefixPath(srcNormalized);
2179
2292
  const destPrefixed = this.#prefixPath(destNormalized);
2180
- const srcEntry = this.#stmt("SELECT * FROM fs_entries WHERE path = ?").get(
2181
- srcPrefixed
2293
+ const srcEntry = entryRow.optional().parse(
2294
+ this.#stmt("SELECT * FROM fs_entries WHERE path = ?").get(srcPrefixed)
2182
2295
  );
2183
2296
  if (!srcEntry) {
2184
2297
  throw new Error(`ENOENT: no such file or directory: ${existingPath}`);
@@ -2198,9 +2311,7 @@ var SqliteFs = class {
2198
2311
  `INSERT INTO fs_entries (path, type, mode, size, mtime)
2199
2312
  VALUES (?, 'file', ?, ?, ?)`
2200
2313
  ).run(destPrefixed, srcEntry.mode, srcEntry.size, Date.now());
2201
- const chunks = this.#stmt(
2202
- "SELECT chunkIndex, data FROM fs_chunks WHERE path = ?"
2203
- ).all(srcPrefixed);
2314
+ const chunks = this.#chunks(srcPrefixed);
2204
2315
  for (const chunk of chunks) {
2205
2316
  this.#stmt(
2206
2317
  "INSERT INTO fs_chunks (path, chunkIndex, data) VALUES (?, ?, ?)"
@@ -2211,9 +2322,11 @@ var SqliteFs = class {
2211
2322
  async readlink(linkPath) {
2212
2323
  const normalized = this.#normalizePath(linkPath);
2213
2324
  const prefixed = this.#prefixPath(normalized);
2214
- const entry = this.#stmt(
2215
- "SELECT type, symlinkTarget FROM fs_entries WHERE path = ?"
2216
- ).get(prefixed);
2325
+ const entry = linkRow.optional().parse(
2326
+ this.#stmt(
2327
+ "SELECT type, symlinkTarget FROM fs_entries WHERE path = ?"
2328
+ ).get(prefixed)
2329
+ );
2217
2330
  if (!entry) {
2218
2331
  throw new Error(`ENOENT: no such file or directory: ${linkPath}`);
2219
2332
  }
@@ -2227,6 +2340,7 @@ var SqliteFs = class {
2227
2340
  // packages/text2sql/src/lib/fs/mssql/mssql-fs.ts
2228
2341
  import { createRequire } from "node:module";
2229
2342
  import * as path4 from "node:path";
2343
+ import z7 from "zod";
2230
2344
 
2231
2345
  // packages/text2sql/src/lib/fs/mssql/ddl.mssql-fs.ts
2232
2346
  function mssqlFsDDL(schema) {
@@ -2259,6 +2373,33 @@ GO
2259
2373
  }
2260
2374
 
2261
2375
  // packages/text2sql/src/lib/fs/mssql/mssql-fs.ts
2376
+ var entryRow2 = z7.object({
2377
+ path: z7.string(),
2378
+ type: entryType,
2379
+ mode: z7.number(),
2380
+ size: bigintColumn,
2381
+ mtime: bigintColumn,
2382
+ symlinkTarget: z7.string().nullable()
2383
+ });
2384
+ var typeRow2 = entryRow2.pick({ type: true });
2385
+ var pathRow2 = entryRow2.pick({ path: true });
2386
+ var pathTypeRow2 = entryRow2.pick({ path: true, type: true });
2387
+ var linkRow2 = z7.discriminatedUnion("type", [
2388
+ z7.object({ type: z7.literal("symlink"), symlinkTarget: z7.string() }),
2389
+ z7.object({
2390
+ type: z7.enum(["file", "directory"]),
2391
+ symlinkTarget: z7.string().nullable()
2392
+ })
2393
+ ]);
2394
+ var existsRow = z7.object({ exists: z7.union([z7.literal(0), z7.literal(1)]) });
2395
+ var chunkRow2 = z7.object({
2396
+ chunkIndex: z7.number(),
2397
+ data: z7.instanceof(Buffer)
2398
+ });
2399
+ var dataRow2 = chunkRow2.pick({ data: true });
2400
+ function rowsOf(row, result) {
2401
+ return z7.array(row).parse(result.recordset);
2402
+ }
2262
2403
  var MssqlFs = class _MssqlFs {
2263
2404
  #pool;
2264
2405
  #chunkSize;
@@ -2317,8 +2458,11 @@ var MssqlFs = class _MssqlFs {
2317
2458
  await this.#pool.request().batch(batch);
2318
2459
  }
2319
2460
  }
2320
- const rootSlashExists = await this.#rawQuery(
2321
- `SELECT CASE WHEN EXISTS(SELECT 1 FROM ${this.#t("fs_entries")} WHERE path = '/') THEN 1 ELSE 0 END as [exists]`
2461
+ const rootSlashExists = rowsOf(
2462
+ existsRow,
2463
+ await this.#rawQuery(
2464
+ `SELECT CASE WHEN EXISTS(SELECT 1 FROM ${this.#t("fs_entries")} WHERE path = '/') THEN 1 ELSE 0 END as [exists]`
2465
+ )
2322
2466
  );
2323
2467
  if (rootSlashExists[0].exists === 0) {
2324
2468
  await this.#rawExec(
@@ -2328,9 +2472,12 @@ var MssqlFs = class _MssqlFs {
2328
2472
  }
2329
2473
  if (this.#root) {
2330
2474
  await this.#createParentDirs(this.#root);
2331
- const rootExists = await this.#rawQuery(
2332
- `SELECT CASE WHEN EXISTS(SELECT 1 FROM ${this.#t("fs_entries")} WHERE path = @p0) THEN 1 ELSE 0 END as [exists]`,
2333
- [this.#root]
2475
+ const rootExists = rowsOf(
2476
+ existsRow,
2477
+ await this.#rawQuery(
2478
+ `SELECT CASE WHEN EXISTS(SELECT 1 FROM ${this.#t("fs_entries")} WHERE path = @p0) THEN 1 ELSE 0 END as [exists]`,
2479
+ [this.#root]
2480
+ )
2334
2481
  );
2335
2482
  if (rootExists[0].exists === 0) {
2336
2483
  await this.#rawExec(
@@ -2353,9 +2500,12 @@ var MssqlFs = class _MssqlFs {
2353
2500
  let currentPath = "/";
2354
2501
  for (let i = 0; i < segments.length - 1; i++) {
2355
2502
  currentPath = path4.posix.join(currentPath, segments[i]);
2356
- const exists = await this.#rawQuery(
2357
- `SELECT CASE WHEN EXISTS(SELECT 1 FROM ${this.#t("fs_entries")} WHERE path = @p0) THEN 1 ELSE 0 END as [exists]`,
2358
- [currentPath]
2503
+ const exists = rowsOf(
2504
+ existsRow,
2505
+ await this.#rawQuery(
2506
+ `SELECT CASE WHEN EXISTS(SELECT 1 FROM ${this.#t("fs_entries")} WHERE path = @p0) THEN 1 ELSE 0 END as [exists]`,
2507
+ [currentPath]
2508
+ )
2359
2509
  );
2360
2510
  if (exists[0].exists === 0) {
2361
2511
  await this.#rawExec(
@@ -2365,13 +2515,12 @@ var MssqlFs = class _MssqlFs {
2365
2515
  }
2366
2516
  }
2367
2517
  }
2368
- async #rawQuery(sql, params) {
2518
+ #rawQuery(sql, params) {
2369
2519
  const request = this.#pool.request();
2370
2520
  params?.forEach((value, index2) => {
2371
2521
  request.input(`p${index2}`, value);
2372
2522
  });
2373
- const result = await request.query(sql);
2374
- return result.recordset;
2523
+ return request.query(sql);
2375
2524
  }
2376
2525
  async #rawExec(sql, params) {
2377
2526
  const request = this.#pool.request();
@@ -2440,10 +2589,12 @@ var MssqlFs = class _MssqlFs {
2440
2589
  if (parent === rootPath || parent === "/") return;
2441
2590
  const request = transaction.request();
2442
2591
  request.input("p0", parent);
2443
- const result = await request.query(
2444
- `SELECT type FROM ${this.#t("fs_entries")} WHERE path = @p0`
2592
+ const [entry] = rowsOf(
2593
+ typeRow2,
2594
+ await request.query(
2595
+ `SELECT type FROM ${this.#t("fs_entries")} WHERE path = @p0`
2596
+ )
2445
2597
  );
2446
- const entry = result.recordset[0];
2447
2598
  if (!entry) {
2448
2599
  await this.#ensureParentExists(parent, transaction);
2449
2600
  const insertReq = transaction.request();
@@ -2477,20 +2628,11 @@ var MssqlFs = class _MssqlFs {
2477
2628
  }
2478
2629
  }
2479
2630
  async #readChunks(filePath, transaction) {
2480
- let rows;
2481
- if (transaction) {
2482
- const req = transaction.request();
2483
- req.input("p0", filePath);
2484
- const result2 = await req.query(
2485
- `SELECT data FROM ${this.#t("fs_chunks")} WHERE path = @p0 ORDER BY chunkIndex`
2486
- );
2487
- rows = result2.recordset;
2488
- } else {
2489
- rows = await this.#query(
2490
- `SELECT data FROM ${this.#t("fs_chunks")} WHERE path = @p0 ORDER BY chunkIndex`,
2491
- [filePath]
2492
- );
2493
- }
2631
+ const sql = `SELECT data FROM ${this.#t("fs_chunks")} WHERE path = @p0 ORDER BY chunkIndex`;
2632
+ const rows = rowsOf(
2633
+ dataRow2,
2634
+ transaction ? await transaction.request().input("p0", filePath).query(sql) : await this.#query(sql, [filePath])
2635
+ );
2494
2636
  if (rows.length === 0) {
2495
2637
  return new Uint8Array(0);
2496
2638
  }
@@ -2507,11 +2649,13 @@ var MssqlFs = class _MssqlFs {
2507
2649
  if (seen.has(p)) {
2508
2650
  throw new Error(`readFile: circular symlink: ${p}`);
2509
2651
  }
2510
- const rows = await this.#query(
2511
- `SELECT type, symlinkTarget FROM ${this.#t("fs_entries")} WHERE path = @p0`,
2512
- [p]
2652
+ const [entry] = rowsOf(
2653
+ linkRow2,
2654
+ await this.#query(
2655
+ `SELECT type, symlinkTarget FROM ${this.#t("fs_entries")} WHERE path = @p0`,
2656
+ [p]
2657
+ )
2513
2658
  );
2514
- const entry = rows[0];
2515
2659
  if (!entry) {
2516
2660
  throw new Error(`ENOENT: no such file or directory: ${p}`);
2517
2661
  }
@@ -2528,8 +2672,7 @@ var MssqlFs = class _MssqlFs {
2528
2672
  if (content instanceof Uint8Array) {
2529
2673
  return content;
2530
2674
  }
2531
- const enc = encoding ?? "utf8";
2532
- return new Uint8Array(Buffer.from(content, enc));
2675
+ return new Uint8Array(Buffer.from(content, encoding ?? "utf8"));
2533
2676
  }
2534
2677
  async close() {
2535
2678
  if (this.#ownsPool) {
@@ -2543,11 +2686,13 @@ var MssqlFs = class _MssqlFs {
2543
2686
  const normalized = this.#normalizePath(filePath);
2544
2687
  const prefixed = this.#prefixPath(normalized);
2545
2688
  const resolved = await this.#resolveSymlink(prefixed);
2546
- const rows = await this.#query(
2547
- `SELECT type FROM ${this.#t("fs_entries")} WHERE path = @p0`,
2548
- [resolved]
2689
+ const [entry] = rowsOf(
2690
+ typeRow2,
2691
+ await this.#query(
2692
+ `SELECT type FROM ${this.#t("fs_entries")} WHERE path = @p0`,
2693
+ [resolved]
2694
+ )
2549
2695
  );
2550
- const entry = rows[0];
2551
2696
  if (!entry) {
2552
2697
  throw new Error(`ENOENT: no such file or directory: ${filePath}`);
2553
2698
  }
@@ -2562,11 +2707,13 @@ var MssqlFs = class _MssqlFs {
2562
2707
  const normalized = this.#normalizePath(filePath);
2563
2708
  const prefixed = this.#prefixPath(normalized);
2564
2709
  const resolved = await this.#resolveSymlink(prefixed);
2565
- const rows = await this.#query(
2566
- `SELECT type FROM ${this.#t("fs_entries")} WHERE path = @p0`,
2567
- [resolved]
2710
+ const [entry] = rowsOf(
2711
+ typeRow2,
2712
+ await this.#query(
2713
+ `SELECT type FROM ${this.#t("fs_entries")} WHERE path = @p0`,
2714
+ [resolved]
2715
+ )
2568
2716
  );
2569
- const entry = rows[0];
2570
2717
  if (!entry) {
2571
2718
  throw new Error(`ENOENT: no such file or directory: ${filePath}`);
2572
2719
  }
@@ -2608,10 +2755,12 @@ var MssqlFs = class _MssqlFs {
2608
2755
  await this.#ensureParentExists(prefixed, transaction);
2609
2756
  const checkReq = transaction.request();
2610
2757
  checkReq.input("p0", prefixed);
2611
- const result = await checkReq.query(
2612
- `SELECT type FROM ${this.#t("fs_entries")} WHERE path = @p0`
2758
+ const [entry] = rowsOf(
2759
+ typeRow2,
2760
+ await checkReq.query(
2761
+ `SELECT type FROM ${this.#t("fs_entries")} WHERE path = @p0`
2762
+ )
2613
2763
  );
2614
- const entry = result.recordset[0];
2615
2764
  if (entry && entry.type !== "file") {
2616
2765
  throw new Error(`appendFile: not a file: ${filePath}`);
2617
2766
  }
@@ -2639,9 +2788,12 @@ var MssqlFs = class _MssqlFs {
2639
2788
  async exists(filePath) {
2640
2789
  const normalized = this.#normalizePath(filePath);
2641
2790
  const prefixed = this.#prefixPath(normalized);
2642
- const rows = await this.#query(
2643
- `SELECT CASE WHEN EXISTS(SELECT 1 FROM ${this.#t("fs_entries")} WHERE path = @p0) THEN 1 ELSE 0 END as [exists]`,
2644
- [prefixed]
2791
+ const rows = rowsOf(
2792
+ existsRow,
2793
+ await this.#query(
2794
+ `SELECT CASE WHEN EXISTS(SELECT 1 FROM ${this.#t("fs_entries")} WHERE path = @p0) THEN 1 ELSE 0 END as [exists]`,
2795
+ [prefixed]
2796
+ )
2645
2797
  );
2646
2798
  return rows[0].exists === 1;
2647
2799
  }
@@ -2649,11 +2801,13 @@ var MssqlFs = class _MssqlFs {
2649
2801
  const normalized = this.#normalizePath(filePath);
2650
2802
  const prefixed = this.#prefixPath(normalized);
2651
2803
  const resolved = await this.#resolveSymlink(prefixed);
2652
- const rows = await this.#query(
2653
- `SELECT * FROM ${this.#t("fs_entries")} WHERE path = @p0`,
2654
- [resolved]
2804
+ const [entry] = rowsOf(
2805
+ entryRow2,
2806
+ await this.#query(
2807
+ `SELECT * FROM ${this.#t("fs_entries")} WHERE path = @p0`,
2808
+ [resolved]
2809
+ )
2655
2810
  );
2656
- const entry = rows[0];
2657
2811
  if (!entry) {
2658
2812
  throw new Error(`ENOENT: no such file or directory: ${filePath}`);
2659
2813
  }
@@ -2661,19 +2815,21 @@ var MssqlFs = class _MssqlFs {
2661
2815
  isFile: entry.type === "file",
2662
2816
  isDirectory: entry.type === "directory",
2663
2817
  isSymbolicLink: false,
2664
- mode: Number(entry.mode),
2665
- size: Number(entry.size),
2666
- mtime: new Date(Number(entry.mtime))
2818
+ mode: entry.mode,
2819
+ size: entry.size,
2820
+ mtime: new Date(entry.mtime)
2667
2821
  };
2668
2822
  }
2669
2823
  async lstat(filePath) {
2670
2824
  const normalized = this.#normalizePath(filePath);
2671
2825
  const prefixed = this.#prefixPath(normalized);
2672
- const rows = await this.#query(
2673
- `SELECT * FROM ${this.#t("fs_entries")} WHERE path = @p0`,
2674
- [prefixed]
2826
+ const [entry] = rowsOf(
2827
+ entryRow2,
2828
+ await this.#query(
2829
+ `SELECT * FROM ${this.#t("fs_entries")} WHERE path = @p0`,
2830
+ [prefixed]
2831
+ )
2675
2832
  );
2676
- const entry = rows[0];
2677
2833
  if (!entry) {
2678
2834
  throw new Error(`ENOENT: no such file or directory: ${filePath}`);
2679
2835
  }
@@ -2681,19 +2837,21 @@ var MssqlFs = class _MssqlFs {
2681
2837
  isFile: entry.type === "file",
2682
2838
  isDirectory: entry.type === "directory",
2683
2839
  isSymbolicLink: entry.type === "symlink",
2684
- mode: Number(entry.mode),
2685
- size: Number(entry.size),
2686
- mtime: new Date(Number(entry.mtime))
2840
+ mode: entry.mode,
2841
+ size: entry.size,
2842
+ mtime: new Date(entry.mtime)
2687
2843
  };
2688
2844
  }
2689
2845
  async mkdir(dirPath, options) {
2690
2846
  const normalized = this.#normalizePath(dirPath);
2691
2847
  const prefixed = this.#prefixPath(normalized);
2692
- const existingRows = await this.#query(
2693
- `SELECT type FROM ${this.#t("fs_entries")} WHERE path = @p0`,
2694
- [prefixed]
2848
+ const [existing] = rowsOf(
2849
+ typeRow2,
2850
+ await this.#query(
2851
+ `SELECT type FROM ${this.#t("fs_entries")} WHERE path = @p0`,
2852
+ [prefixed]
2853
+ )
2695
2854
  );
2696
- const existing = existingRows[0];
2697
2855
  if (existing) {
2698
2856
  if (options?.recursive) {
2699
2857
  return;
@@ -2710,10 +2868,12 @@ var MssqlFs = class _MssqlFs {
2710
2868
  currentPath = path4.posix.join(currentPath, segment);
2711
2869
  const checkReq = transaction.request();
2712
2870
  checkReq.input("p0", currentPath);
2713
- const result = await checkReq.query(
2714
- `SELECT type FROM ${this.#t("fs_entries")} WHERE path = @p0`
2871
+ const [exists] = rowsOf(
2872
+ typeRow2,
2873
+ await checkReq.query(
2874
+ `SELECT type FROM ${this.#t("fs_entries")} WHERE path = @p0`
2875
+ )
2715
2876
  );
2716
- const exists = result.recordset[0];
2717
2877
  if (!exists) {
2718
2878
  const insertReq = transaction.request();
2719
2879
  insertReq.input("p0", currentPath);
@@ -2729,10 +2889,12 @@ var MssqlFs = class _MssqlFs {
2729
2889
  const parent = this.#dirname(prefixed);
2730
2890
  const parentReq = transaction.request();
2731
2891
  parentReq.input("p0", parent);
2732
- const parentResult = await parentReq.query(
2733
- `SELECT type FROM ${this.#t("fs_entries")} WHERE path = @p0`
2892
+ const [parentEntry] = rowsOf(
2893
+ typeRow2,
2894
+ await parentReq.query(
2895
+ `SELECT type FROM ${this.#t("fs_entries")} WHERE path = @p0`
2896
+ )
2734
2897
  );
2735
- const parentEntry = parentResult.recordset[0];
2736
2898
  if (!parentEntry) {
2737
2899
  throw new Error(`mkdir: parent does not exist: ${parent}`);
2738
2900
  }
@@ -2752,11 +2914,13 @@ var MssqlFs = class _MssqlFs {
2752
2914
  const normalized = this.#normalizePath(dirPath);
2753
2915
  const prefixed = this.#prefixPath(normalized);
2754
2916
  const resolved = await this.#resolveSymlink(prefixed);
2755
- const entryRows = await this.#query(
2756
- `SELECT type FROM ${this.#t("fs_entries")} WHERE path = @p0`,
2757
- [resolved]
2917
+ const [entry] = rowsOf(
2918
+ typeRow2,
2919
+ await this.#query(
2920
+ `SELECT type FROM ${this.#t("fs_entries")} WHERE path = @p0`,
2921
+ [resolved]
2922
+ )
2758
2923
  );
2759
- const entry = entryRows[0];
2760
2924
  if (!entry) {
2761
2925
  throw new Error(`ENOENT: no such file or directory: ${dirPath}`);
2762
2926
  }
@@ -2764,12 +2928,15 @@ var MssqlFs = class _MssqlFs {
2764
2928
  throw new Error(`ENOTDIR: not a directory: ${dirPath}`);
2765
2929
  }
2766
2930
  const prefix = resolved === "/" ? "/" : resolved + "/";
2767
- const rows = await this.#query(
2768
- `SELECT path FROM ${this.#t("fs_entries")}
2931
+ const rows = rowsOf(
2932
+ pathRow2,
2933
+ await this.#query(
2934
+ `SELECT path FROM ${this.#t("fs_entries")}
2769
2935
  WHERE path LIKE @p0 + '%'
2770
2936
  AND path != @p1
2771
2937
  AND path NOT LIKE @p0 + '%/%'`,
2772
- [prefix, resolved]
2938
+ [prefix, resolved]
2939
+ )
2773
2940
  );
2774
2941
  return rows.map((row) => path4.posix.basename(row.path));
2775
2942
  }
@@ -2777,11 +2944,13 @@ var MssqlFs = class _MssqlFs {
2777
2944
  const normalized = this.#normalizePath(dirPath);
2778
2945
  const prefixed = this.#prefixPath(normalized);
2779
2946
  const resolved = await this.#resolveSymlink(prefixed);
2780
- const entryRows = await this.#query(
2781
- `SELECT type FROM ${this.#t("fs_entries")} WHERE path = @p0`,
2782
- [resolved]
2947
+ const [entry] = rowsOf(
2948
+ typeRow2,
2949
+ await this.#query(
2950
+ `SELECT type FROM ${this.#t("fs_entries")} WHERE path = @p0`,
2951
+ [resolved]
2952
+ )
2783
2953
  );
2784
- const entry = entryRows[0];
2785
2954
  if (!entry) {
2786
2955
  throw new Error(`ENOENT: no such file or directory: ${dirPath}`);
2787
2956
  }
@@ -2789,12 +2958,15 @@ var MssqlFs = class _MssqlFs {
2789
2958
  throw new Error(`ENOTDIR: not a directory: ${dirPath}`);
2790
2959
  }
2791
2960
  const prefix = resolved === "/" ? "/" : resolved + "/";
2792
- const rows = await this.#query(
2793
- `SELECT path, type FROM ${this.#t("fs_entries")}
2961
+ const rows = rowsOf(
2962
+ pathTypeRow2,
2963
+ await this.#query(
2964
+ `SELECT path, type FROM ${this.#t("fs_entries")}
2794
2965
  WHERE path LIKE @p0 + '%'
2795
2966
  AND path != @p1
2796
2967
  AND path NOT LIKE @p0 + '%/%'`,
2797
- [prefix, resolved]
2968
+ [prefix, resolved]
2969
+ )
2798
2970
  );
2799
2971
  return rows.map((row) => ({
2800
2972
  name: path4.posix.basename(row.path),
@@ -2806,11 +2978,13 @@ var MssqlFs = class _MssqlFs {
2806
2978
  async rm(filePath, options) {
2807
2979
  const normalized = this.#normalizePath(filePath);
2808
2980
  const prefixed = this.#prefixPath(normalized);
2809
- const rows = await this.#query(
2810
- `SELECT type FROM ${this.#t("fs_entries")} WHERE path = @p0`,
2811
- [prefixed]
2981
+ const [entry] = rowsOf(
2982
+ typeRow2,
2983
+ await this.#query(
2984
+ `SELECT type FROM ${this.#t("fs_entries")} WHERE path = @p0`,
2985
+ [prefixed]
2986
+ )
2812
2987
  );
2813
- const entry = rows[0];
2814
2988
  if (!entry) {
2815
2989
  if (options?.force) {
2816
2990
  return;
@@ -2821,10 +2995,13 @@ var MssqlFs = class _MssqlFs {
2821
2995
  if (entry.type === "directory") {
2822
2996
  const childrenReq = transaction.request();
2823
2997
  childrenReq.input("p0", prefixed);
2824
- const childrenResult = await childrenReq.query(
2825
- `SELECT CASE WHEN EXISTS(SELECT 1 FROM ${this.#t("fs_entries")} WHERE path LIKE @p0 + '/%') THEN 1 ELSE 0 END as [exists]`
2998
+ const children = rowsOf(
2999
+ existsRow,
3000
+ await childrenReq.query(
3001
+ `SELECT CASE WHEN EXISTS(SELECT 1 FROM ${this.#t("fs_entries")} WHERE path LIKE @p0 + '/%') THEN 1 ELSE 0 END as [exists]`
3002
+ )
2826
3003
  );
2827
- if (childrenResult.recordset[0].exists === 1 && !options?.recursive) {
3004
+ if (children[0].exists === 1 && !options?.recursive) {
2828
3005
  throw new Error(`ENOTEMPTY: directory not empty: ${filePath}`);
2829
3006
  }
2830
3007
  const deleteReq = transaction.request();
@@ -2846,11 +3023,13 @@ var MssqlFs = class _MssqlFs {
2846
3023
  const destNormalized = this.#normalizePath(dest);
2847
3024
  const srcPrefixed = this.#prefixPath(srcNormalized);
2848
3025
  const destPrefixed = this.#prefixPath(destNormalized);
2849
- const srcRows = await this.#query(
2850
- `SELECT * FROM ${this.#t("fs_entries")} WHERE path = @p0`,
2851
- [srcPrefixed]
3026
+ const [srcEntry] = rowsOf(
3027
+ entryRow2,
3028
+ await this.#query(
3029
+ `SELECT * FROM ${this.#t("fs_entries")} WHERE path = @p0`,
3030
+ [srcPrefixed]
3031
+ )
2852
3032
  );
2853
- const srcEntry = srcRows[0];
2854
3033
  if (!srcEntry) {
2855
3034
  throw new Error(`ENOENT: no such file or directory: ${src}`);
2856
3035
  }
@@ -2862,10 +3041,13 @@ var MssqlFs = class _MssqlFs {
2862
3041
  if (srcEntry.type === "directory") {
2863
3042
  const allEntriesReq = transaction.request();
2864
3043
  allEntriesReq.input("p0", srcPrefixed);
2865
- const allEntriesResult = await allEntriesReq.query(
2866
- `SELECT * FROM ${this.#t("fs_entries")} WHERE path = @p0 OR path LIKE @p0 + '/%'`
3044
+ const allEntries = rowsOf(
3045
+ entryRow2,
3046
+ await allEntriesReq.query(
3047
+ `SELECT * FROM ${this.#t("fs_entries")} WHERE path = @p0 OR path LIKE @p0 + '/%'`
3048
+ )
2867
3049
  );
2868
- for (const entry of allEntriesResult.recordset) {
3050
+ for (const entry of allEntries) {
2869
3051
  const relativePath = path4.posix.relative(srcPrefixed, entry.path);
2870
3052
  const newPath = path4.posix.join(destPrefixed, relativePath);
2871
3053
  const insertReq = transaction.request();
@@ -2893,10 +3075,13 @@ var MssqlFs = class _MssqlFs {
2893
3075
  );
2894
3076
  const chunksReq = transaction.request();
2895
3077
  chunksReq.input("p0", entry.path);
2896
- const chunksResult = await chunksReq.query(
2897
- `SELECT chunkIndex, data FROM ${this.#t("fs_chunks")} WHERE path = @p0`
3078
+ const chunks = rowsOf(
3079
+ chunkRow2,
3080
+ await chunksReq.query(
3081
+ `SELECT chunkIndex, data FROM ${this.#t("fs_chunks")} WHERE path = @p0`
3082
+ )
2898
3083
  );
2899
- for (const chunk of chunksResult.recordset) {
3084
+ for (const chunk of chunks) {
2900
3085
  const chunkInsertReq = transaction.request();
2901
3086
  chunkInsertReq.input("p0", newPath);
2902
3087
  chunkInsertReq.input("p1", chunk.chunkIndex);
@@ -2928,15 +3113,18 @@ var MssqlFs = class _MssqlFs {
2928
3113
  if (srcEntry.type === "file") {
2929
3114
  const chunksReq = transaction.request();
2930
3115
  chunksReq.input("p0", srcPrefixed);
2931
- const chunksResult = await chunksReq.query(
2932
- `SELECT chunkIndex, data FROM ${this.#t("fs_chunks")} WHERE path = @p0`
3116
+ const chunks = rowsOf(
3117
+ chunkRow2,
3118
+ await chunksReq.query(
3119
+ `SELECT chunkIndex, data FROM ${this.#t("fs_chunks")} WHERE path = @p0`
3120
+ )
2933
3121
  );
2934
3122
  const deleteChunksReq = transaction.request();
2935
3123
  deleteChunksReq.input("p0", destPrefixed);
2936
3124
  await deleteChunksReq.query(
2937
3125
  `DELETE FROM ${this.#t("fs_chunks")} WHERE path = @p0`
2938
3126
  );
2939
- for (const chunk of chunksResult.recordset) {
3127
+ for (const chunk of chunks) {
2940
3128
  const chunkInsertReq = transaction.request();
2941
3129
  chunkInsertReq.input("p0", destPrefixed);
2942
3130
  chunkInsertReq.input("p1", chunk.chunkIndex);
@@ -2954,11 +3142,13 @@ var MssqlFs = class _MssqlFs {
2954
3142
  const destNormalized = this.#normalizePath(dest);
2955
3143
  const srcPrefixed = this.#prefixPath(srcNormalized);
2956
3144
  const destPrefixed = this.#prefixPath(destNormalized);
2957
- const srcRows = await this.#query(
2958
- `SELECT * FROM ${this.#t("fs_entries")} WHERE path = @p0`,
2959
- [srcPrefixed]
3145
+ const [srcEntry] = rowsOf(
3146
+ entryRow2,
3147
+ await this.#query(
3148
+ `SELECT * FROM ${this.#t("fs_entries")} WHERE path = @p0`,
3149
+ [srcPrefixed]
3150
+ )
2960
3151
  );
2961
- const srcEntry = srcRows[0];
2962
3152
  if (!srcEntry) {
2963
3153
  throw new Error(`ENOENT: no such file or directory: ${src}`);
2964
3154
  }
@@ -2967,15 +3157,18 @@ var MssqlFs = class _MssqlFs {
2967
3157
  if (srcEntry.type === "directory") {
2968
3158
  const allEntriesReq = transaction.request();
2969
3159
  allEntriesReq.input("p0", srcPrefixed);
2970
- const allEntriesResult = await allEntriesReq.query(
2971
- `SELECT * FROM ${this.#t("fs_entries")} WHERE path = @p0 OR path LIKE @p0 + '/%' ORDER BY path DESC`
3160
+ const allEntries = rowsOf(
3161
+ entryRow2,
3162
+ await allEntriesReq.query(
3163
+ `SELECT * FROM ${this.#t("fs_entries")} WHERE path = @p0 OR path LIKE @p0 + '/%' ORDER BY path DESC`
3164
+ )
2972
3165
  );
2973
3166
  const destDeleteReq = transaction.request();
2974
3167
  destDeleteReq.input("dp0", destPrefixed);
2975
3168
  await destDeleteReq.query(
2976
3169
  `DELETE FROM ${this.#t("fs_entries")} WHERE path = @dp0 OR path LIKE @dp0 + '/%'`
2977
3170
  );
2978
- for (const entry of [...allEntriesResult.recordset].reverse()) {
3171
+ for (const entry of [...allEntries].reverse()) {
2979
3172
  const relativePath = path4.posix.relative(srcPrefixed, entry.path);
2980
3173
  const newPath = path4.posix.join(destPrefixed, relativePath);
2981
3174
  const insertReq = transaction.request();
@@ -3003,10 +3196,13 @@ var MssqlFs = class _MssqlFs {
3003
3196
  );
3004
3197
  const chunksReq = transaction.request();
3005
3198
  chunksReq.input("p0", entry.path);
3006
- const chunksResult = await chunksReq.query(
3007
- `SELECT chunkIndex, data FROM ${this.#t("fs_chunks")} WHERE path = @p0`
3199
+ const chunks = rowsOf(
3200
+ chunkRow2,
3201
+ await chunksReq.query(
3202
+ `SELECT chunkIndex, data FROM ${this.#t("fs_chunks")} WHERE path = @p0`
3203
+ )
3008
3204
  );
3009
- for (const chunk of chunksResult.recordset) {
3205
+ for (const chunk of chunks) {
3010
3206
  const chunkInsertReq = transaction.request();
3011
3207
  chunkInsertReq.input("p0", newPath);
3012
3208
  chunkInsertReq.input("p1", chunk.chunkIndex);
@@ -3048,10 +3244,13 @@ var MssqlFs = class _MssqlFs {
3048
3244
  );
3049
3245
  const chunksReq = transaction.request();
3050
3246
  chunksReq.input("p0", srcPrefixed);
3051
- const chunksResult = await chunksReq.query(
3052
- `SELECT chunkIndex, data FROM ${this.#t("fs_chunks")} WHERE path = @p0`
3247
+ const chunks = rowsOf(
3248
+ chunkRow2,
3249
+ await chunksReq.query(
3250
+ `SELECT chunkIndex, data FROM ${this.#t("fs_chunks")} WHERE path = @p0`
3251
+ )
3053
3252
  );
3054
- for (const chunk of chunksResult.recordset) {
3253
+ for (const chunk of chunks) {
3055
3254
  const chunkInsertReq = transaction.request();
3056
3255
  chunkInsertReq.input("p0", destPrefixed);
3057
3256
  chunkInsertReq.input("p1", chunk.chunkIndex);
@@ -3078,8 +3277,11 @@ var MssqlFs = class _MssqlFs {
3078
3277
  );
3079
3278
  }
3080
3279
  async getAllPathsAsync() {
3081
- const rows = await this.#query(
3082
- `SELECT path FROM ${this.#t("fs_entries")} ORDER BY path`
3280
+ const rows = rowsOf(
3281
+ pathRow2,
3282
+ await this.#query(
3283
+ `SELECT path FROM ${this.#t("fs_entries")} ORDER BY path`
3284
+ )
3083
3285
  );
3084
3286
  return rows.map((row) => row.path);
3085
3287
  }
@@ -3087,9 +3289,12 @@ var MssqlFs = class _MssqlFs {
3087
3289
  const normalized = this.#normalizePath(filePath);
3088
3290
  const prefixed = this.#prefixPath(normalized);
3089
3291
  const resolved = await this.#resolveSymlink(prefixed);
3090
- const rows = await this.#query(
3091
- `SELECT CASE WHEN EXISTS(SELECT 1 FROM ${this.#t("fs_entries")} WHERE path = @p0) THEN 1 ELSE 0 END as [exists]`,
3092
- [resolved]
3292
+ const rows = rowsOf(
3293
+ existsRow,
3294
+ await this.#query(
3295
+ `SELECT CASE WHEN EXISTS(SELECT 1 FROM ${this.#t("fs_entries")} WHERE path = @p0) THEN 1 ELSE 0 END as [exists]`,
3296
+ [resolved]
3297
+ )
3093
3298
  );
3094
3299
  if (rows[0].exists !== 1) {
3095
3300
  throw new Error(`ENOENT: no such file or directory: ${filePath}`);
@@ -3122,9 +3327,12 @@ var MssqlFs = class _MssqlFs {
3122
3327
  async symlink(target, linkPath) {
3123
3328
  const normalized = this.#normalizePath(linkPath);
3124
3329
  const prefixed = this.#prefixPath(normalized);
3125
- const existingRows = await this.#query(
3126
- `SELECT CASE WHEN EXISTS(SELECT 1 FROM ${this.#t("fs_entries")} WHERE path = @p0) THEN 1 ELSE 0 END as [exists]`,
3127
- [prefixed]
3330
+ const existingRows = rowsOf(
3331
+ existsRow,
3332
+ await this.#query(
3333
+ `SELECT CASE WHEN EXISTS(SELECT 1 FROM ${this.#t("fs_entries")} WHERE path = @p0) THEN 1 ELSE 0 END as [exists]`,
3334
+ [prefixed]
3335
+ )
3128
3336
  );
3129
3337
  if (existingRows[0].exists === 1) {
3130
3338
  throw new Error(`EEXIST: file already exists: ${linkPath}`);
@@ -3146,20 +3354,25 @@ var MssqlFs = class _MssqlFs {
3146
3354
  const destNormalized = this.#normalizePath(newPath);
3147
3355
  const srcPrefixed = this.#prefixPath(srcNormalized);
3148
3356
  const destPrefixed = this.#prefixPath(destNormalized);
3149
- const srcRows = await this.#query(
3150
- `SELECT * FROM ${this.#t("fs_entries")} WHERE path = @p0`,
3151
- [srcPrefixed]
3357
+ const [srcEntry] = rowsOf(
3358
+ entryRow2,
3359
+ await this.#query(
3360
+ `SELECT * FROM ${this.#t("fs_entries")} WHERE path = @p0`,
3361
+ [srcPrefixed]
3362
+ )
3152
3363
  );
3153
- const srcEntry = srcRows[0];
3154
3364
  if (!srcEntry) {
3155
3365
  throw new Error(`ENOENT: no such file or directory: ${existingPath}`);
3156
3366
  }
3157
3367
  if (srcEntry.type !== "file") {
3158
3368
  throw new Error(`link: not supported for directories: ${existingPath}`);
3159
3369
  }
3160
- const existingRows = await this.#query(
3161
- `SELECT CASE WHEN EXISTS(SELECT 1 FROM ${this.#t("fs_entries")} WHERE path = @p0) THEN 1 ELSE 0 END as [exists]`,
3162
- [destPrefixed]
3370
+ const existingRows = rowsOf(
3371
+ existsRow,
3372
+ await this.#query(
3373
+ `SELECT CASE WHEN EXISTS(SELECT 1 FROM ${this.#t("fs_entries")} WHERE path = @p0) THEN 1 ELSE 0 END as [exists]`,
3374
+ [destPrefixed]
3375
+ )
3163
3376
  );
3164
3377
  if (existingRows[0].exists === 1) {
3165
3378
  throw new Error(`EEXIST: file already exists: ${newPath}`);
@@ -3177,10 +3390,13 @@ var MssqlFs = class _MssqlFs {
3177
3390
  );
3178
3391
  const chunksReq = transaction.request();
3179
3392
  chunksReq.input("p0", srcPrefixed);
3180
- const chunksResult = await chunksReq.query(
3181
- `SELECT chunkIndex, data FROM ${this.#t("fs_chunks")} WHERE path = @p0`
3393
+ const chunks = rowsOf(
3394
+ chunkRow2,
3395
+ await chunksReq.query(
3396
+ `SELECT chunkIndex, data FROM ${this.#t("fs_chunks")} WHERE path = @p0`
3397
+ )
3182
3398
  );
3183
- for (const chunk of chunksResult.recordset) {
3399
+ for (const chunk of chunks) {
3184
3400
  const chunkInsertReq = transaction.request();
3185
3401
  chunkInsertReq.input("p0", destPrefixed);
3186
3402
  chunkInsertReq.input("p1", chunk.chunkIndex);
@@ -3194,11 +3410,13 @@ var MssqlFs = class _MssqlFs {
3194
3410
  async readlink(linkPath) {
3195
3411
  const normalized = this.#normalizePath(linkPath);
3196
3412
  const prefixed = this.#prefixPath(normalized);
3197
- const rows = await this.#query(
3198
- `SELECT type, symlinkTarget FROM ${this.#t("fs_entries")} WHERE path = @p0`,
3199
- [prefixed]
3413
+ const [entry] = rowsOf(
3414
+ linkRow2,
3415
+ await this.#query(
3416
+ `SELECT type, symlinkTarget FROM ${this.#t("fs_entries")} WHERE path = @p0`,
3417
+ [prefixed]
3418
+ )
3200
3419
  );
3201
- const entry = rows[0];
3202
3420
  if (!entry) {
3203
3421
  throw new Error(`ENOENT: no such file or directory: ${linkPath}`);
3204
3422
  }
@@ -3212,6 +3430,7 @@ var MssqlFs = class _MssqlFs {
3212
3430
  // packages/text2sql/src/lib/fs/postgres/postgres-fs.ts
3213
3431
  import { createRequire as createRequire2 } from "node:module";
3214
3432
  import * as path5 from "node:path";
3433
+ import z8 from "zod";
3215
3434
 
3216
3435
  // packages/text2sql/src/lib/fs/postgres/ddl.postgres-fs.ts
3217
3436
  function postgresFsDDL(schema) {
@@ -3240,6 +3459,33 @@ CREATE TABLE IF NOT EXISTS "${schema}"."fs_chunks" (
3240
3459
  }
3241
3460
 
3242
3461
  // packages/text2sql/src/lib/fs/postgres/postgres-fs.ts
3462
+ var entryRow3 = z8.object({
3463
+ path: z8.string(),
3464
+ type: entryType,
3465
+ mode: z8.number(),
3466
+ size: bigintColumn,
3467
+ mtime: bigintColumn,
3468
+ symlink_target: z8.string().nullable()
3469
+ });
3470
+ var typeRow3 = entryRow3.pick({ type: true });
3471
+ var pathRow3 = entryRow3.pick({ path: true });
3472
+ var pathTypeRow3 = entryRow3.pick({ path: true, type: true });
3473
+ var linkRow3 = z8.discriminatedUnion("type", [
3474
+ z8.object({ type: z8.literal("symlink"), symlink_target: z8.string() }),
3475
+ z8.object({
3476
+ type: z8.enum(["file", "directory"]),
3477
+ symlink_target: z8.string().nullable()
3478
+ })
3479
+ ]);
3480
+ var existsRow2 = z8.object({ exists: z8.boolean() });
3481
+ var chunkRow3 = z8.object({
3482
+ chunk_index: z8.number(),
3483
+ data: z8.instanceof(Buffer)
3484
+ });
3485
+ var dataRow3 = chunkRow3.pick({ data: true });
3486
+ function rowsOf2(row, result) {
3487
+ return z8.array(row).parse(result.rows);
3488
+ }
3243
3489
  var PostgresFs = class _PostgresFs {
3244
3490
  #pool;
3245
3491
  #chunkSize;
@@ -3281,8 +3527,11 @@ var PostgresFs = class _PostgresFs {
3281
3527
  async initialize() {
3282
3528
  const ddl = postgresFsDDL(this.#schema);
3283
3529
  await this.#pool.query(ddl);
3284
- const rootSlashExists = await this.#rawQuery(
3285
- `SELECT EXISTS(SELECT 1 FROM ${this.#t("fs_entries")} WHERE path = '/') AS exists`
3530
+ const rootSlashExists = rowsOf2(
3531
+ existsRow2,
3532
+ await this.#rawQuery(
3533
+ `SELECT EXISTS(SELECT 1 FROM ${this.#t("fs_entries")} WHERE path = '/') AS exists`
3534
+ )
3286
3535
  );
3287
3536
  if (!rootSlashExists[0].exists) {
3288
3537
  await this.#rawExec(
@@ -3292,9 +3541,12 @@ var PostgresFs = class _PostgresFs {
3292
3541
  }
3293
3542
  if (this.#root) {
3294
3543
  await this.#createParentDirs(this.#root);
3295
- const rootExists = await this.#rawQuery(
3296
- `SELECT EXISTS(SELECT 1 FROM ${this.#t("fs_entries")} WHERE path = $1) AS exists`,
3297
- [this.#root]
3544
+ const rootExists = rowsOf2(
3545
+ existsRow2,
3546
+ await this.#rawQuery(
3547
+ `SELECT EXISTS(SELECT 1 FROM ${this.#t("fs_entries")} WHERE path = $1) AS exists`,
3548
+ [this.#root]
3549
+ )
3298
3550
  );
3299
3551
  if (!rootExists[0].exists) {
3300
3552
  await this.#rawExec(
@@ -3317,9 +3569,12 @@ var PostgresFs = class _PostgresFs {
3317
3569
  let currentPath = "/";
3318
3570
  for (let i = 0; i < segments.length - 1; i++) {
3319
3571
  currentPath = path5.posix.join(currentPath, segments[i]);
3320
- const exists = await this.#rawQuery(
3321
- `SELECT EXISTS(SELECT 1 FROM ${this.#t("fs_entries")} WHERE path = $1) AS exists`,
3322
- [currentPath]
3572
+ const exists = rowsOf2(
3573
+ existsRow2,
3574
+ await this.#rawQuery(
3575
+ `SELECT EXISTS(SELECT 1 FROM ${this.#t("fs_entries")} WHERE path = $1) AS exists`,
3576
+ [currentPath]
3577
+ )
3323
3578
  );
3324
3579
  if (!exists[0].exists) {
3325
3580
  await this.#rawExec(
@@ -3329,9 +3584,8 @@ var PostgresFs = class _PostgresFs {
3329
3584
  }
3330
3585
  }
3331
3586
  }
3332
- async #rawQuery(sql, params) {
3333
- const result = await this.#pool.query(sql, params);
3334
- return result.rows;
3587
+ #rawQuery(sql, params) {
3588
+ return this.#pool.query(sql, params);
3335
3589
  }
3336
3590
  async #rawExec(sql, params) {
3337
3591
  const result = await this.#pool.query(sql, params);
@@ -3395,11 +3649,13 @@ var PostgresFs = class _PostgresFs {
3395
3649
  const parent = this.#dirname(filePath);
3396
3650
  const rootPath = this.#root || "/";
3397
3651
  if (parent === rootPath || parent === "/") return;
3398
- const result = await client.query(
3399
- `SELECT type FROM ${this.#t("fs_entries")} WHERE path = $1`,
3400
- [parent]
3652
+ const [entry] = rowsOf2(
3653
+ typeRow3,
3654
+ await client.query(
3655
+ `SELECT type FROM ${this.#t("fs_entries")} WHERE path = $1`,
3656
+ [parent]
3657
+ )
3401
3658
  );
3402
- const entry = result.rows[0];
3403
3659
  if (!entry) {
3404
3660
  await this.#ensureParentExists(parent, client);
3405
3661
  await client.query(
@@ -3426,19 +3682,11 @@ var PostgresFs = class _PostgresFs {
3426
3682
  }
3427
3683
  }
3428
3684
  async #readChunks(filePath, client) {
3429
- let rows;
3430
- if (client) {
3431
- const result2 = await client.query(
3432
- `SELECT data FROM ${this.#t("fs_chunks")} WHERE path = $1 ORDER BY chunk_index`,
3433
- [filePath]
3434
- );
3435
- rows = result2.rows;
3436
- } else {
3437
- rows = await this.#query(
3438
- `SELECT data FROM ${this.#t("fs_chunks")} WHERE path = $1 ORDER BY chunk_index`,
3439
- [filePath]
3440
- );
3441
- }
3685
+ const sql = `SELECT data FROM ${this.#t("fs_chunks")} WHERE path = $1 ORDER BY chunk_index`;
3686
+ const rows = rowsOf2(
3687
+ dataRow3,
3688
+ client ? await client.query(sql, [filePath]) : await this.#query(sql, [filePath])
3689
+ );
3442
3690
  if (rows.length === 0) {
3443
3691
  return new Uint8Array(0);
3444
3692
  }
@@ -3455,11 +3703,13 @@ var PostgresFs = class _PostgresFs {
3455
3703
  if (seen.has(p)) {
3456
3704
  throw new Error(`readFile: circular symlink: ${p}`);
3457
3705
  }
3458
- const rows = await this.#query(
3459
- `SELECT type, symlink_target FROM ${this.#t("fs_entries")} WHERE path = $1`,
3460
- [p]
3706
+ const [entry] = rowsOf2(
3707
+ linkRow3,
3708
+ await this.#query(
3709
+ `SELECT type, symlink_target FROM ${this.#t("fs_entries")} WHERE path = $1`,
3710
+ [p]
3711
+ )
3461
3712
  );
3462
- const entry = rows[0];
3463
3713
  if (!entry) {
3464
3714
  throw new Error(`ENOENT: no such file or directory: ${p}`);
3465
3715
  }
@@ -3476,8 +3726,7 @@ var PostgresFs = class _PostgresFs {
3476
3726
  if (content instanceof Uint8Array) {
3477
3727
  return content;
3478
3728
  }
3479
- const enc = encoding ?? "utf8";
3480
- return new Uint8Array(Buffer.from(content, enc));
3729
+ return new Uint8Array(Buffer.from(content, encoding ?? "utf8"));
3481
3730
  }
3482
3731
  async close() {
3483
3732
  if (this.#ownsPool) {
@@ -3491,11 +3740,13 @@ var PostgresFs = class _PostgresFs {
3491
3740
  const normalized = this.#normalizePath(filePath);
3492
3741
  const prefixed = this.#prefixPath(normalized);
3493
3742
  const resolved = await this.#resolveSymlink(prefixed);
3494
- const rows = await this.#query(
3495
- `SELECT type FROM ${this.#t("fs_entries")} WHERE path = $1`,
3496
- [resolved]
3743
+ const [entry] = rowsOf2(
3744
+ typeRow3,
3745
+ await this.#query(
3746
+ `SELECT type FROM ${this.#t("fs_entries")} WHERE path = $1`,
3747
+ [resolved]
3748
+ )
3497
3749
  );
3498
- const entry = rows[0];
3499
3750
  if (!entry) {
3500
3751
  throw new Error(`ENOENT: no such file or directory: ${filePath}`);
3501
3752
  }
@@ -3510,11 +3761,13 @@ var PostgresFs = class _PostgresFs {
3510
3761
  const normalized = this.#normalizePath(filePath);
3511
3762
  const prefixed = this.#prefixPath(normalized);
3512
3763
  const resolved = await this.#resolveSymlink(prefixed);
3513
- const rows = await this.#query(
3514
- `SELECT type FROM ${this.#t("fs_entries")} WHERE path = $1`,
3515
- [resolved]
3764
+ const [entry] = rowsOf2(
3765
+ typeRow3,
3766
+ await this.#query(
3767
+ `SELECT type FROM ${this.#t("fs_entries")} WHERE path = $1`,
3768
+ [resolved]
3769
+ )
3516
3770
  );
3517
- const entry = rows[0];
3518
3771
  if (!entry) {
3519
3772
  throw new Error(`ENOENT: no such file or directory: ${filePath}`);
3520
3773
  }
@@ -3546,11 +3799,13 @@ var PostgresFs = class _PostgresFs {
3546
3799
  const newData = this.#toUint8Array(content, encoding);
3547
3800
  await this.#useTransaction(async (client) => {
3548
3801
  await this.#ensureParentExists(prefixed, client);
3549
- const result = await client.query(
3550
- `SELECT type FROM ${this.#t("fs_entries")} WHERE path = $1`,
3551
- [prefixed]
3802
+ const [entry] = rowsOf2(
3803
+ typeRow3,
3804
+ await client.query(
3805
+ `SELECT type FROM ${this.#t("fs_entries")} WHERE path = $1`,
3806
+ [prefixed]
3807
+ )
3552
3808
  );
3553
- const entry = result.rows[0];
3554
3809
  if (entry && entry.type !== "file") {
3555
3810
  throw new Error(`appendFile: not a file: ${filePath}`);
3556
3811
  }
@@ -3570,9 +3825,12 @@ var PostgresFs = class _PostgresFs {
3570
3825
  async exists(filePath) {
3571
3826
  const normalized = this.#normalizePath(filePath);
3572
3827
  const prefixed = this.#prefixPath(normalized);
3573
- const rows = await this.#query(
3574
- `SELECT EXISTS(SELECT 1 FROM ${this.#t("fs_entries")} WHERE path = $1) AS exists`,
3575
- [prefixed]
3828
+ const rows = rowsOf2(
3829
+ existsRow2,
3830
+ await this.#query(
3831
+ `SELECT EXISTS(SELECT 1 FROM ${this.#t("fs_entries")} WHERE path = $1) AS exists`,
3832
+ [prefixed]
3833
+ )
3576
3834
  );
3577
3835
  return rows[0].exists;
3578
3836
  }
@@ -3580,11 +3838,13 @@ var PostgresFs = class _PostgresFs {
3580
3838
  const normalized = this.#normalizePath(filePath);
3581
3839
  const prefixed = this.#prefixPath(normalized);
3582
3840
  const resolved = await this.#resolveSymlink(prefixed);
3583
- const rows = await this.#query(
3584
- `SELECT * FROM ${this.#t("fs_entries")} WHERE path = $1`,
3585
- [resolved]
3841
+ const [entry] = rowsOf2(
3842
+ entryRow3,
3843
+ await this.#query(
3844
+ `SELECT * FROM ${this.#t("fs_entries")} WHERE path = $1`,
3845
+ [resolved]
3846
+ )
3586
3847
  );
3587
- const entry = rows[0];
3588
3848
  if (!entry) {
3589
3849
  throw new Error(`ENOENT: no such file or directory: ${filePath}`);
3590
3850
  }
@@ -3592,19 +3852,21 @@ var PostgresFs = class _PostgresFs {
3592
3852
  isFile: entry.type === "file",
3593
3853
  isDirectory: entry.type === "directory",
3594
3854
  isSymbolicLink: false,
3595
- mode: Number(entry.mode),
3596
- size: Number(entry.size),
3597
- mtime: new Date(Number(entry.mtime))
3855
+ mode: entry.mode,
3856
+ size: entry.size,
3857
+ mtime: new Date(entry.mtime)
3598
3858
  };
3599
3859
  }
3600
3860
  async lstat(filePath) {
3601
3861
  const normalized = this.#normalizePath(filePath);
3602
3862
  const prefixed = this.#prefixPath(normalized);
3603
- const rows = await this.#query(
3604
- `SELECT * FROM ${this.#t("fs_entries")} WHERE path = $1`,
3605
- [prefixed]
3863
+ const [entry] = rowsOf2(
3864
+ entryRow3,
3865
+ await this.#query(
3866
+ `SELECT * FROM ${this.#t("fs_entries")} WHERE path = $1`,
3867
+ [prefixed]
3868
+ )
3606
3869
  );
3607
- const entry = rows[0];
3608
3870
  if (!entry) {
3609
3871
  throw new Error(`ENOENT: no such file or directory: ${filePath}`);
3610
3872
  }
@@ -3612,19 +3874,21 @@ var PostgresFs = class _PostgresFs {
3612
3874
  isFile: entry.type === "file",
3613
3875
  isDirectory: entry.type === "directory",
3614
3876
  isSymbolicLink: entry.type === "symlink",
3615
- mode: Number(entry.mode),
3616
- size: Number(entry.size),
3617
- mtime: new Date(Number(entry.mtime))
3877
+ mode: entry.mode,
3878
+ size: entry.size,
3879
+ mtime: new Date(entry.mtime)
3618
3880
  };
3619
3881
  }
3620
3882
  async mkdir(dirPath, options) {
3621
3883
  const normalized = this.#normalizePath(dirPath);
3622
3884
  const prefixed = this.#prefixPath(normalized);
3623
- const existingRows = await this.#query(
3624
- `SELECT type FROM ${this.#t("fs_entries")} WHERE path = $1`,
3625
- [prefixed]
3885
+ const [existing] = rowsOf2(
3886
+ typeRow3,
3887
+ await this.#query(
3888
+ `SELECT type FROM ${this.#t("fs_entries")} WHERE path = $1`,
3889
+ [prefixed]
3890
+ )
3626
3891
  );
3627
- const existing = existingRows[0];
3628
3892
  if (existing) {
3629
3893
  if (options?.recursive) {
3630
3894
  return;
@@ -3639,11 +3903,13 @@ var PostgresFs = class _PostgresFs {
3639
3903
  let currentPath = rootPath;
3640
3904
  for (const segment of segments) {
3641
3905
  currentPath = path5.posix.join(currentPath, segment);
3642
- const result = await client.query(
3643
- `SELECT type FROM ${this.#t("fs_entries")} WHERE path = $1`,
3644
- [currentPath]
3906
+ const [exists] = rowsOf2(
3907
+ typeRow3,
3908
+ await client.query(
3909
+ `SELECT type FROM ${this.#t("fs_entries")} WHERE path = $1`,
3910
+ [currentPath]
3911
+ )
3645
3912
  );
3646
- const exists = result.rows[0];
3647
3913
  if (!exists) {
3648
3914
  await client.query(
3649
3915
  `INSERT INTO ${this.#t("fs_entries")} (path, type, mode, size, mtime) VALUES ($1, 'directory', 493, 0, $2)`,
@@ -3655,11 +3921,13 @@ var PostgresFs = class _PostgresFs {
3655
3921
  }
3656
3922
  } else {
3657
3923
  const parent = this.#dirname(prefixed);
3658
- const parentResult = await client.query(
3659
- `SELECT type FROM ${this.#t("fs_entries")} WHERE path = $1`,
3660
- [parent]
3924
+ const [parentEntry] = rowsOf2(
3925
+ typeRow3,
3926
+ await client.query(
3927
+ `SELECT type FROM ${this.#t("fs_entries")} WHERE path = $1`,
3928
+ [parent]
3929
+ )
3661
3930
  );
3662
- const parentEntry = parentResult.rows[0];
3663
3931
  if (!parentEntry) {
3664
3932
  throw new Error(`mkdir: parent does not exist: ${parent}`);
3665
3933
  }
@@ -3677,11 +3945,13 @@ var PostgresFs = class _PostgresFs {
3677
3945
  const normalized = this.#normalizePath(dirPath);
3678
3946
  const prefixed = this.#prefixPath(normalized);
3679
3947
  const resolved = await this.#resolveSymlink(prefixed);
3680
- const entryRows = await this.#query(
3681
- `SELECT type FROM ${this.#t("fs_entries")} WHERE path = $1`,
3682
- [resolved]
3948
+ const [entry] = rowsOf2(
3949
+ typeRow3,
3950
+ await this.#query(
3951
+ `SELECT type FROM ${this.#t("fs_entries")} WHERE path = $1`,
3952
+ [resolved]
3953
+ )
3683
3954
  );
3684
- const entry = entryRows[0];
3685
3955
  if (!entry) {
3686
3956
  throw new Error(`ENOENT: no such file or directory: ${dirPath}`);
3687
3957
  }
@@ -3689,12 +3959,15 @@ var PostgresFs = class _PostgresFs {
3689
3959
  throw new Error(`ENOTDIR: not a directory: ${dirPath}`);
3690
3960
  }
3691
3961
  const prefix = resolved === "/" ? "/" : resolved + "/";
3692
- const rows = await this.#query(
3693
- `SELECT path FROM ${this.#t("fs_entries")}
3962
+ const rows = rowsOf2(
3963
+ pathRow3,
3964
+ await this.#query(
3965
+ `SELECT path FROM ${this.#t("fs_entries")}
3694
3966
  WHERE path LIKE $1 || '%'
3695
3967
  AND path != $2
3696
3968
  AND path NOT LIKE $1 || '%/%'`,
3697
- [prefix, resolved]
3969
+ [prefix, resolved]
3970
+ )
3698
3971
  );
3699
3972
  return rows.map((row) => path5.posix.basename(row.path));
3700
3973
  }
@@ -3702,11 +3975,13 @@ var PostgresFs = class _PostgresFs {
3702
3975
  const normalized = this.#normalizePath(dirPath);
3703
3976
  const prefixed = this.#prefixPath(normalized);
3704
3977
  const resolved = await this.#resolveSymlink(prefixed);
3705
- const entryRows = await this.#query(
3706
- `SELECT type FROM ${this.#t("fs_entries")} WHERE path = $1`,
3707
- [resolved]
3978
+ const [entry] = rowsOf2(
3979
+ typeRow3,
3980
+ await this.#query(
3981
+ `SELECT type FROM ${this.#t("fs_entries")} WHERE path = $1`,
3982
+ [resolved]
3983
+ )
3708
3984
  );
3709
- const entry = entryRows[0];
3710
3985
  if (!entry) {
3711
3986
  throw new Error(`ENOENT: no such file or directory: ${dirPath}`);
3712
3987
  }
@@ -3714,12 +3989,15 @@ var PostgresFs = class _PostgresFs {
3714
3989
  throw new Error(`ENOTDIR: not a directory: ${dirPath}`);
3715
3990
  }
3716
3991
  const prefix = resolved === "/" ? "/" : resolved + "/";
3717
- const rows = await this.#query(
3718
- `SELECT path, type FROM ${this.#t("fs_entries")}
3992
+ const rows = rowsOf2(
3993
+ pathTypeRow3,
3994
+ await this.#query(
3995
+ `SELECT path, type FROM ${this.#t("fs_entries")}
3719
3996
  WHERE path LIKE $1 || '%'
3720
3997
  AND path != $2
3721
3998
  AND path NOT LIKE $1 || '%/%'`,
3722
- [prefix, resolved]
3999
+ [prefix, resolved]
4000
+ )
3723
4001
  );
3724
4002
  return rows.map((row) => ({
3725
4003
  name: path5.posix.basename(row.path),
@@ -3731,11 +4009,13 @@ var PostgresFs = class _PostgresFs {
3731
4009
  async rm(filePath, options) {
3732
4010
  const normalized = this.#normalizePath(filePath);
3733
4011
  const prefixed = this.#prefixPath(normalized);
3734
- const rows = await this.#query(
3735
- `SELECT type FROM ${this.#t("fs_entries")} WHERE path = $1`,
3736
- [prefixed]
4012
+ const [entry] = rowsOf2(
4013
+ typeRow3,
4014
+ await this.#query(
4015
+ `SELECT type FROM ${this.#t("fs_entries")} WHERE path = $1`,
4016
+ [prefixed]
4017
+ )
3737
4018
  );
3738
- const entry = rows[0];
3739
4019
  if (!entry) {
3740
4020
  if (options?.force) {
3741
4021
  return;
@@ -3744,11 +4024,14 @@ var PostgresFs = class _PostgresFs {
3744
4024
  }
3745
4025
  await this.#useTransaction(async (client) => {
3746
4026
  if (entry.type === "directory") {
3747
- const childrenResult = await client.query(
3748
- `SELECT EXISTS(SELECT 1 FROM ${this.#t("fs_entries")} WHERE path LIKE $1 || '/%') AS exists`,
3749
- [prefixed]
4027
+ const children = rowsOf2(
4028
+ existsRow2,
4029
+ await client.query(
4030
+ `SELECT EXISTS(SELECT 1 FROM ${this.#t("fs_entries")} WHERE path LIKE $1 || '/%') AS exists`,
4031
+ [prefixed]
4032
+ )
3750
4033
  );
3751
- if (childrenResult.rows[0].exists && !options?.recursive) {
4034
+ if (children[0].exists && !options?.recursive) {
3752
4035
  throw new Error(`ENOTEMPTY: directory not empty: ${filePath}`);
3753
4036
  }
3754
4037
  await client.query(
@@ -3768,11 +4051,13 @@ var PostgresFs = class _PostgresFs {
3768
4051
  const destNormalized = this.#normalizePath(dest);
3769
4052
  const srcPrefixed = this.#prefixPath(srcNormalized);
3770
4053
  const destPrefixed = this.#prefixPath(destNormalized);
3771
- const srcRows = await this.#query(
3772
- `SELECT * FROM ${this.#t("fs_entries")} WHERE path = $1`,
3773
- [srcPrefixed]
4054
+ const [srcEntry] = rowsOf2(
4055
+ entryRow3,
4056
+ await this.#query(
4057
+ `SELECT * FROM ${this.#t("fs_entries")} WHERE path = $1`,
4058
+ [srcPrefixed]
4059
+ )
3774
4060
  );
3775
- const srcEntry = srcRows[0];
3776
4061
  if (!srcEntry) {
3777
4062
  throw new Error(`ENOENT: no such file or directory: ${src}`);
3778
4063
  }
@@ -3782,11 +4067,14 @@ var PostgresFs = class _PostgresFs {
3782
4067
  await this.#useTransaction(async (client) => {
3783
4068
  await this.#ensureParentExists(destPrefixed, client);
3784
4069
  if (srcEntry.type === "directory") {
3785
- const allEntriesResult = await client.query(
3786
- `SELECT * FROM ${this.#t("fs_entries")} WHERE path = $1 OR path LIKE $1 || '/%'`,
3787
- [srcPrefixed]
4070
+ const allEntries = rowsOf2(
4071
+ entryRow3,
4072
+ await client.query(
4073
+ `SELECT * FROM ${this.#t("fs_entries")} WHERE path = $1 OR path LIKE $1 || '/%'`,
4074
+ [srcPrefixed]
4075
+ )
3788
4076
  );
3789
- for (const entry of allEntriesResult.rows) {
4077
+ for (const entry of allEntries) {
3790
4078
  const relativePath = path5.posix.relative(srcPrefixed, entry.path);
3791
4079
  const newPath = path5.posix.join(destPrefixed, relativePath);
3792
4080
  await client.query(
@@ -3807,11 +4095,14 @@ var PostgresFs = class _PostgresFs {
3807
4095
  `DELETE FROM ${this.#t("fs_chunks")} WHERE path = $1`,
3808
4096
  [newPath]
3809
4097
  );
3810
- const chunksResult = await client.query(
3811
- `SELECT chunk_index, data FROM ${this.#t("fs_chunks")} WHERE path = $1`,
3812
- [entry.path]
4098
+ const chunks = rowsOf2(
4099
+ chunkRow3,
4100
+ await client.query(
4101
+ `SELECT chunk_index, data FROM ${this.#t("fs_chunks")} WHERE path = $1`,
4102
+ [entry.path]
4103
+ )
3813
4104
  );
3814
- for (const chunk of chunksResult.rows) {
4105
+ for (const chunk of chunks) {
3815
4106
  await client.query(
3816
4107
  `INSERT INTO ${this.#t("fs_chunks")} (path, chunk_index, data) VALUES ($1, $2, $3)`,
3817
4108
  [newPath, chunk.chunk_index, chunk.data]
@@ -3834,15 +4125,18 @@ var PostgresFs = class _PostgresFs {
3834
4125
  ]
3835
4126
  );
3836
4127
  if (srcEntry.type === "file") {
3837
- const chunksResult = await client.query(
3838
- `SELECT chunk_index, data FROM ${this.#t("fs_chunks")} WHERE path = $1`,
3839
- [srcPrefixed]
4128
+ const chunks = rowsOf2(
4129
+ chunkRow3,
4130
+ await client.query(
4131
+ `SELECT chunk_index, data FROM ${this.#t("fs_chunks")} WHERE path = $1`,
4132
+ [srcPrefixed]
4133
+ )
3840
4134
  );
3841
4135
  await client.query(
3842
4136
  `DELETE FROM ${this.#t("fs_chunks")} WHERE path = $1`,
3843
4137
  [destPrefixed]
3844
4138
  );
3845
- for (const chunk of chunksResult.rows) {
4139
+ for (const chunk of chunks) {
3846
4140
  await client.query(
3847
4141
  `INSERT INTO ${this.#t("fs_chunks")} (path, chunk_index, data) VALUES ($1, $2, $3)`,
3848
4142
  [destPrefixed, chunk.chunk_index, chunk.data]
@@ -3857,26 +4151,31 @@ var PostgresFs = class _PostgresFs {
3857
4151
  const destNormalized = this.#normalizePath(dest);
3858
4152
  const srcPrefixed = this.#prefixPath(srcNormalized);
3859
4153
  const destPrefixed = this.#prefixPath(destNormalized);
3860
- const srcRows = await this.#query(
3861
- `SELECT * FROM ${this.#t("fs_entries")} WHERE path = $1`,
3862
- [srcPrefixed]
4154
+ const [srcEntry] = rowsOf2(
4155
+ entryRow3,
4156
+ await this.#query(
4157
+ `SELECT * FROM ${this.#t("fs_entries")} WHERE path = $1`,
4158
+ [srcPrefixed]
4159
+ )
3863
4160
  );
3864
- const srcEntry = srcRows[0];
3865
4161
  if (!srcEntry) {
3866
4162
  throw new Error(`ENOENT: no such file or directory: ${src}`);
3867
4163
  }
3868
4164
  await this.#useTransaction(async (client) => {
3869
4165
  await this.#ensureParentExists(destPrefixed, client);
3870
4166
  if (srcEntry.type === "directory") {
3871
- const allEntriesResult = await client.query(
3872
- `SELECT * FROM ${this.#t("fs_entries")} WHERE path = $1 OR path LIKE $1 || '/%' ORDER BY path DESC`,
3873
- [srcPrefixed]
4167
+ const allEntries = rowsOf2(
4168
+ entryRow3,
4169
+ await client.query(
4170
+ `SELECT * FROM ${this.#t("fs_entries")} WHERE path = $1 OR path LIKE $1 || '/%' ORDER BY path DESC`,
4171
+ [srcPrefixed]
4172
+ )
3874
4173
  );
3875
4174
  await client.query(
3876
4175
  `DELETE FROM ${this.#t("fs_entries")} WHERE path = $1 OR path LIKE $1 || '/%'`,
3877
4176
  [destPrefixed]
3878
4177
  );
3879
- for (const entry of [...allEntriesResult.rows].reverse()) {
4178
+ for (const entry of [...allEntries].reverse()) {
3880
4179
  const relativePath = path5.posix.relative(srcPrefixed, entry.path);
3881
4180
  const newPath = path5.posix.join(destPrefixed, relativePath);
3882
4181
  await client.query(
@@ -3897,11 +4196,14 @@ var PostgresFs = class _PostgresFs {
3897
4196
  `DELETE FROM ${this.#t("fs_chunks")} WHERE path = $1`,
3898
4197
  [newPath]
3899
4198
  );
3900
- const chunksResult = await client.query(
3901
- `SELECT chunk_index, data FROM ${this.#t("fs_chunks")} WHERE path = $1`,
3902
- [entry.path]
4199
+ const chunks = rowsOf2(
4200
+ chunkRow3,
4201
+ await client.query(
4202
+ `SELECT chunk_index, data FROM ${this.#t("fs_chunks")} WHERE path = $1`,
4203
+ [entry.path]
4204
+ )
3903
4205
  );
3904
- for (const chunk of chunksResult.rows) {
4206
+ for (const chunk of chunks) {
3905
4207
  await client.query(
3906
4208
  `INSERT INTO ${this.#t("fs_chunks")} (path, chunk_index, data) VALUES ($1, $2, $3)`,
3907
4209
  [newPath, chunk.chunk_index, chunk.data]
@@ -3932,11 +4234,14 @@ var PostgresFs = class _PostgresFs {
3932
4234
  `DELETE FROM ${this.#t("fs_chunks")} WHERE path = $1`,
3933
4235
  [destPrefixed]
3934
4236
  );
3935
- const chunksResult = await client.query(
3936
- `SELECT chunk_index, data FROM ${this.#t("fs_chunks")} WHERE path = $1`,
3937
- [srcPrefixed]
4237
+ const chunks = rowsOf2(
4238
+ chunkRow3,
4239
+ await client.query(
4240
+ `SELECT chunk_index, data FROM ${this.#t("fs_chunks")} WHERE path = $1`,
4241
+ [srcPrefixed]
4242
+ )
3938
4243
  );
3939
- for (const chunk of chunksResult.rows) {
4244
+ for (const chunk of chunks) {
3940
4245
  await client.query(
3941
4246
  `INSERT INTO ${this.#t("fs_chunks")} (path, chunk_index, data) VALUES ($1, $2, $3)`,
3942
4247
  [destPrefixed, chunk.chunk_index, chunk.data]
@@ -3959,8 +4264,11 @@ var PostgresFs = class _PostgresFs {
3959
4264
  );
3960
4265
  }
3961
4266
  async getAllPathsAsync() {
3962
- const rows = await this.#query(
3963
- `SELECT path FROM ${this.#t("fs_entries")} ORDER BY path`
4267
+ const rows = rowsOf2(
4268
+ pathRow3,
4269
+ await this.#query(
4270
+ `SELECT path FROM ${this.#t("fs_entries")} ORDER BY path`
4271
+ )
3964
4272
  );
3965
4273
  return rows.map((row) => row.path);
3966
4274
  }
@@ -3968,9 +4276,12 @@ var PostgresFs = class _PostgresFs {
3968
4276
  const normalized = this.#normalizePath(filePath);
3969
4277
  const prefixed = this.#prefixPath(normalized);
3970
4278
  const resolved = await this.#resolveSymlink(prefixed);
3971
- const rows = await this.#query(
3972
- `SELECT EXISTS(SELECT 1 FROM ${this.#t("fs_entries")} WHERE path = $1) AS exists`,
3973
- [resolved]
4279
+ const rows = rowsOf2(
4280
+ existsRow2,
4281
+ await this.#query(
4282
+ `SELECT EXISTS(SELECT 1 FROM ${this.#t("fs_entries")} WHERE path = $1) AS exists`,
4283
+ [resolved]
4284
+ )
3974
4285
  );
3975
4286
  if (!rows[0].exists) {
3976
4287
  throw new Error(`ENOENT: no such file or directory: ${filePath}`);
@@ -4003,9 +4314,12 @@ var PostgresFs = class _PostgresFs {
4003
4314
  async symlink(target, linkPath) {
4004
4315
  const normalized = this.#normalizePath(linkPath);
4005
4316
  const prefixed = this.#prefixPath(normalized);
4006
- const existingRows = await this.#query(
4007
- `SELECT EXISTS(SELECT 1 FROM ${this.#t("fs_entries")} WHERE path = $1) AS exists`,
4008
- [prefixed]
4317
+ const existingRows = rowsOf2(
4318
+ existsRow2,
4319
+ await this.#query(
4320
+ `SELECT EXISTS(SELECT 1 FROM ${this.#t("fs_entries")} WHERE path = $1) AS exists`,
4321
+ [prefixed]
4322
+ )
4009
4323
  );
4010
4324
  if (existingRows[0].exists) {
4011
4325
  throw new Error(`EEXIST: file already exists: ${linkPath}`);
@@ -4024,20 +4338,25 @@ var PostgresFs = class _PostgresFs {
4024
4338
  const destNormalized = this.#normalizePath(newPath);
4025
4339
  const srcPrefixed = this.#prefixPath(srcNormalized);
4026
4340
  const destPrefixed = this.#prefixPath(destNormalized);
4027
- const srcRows = await this.#query(
4028
- `SELECT * FROM ${this.#t("fs_entries")} WHERE path = $1`,
4029
- [srcPrefixed]
4341
+ const [srcEntry] = rowsOf2(
4342
+ entryRow3,
4343
+ await this.#query(
4344
+ `SELECT * FROM ${this.#t("fs_entries")} WHERE path = $1`,
4345
+ [srcPrefixed]
4346
+ )
4030
4347
  );
4031
- const srcEntry = srcRows[0];
4032
4348
  if (!srcEntry) {
4033
4349
  throw new Error(`ENOENT: no such file or directory: ${existingPath}`);
4034
4350
  }
4035
4351
  if (srcEntry.type !== "file") {
4036
4352
  throw new Error(`link: not supported for directories: ${existingPath}`);
4037
4353
  }
4038
- const existingRows = await this.#query(
4039
- `SELECT EXISTS(SELECT 1 FROM ${this.#t("fs_entries")} WHERE path = $1) AS exists`,
4040
- [destPrefixed]
4354
+ const existingRows = rowsOf2(
4355
+ existsRow2,
4356
+ await this.#query(
4357
+ `SELECT EXISTS(SELECT 1 FROM ${this.#t("fs_entries")} WHERE path = $1) AS exists`,
4358
+ [destPrefixed]
4359
+ )
4041
4360
  );
4042
4361
  if (existingRows[0].exists) {
4043
4362
  throw new Error(`EEXIST: file already exists: ${newPath}`);
@@ -4049,11 +4368,14 @@ var PostgresFs = class _PostgresFs {
4049
4368
  VALUES ($1, 'file', $2, $3, $4)`,
4050
4369
  [destPrefixed, srcEntry.mode, srcEntry.size, Date.now()]
4051
4370
  );
4052
- const chunksResult = await client.query(
4053
- `SELECT chunk_index, data FROM ${this.#t("fs_chunks")} WHERE path = $1`,
4054
- [srcPrefixed]
4371
+ const chunks = rowsOf2(
4372
+ chunkRow3,
4373
+ await client.query(
4374
+ `SELECT chunk_index, data FROM ${this.#t("fs_chunks")} WHERE path = $1`,
4375
+ [srcPrefixed]
4376
+ )
4055
4377
  );
4056
- for (const chunk of chunksResult.rows) {
4378
+ for (const chunk of chunks) {
4057
4379
  await client.query(
4058
4380
  `INSERT INTO ${this.#t("fs_chunks")} (path, chunk_index, data) VALUES ($1, $2, $3)`,
4059
4381
  [destPrefixed, chunk.chunk_index, chunk.data]
@@ -4064,11 +4386,13 @@ var PostgresFs = class _PostgresFs {
4064
4386
  async readlink(linkPath) {
4065
4387
  const normalized = this.#normalizePath(linkPath);
4066
4388
  const prefixed = this.#prefixPath(normalized);
4067
- const rows = await this.#query(
4068
- `SELECT type, symlink_target FROM ${this.#t("fs_entries")} WHERE path = $1`,
4069
- [prefixed]
4389
+ const [entry] = rowsOf2(
4390
+ linkRow3,
4391
+ await this.#query(
4392
+ `SELECT type, symlink_target FROM ${this.#t("fs_entries")} WHERE path = $1`,
4393
+ [prefixed]
4394
+ )
4070
4395
  );
4071
- const entry = rows[0];
4072
4396
  if (!entry) {
4073
4397
  throw new Error(`ENOENT: no such file or directory: ${linkPath}`);
4074
4398
  }
@@ -4583,12 +4907,11 @@ import {
4583
4907
  BashException,
4584
4908
  asStaticWordText as asStaticWordText2
4585
4909
  } from "@deepagents/context";
4910
+ function isRecord(value) {
4911
+ return typeof value === "object" && value !== null;
4912
+ }
4586
4913
  function isScriptNode(value) {
4587
- if (typeof value !== "object" || value === null) {
4588
- return false;
4589
- }
4590
- const node = value;
4591
- return node.type === "Script" && Array.isArray(node.statements);
4914
+ return isRecord(value) && value.type === "Script" && Array.isArray(value.statements);
4592
4915
  }
4593
4916
  var BLOCKED_DB_CLIENT_COMMANDS = /* @__PURE__ */ new Set([
4594
4917
  "psql",
@@ -4678,11 +5001,7 @@ function wordContainsBlockedCommand(word, context, mode) {
4678
5001
  if (!word) {
4679
5002
  return false;
4680
5003
  }
4681
- return wordPartContainsBlockedCommand(
4682
- word.parts,
4683
- context,
4684
- mode
4685
- );
5004
+ return wordPartContainsBlockedCommand(word.parts, context, mode);
4686
5005
  }
4687
5006
  function wordPartContainsBlockedCommand(parts, context, mode) {
4688
5007
  for (const part of parts) {
@@ -4693,6 +5012,9 @@ function wordPartContainsBlockedCommand(parts, context, mode) {
4693
5012
  return false;
4694
5013
  }
4695
5014
  function partContainsBlockedCommand(node, context, mode) {
5015
+ if (!isRecord(node)) {
5016
+ return false;
5017
+ }
4696
5018
  const type = node.type;
4697
5019
  if (type === "CommandSubstitution" || type === "ProcessSubstitution") {
4698
5020
  if (isScriptNode(node.body)) {
@@ -4709,27 +5031,13 @@ function partContainsBlockedCommand(node, context, mode) {
4709
5031
  }
4710
5032
  for (const value of Object.values(node)) {
4711
5033
  if (Array.isArray(value)) {
4712
- for (const item of value) {
4713
- if (typeof item === "object" && item !== null) {
4714
- if (partContainsBlockedCommand(
4715
- item,
4716
- context,
4717
- mode
4718
- )) {
4719
- return true;
4720
- }
4721
- }
5034
+ if (wordPartContainsBlockedCommand(value, context, mode)) {
5035
+ return true;
4722
5036
  }
4723
5037
  continue;
4724
5038
  }
4725
- if (typeof value === "object" && value !== null) {
4726
- if (partContainsBlockedCommand(
4727
- value,
4728
- context,
4729
- mode
4730
- )) {
4731
- return true;
4732
- }
5039
+ if (partContainsBlockedCommand(value, context, mode)) {
5040
+ return true;
4733
5041
  }
4734
5042
  }
4735
5043
  return false;
@@ -5072,11 +5380,7 @@ function isBlockedSimpleCommand(command, context, mode, options) {
5072
5380
  }
5073
5381
  if (command.redirections.some((redirection) => {
5074
5382
  if (redirection.target.type === "Word") {
5075
- return wordContainsBlockedCommand(
5076
- redirection.target,
5077
- context,
5078
- mode
5079
- );
5383
+ return wordContainsBlockedCommand(redirection.target, context, mode);
5080
5384
  }
5081
5385
  if (redirection.target.type === "HereDoc" && redirection.target.content) {
5082
5386
  return wordContainsBlockedCommand(
@@ -5213,10 +5517,8 @@ function wordPartsContainExpansion(parts) {
5213
5517
  if (part.type === "CommandSubstitution" || part.type === "ParameterExpansion" || part.type === "ArithmeticExpansion") {
5214
5518
  return true;
5215
5519
  }
5216
- if (part.type === "DoubleQuoted" && Array.isArray(part.parts)) {
5217
- if (wordPartsContainExpansion(part.parts)) {
5218
- return true;
5219
- }
5520
+ if (part.type === "DoubleQuoted" && wordPartsContainExpansion(part.parts)) {
5521
+ return true;
5220
5522
  }
5221
5523
  }
5222
5524
  return false;
@@ -5232,38 +5534,33 @@ function isSqlCommandRequiringRewrite(cmd) {
5232
5534
  if (!isValidAdapterName(dbName)) return false;
5233
5535
  const sqlArgs = cmd.args.slice(2);
5234
5536
  if (sqlArgs.length > 1) return true;
5235
- return sqlArgs.some(
5236
- (arg) => wordPartsContainExpansion(
5237
- arg.parts
5238
- )
5239
- );
5537
+ return sqlArgs.some((arg) => wordPartsContainExpansion(arg.parts));
5240
5538
  }
5241
5539
  function extractWordPartText(parts) {
5242
- let text = "";
5243
- for (const part of parts) {
5244
- const type = part.type;
5245
- if (type === "Literal" || type === "SingleQuoted" || type === "Escaped") {
5246
- text += part.value;
5247
- } else if (type === "DoubleQuoted" && Array.isArray(part.parts)) {
5248
- text += extractWordPartText(part.parts);
5249
- } else if (type === "CommandSubstitution" && part.legacy === true) {
5250
- text += "`" + serialize(part.body).trim() + "`";
5251
- } else if (type === "CommandSubstitution") {
5252
- text += "$(" + serialize(part.body).trim() + ")";
5253
- } else if (type === "ParameterExpansion") {
5254
- text += emitParameterExpansion(part);
5255
- } else if (type === "ArithmeticExpansion") {
5256
- const expression = part.expression;
5257
- text += "$((" + (expression?.originalText ?? "") + "))";
5258
- }
5259
- }
5260
- return text;
5540
+ return parts.map(wordPartText).join("");
5541
+ }
5542
+ function wordPartText(part) {
5543
+ switch (part.type) {
5544
+ case "Literal":
5545
+ case "SingleQuoted":
5546
+ case "Escaped":
5547
+ return part.value;
5548
+ case "DoubleQuoted":
5549
+ return extractWordPartText(part.parts);
5550
+ case "CommandSubstitution":
5551
+ return part.legacy ? "`" + serialize(part.body).trim() + "`" : "$(" + serialize(part.body).trim() + ")";
5552
+ case "ParameterExpansion":
5553
+ return emitParameterExpansion(part);
5554
+ case "ArithmeticExpansion":
5555
+ return "$((" + (part.expression.originalText ?? "") + "))";
5556
+ default:
5557
+ return "";
5558
+ }
5261
5559
  }
5262
5560
  function emitParameterExpansion(part) {
5263
- const parameter = part.parameter;
5264
- const operation = part.operation;
5561
+ const { parameter, operation } = part;
5265
5562
  if (!operation) return "$" + parameter;
5266
- if (operation.type === "DefaultValue" && operation.word) {
5563
+ if (operation.type === "DefaultValue") {
5267
5564
  const fallback = extractWordPartText(operation.word.parts);
5268
5565
  const separator = operation.checkEmpty ? ":-" : "-";
5269
5566
  return "${" + parameter + separator + fallback + "}";
@@ -5271,11 +5568,7 @@ function emitParameterExpansion(part) {
5271
5568
  return "${" + parameter + "}";
5272
5569
  }
5273
5570
  function extractSqlText(args) {
5274
- return args.map(
5275
- (arg) => extractWordPartText(
5276
- arg.parts
5277
- )
5278
- ).join(" ");
5571
+ return args.map((arg) => extractWordPartText(arg.parts)).join(" ");
5279
5572
  }
5280
5573
  function rewriteSqlCommand(cmd, ast) {
5281
5574
  const subcommand = asStaticWordText2(cmd.args[0]);
@@ -5514,8 +5807,10 @@ var Text2Sql = class {
5514
5807
  if (!Array.isArray(result)) {
5515
5808
  throw new Error("adapter.execute must return an array of rows");
5516
5809
  }
5517
- const columns = result.length > 0 ? Object.keys(result[0]) : [];
5518
- return { rows: result, columns };
5810
+ const rows = result;
5811
+ const [first] = rows;
5812
+ const columns = typeof first === "object" && first !== null ? Object.keys(first) : [];
5813
+ return { rows, columns };
5519
5814
  }
5520
5815
  async #validateWith(adapter, sql) {
5521
5816
  const formatted = adapter.format(sql);
@@ -5679,15 +5974,13 @@ function extractSqlInvocation(command) {
5679
5974
  return parseSqlQueryInvocation(repairSqlCommand(command));
5680
5975
  }
5681
5976
  function inputCommand(input) {
5682
- return input?.command;
5977
+ return typeof input === "object" && input !== null && "command" in input ? input.command : void 0;
5683
5978
  }
5684
5979
  function alreadyValidated(messages, run) {
5685
5980
  for (const message of messages ?? []) {
5686
5981
  for (const part of message.parts) {
5687
5982
  if (!isToolUIPart(part)) continue;
5688
- const invocation = extractSqlInvocation(
5689
- inputCommand(part.input)
5690
- );
5983
+ const invocation = extractSqlInvocation(inputCommand(part.input));
5691
5984
  if (invocation?.subcommand === "validate" && invocation.dbName === run.dbName && invocation.sql === run.sql) {
5692
5985
  return true;
5693
5986
  }
@@ -5745,10 +6038,12 @@ export {
5745
6038
  filterRelationshipsByTables,
5746
6039
  filterTablesByName,
5747
6040
  getTablesWithRelated,
6041
+ groundingFor,
5748
6042
  hashConfig,
5749
6043
  index,
5750
6044
  instructions,
5751
6045
  isValidAdapterName,
6046
+ jsonCodec,
5752
6047
  matchesFilter,
5753
6048
  relationship,
5754
6049
  repairSqlCommand,