@intactfile/engines 0.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 (207) hide show
  1. package/README.md +68 -0
  2. package/dist/archive/diagnose.d.ts +37 -0
  3. package/dist/archive/diagnose.d.ts.map +1 -0
  4. package/dist/archive/diagnose.js +165 -0
  5. package/dist/archive/diagnose.js.map +1 -0
  6. package/dist/archive/format.d.ts +52 -0
  7. package/dist/archive/format.d.ts.map +1 -0
  8. package/dist/archive/format.js +87 -0
  9. package/dist/archive/format.js.map +1 -0
  10. package/dist/archive/host.d.ts +83 -0
  11. package/dist/archive/host.d.ts.map +1 -0
  12. package/dist/archive/host.js +92 -0
  13. package/dist/archive/host.js.map +1 -0
  14. package/dist/archive/index.d.ts +22 -0
  15. package/dist/archive/index.d.ts.map +1 -0
  16. package/dist/archive/index.js +19 -0
  17. package/dist/archive/index.js.map +1 -0
  18. package/dist/archive/salvage.d.ts +73 -0
  19. package/dist/archive/salvage.d.ts.map +1 -0
  20. package/dist/archive/salvage.js +210 -0
  21. package/dist/archive/salvage.js.map +1 -0
  22. package/dist/byte-source.d.ts +19 -0
  23. package/dist/byte-source.d.ts.map +1 -0
  24. package/dist/byte-source.js +16 -0
  25. package/dist/byte-source.js.map +1 -0
  26. package/dist/bytesource/blob.d.ts +14 -0
  27. package/dist/bytesource/blob.d.ts.map +1 -0
  28. package/dist/bytesource/blob.js +23 -0
  29. package/dist/bytesource/blob.js.map +1 -0
  30. package/dist/crc32.d.ts +2 -0
  31. package/dist/crc32.d.ts.map +1 -0
  32. package/dist/crc32.js +18 -0
  33. package/dist/crc32.js.map +1 -0
  34. package/dist/detect/index.d.ts +16 -0
  35. package/dist/detect/index.d.ts.map +1 -0
  36. package/dist/detect/index.js +159 -0
  37. package/dist/detect/index.js.map +1 -0
  38. package/dist/index.d.ts +24 -0
  39. package/dist/index.d.ts.map +1 -0
  40. package/dist/index.js +17 -0
  41. package/dist/index.js.map +1 -0
  42. package/dist/jpeg/browser-loader.d.ts +21 -0
  43. package/dist/jpeg/browser-loader.d.ts.map +1 -0
  44. package/dist/jpeg/browser-loader.js +28 -0
  45. package/dist/jpeg/browser-loader.js.map +1 -0
  46. package/dist/jpeg/diagnose.d.ts +50 -0
  47. package/dist/jpeg/diagnose.d.ts.map +1 -0
  48. package/dist/jpeg/diagnose.js +124 -0
  49. package/dist/jpeg/diagnose.js.map +1 -0
  50. package/dist/jpeg/exif.d.ts +11 -0
  51. package/dist/jpeg/exif.d.ts.map +1 -0
  52. package/dist/jpeg/exif.js +50 -0
  53. package/dist/jpeg/exif.js.map +1 -0
  54. package/dist/jpeg/format.d.ts +106 -0
  55. package/dist/jpeg/format.d.ts.map +1 -0
  56. package/dist/jpeg/format.js +248 -0
  57. package/dist/jpeg/format.js.map +1 -0
  58. package/dist/jpeg/index.d.ts +18 -0
  59. package/dist/jpeg/index.d.ts.map +1 -0
  60. package/dist/jpeg/index.js +14 -0
  61. package/dist/jpeg/index.js.map +1 -0
  62. package/dist/jpeg/mozjpeg-host.d.ts +60 -0
  63. package/dist/jpeg/mozjpeg-host.d.ts.map +1 -0
  64. package/dist/jpeg/mozjpeg-host.js +138 -0
  65. package/dist/jpeg/mozjpeg-host.js.map +1 -0
  66. package/dist/jpeg/repair.d.ts +89 -0
  67. package/dist/jpeg/repair.d.ts.map +1 -0
  68. package/dist/jpeg/repair.js +216 -0
  69. package/dist/jpeg/repair.js.map +1 -0
  70. package/dist/node.d.ts +11 -0
  71. package/dist/node.d.ts.map +1 -0
  72. package/dist/node.js +29 -0
  73. package/dist/node.js.map +1 -0
  74. package/dist/pdf/browser-loader.d.ts +30 -0
  75. package/dist/pdf/browser-loader.d.ts.map +1 -0
  76. package/dist/pdf/browser-loader.js +21 -0
  77. package/dist/pdf/browser-loader.js.map +1 -0
  78. package/dist/pdf/diagnose.d.ts +23 -0
  79. package/dist/pdf/diagnose.d.ts.map +1 -0
  80. package/dist/pdf/diagnose.js +113 -0
  81. package/dist/pdf/diagnose.js.map +1 -0
  82. package/dist/pdf/format.d.ts +61 -0
  83. package/dist/pdf/format.d.ts.map +1 -0
  84. package/dist/pdf/format.js +150 -0
  85. package/dist/pdf/format.js.map +1 -0
  86. package/dist/pdf/index.d.ts +17 -0
  87. package/dist/pdf/index.d.ts.map +1 -0
  88. package/dist/pdf/index.js +12 -0
  89. package/dist/pdf/index.js.map +1 -0
  90. package/dist/pdf/qpdf-host.d.ts +66 -0
  91. package/dist/pdf/qpdf-host.d.ts.map +1 -0
  92. package/dist/pdf/qpdf-host.js +149 -0
  93. package/dist/pdf/qpdf-host.js.map +1 -0
  94. package/dist/pdf/rebuild.d.ts +32 -0
  95. package/dist/pdf/rebuild.d.ts.map +1 -0
  96. package/dist/pdf/rebuild.js +90 -0
  97. package/dist/pdf/rebuild.js.map +1 -0
  98. package/dist/pdf/repair.d.ts +61 -0
  99. package/dist/pdf/repair.d.ts.map +1 -0
  100. package/dist/pdf/repair.js +167 -0
  101. package/dist/pdf/repair.js.map +1 -0
  102. package/dist/png/diagnose.d.ts +50 -0
  103. package/dist/png/diagnose.d.ts.map +1 -0
  104. package/dist/png/diagnose.js +261 -0
  105. package/dist/png/diagnose.js.map +1 -0
  106. package/dist/png/format.d.ts +133 -0
  107. package/dist/png/format.d.ts.map +1 -0
  108. package/dist/png/format.js +350 -0
  109. package/dist/png/format.js.map +1 -0
  110. package/dist/png/index.d.ts +13 -0
  111. package/dist/png/index.d.ts.map +1 -0
  112. package/dist/png/index.js +10 -0
  113. package/dist/png/index.js.map +1 -0
  114. package/dist/png/repair.d.ts +31 -0
  115. package/dist/png/repair.d.ts.map +1 -0
  116. package/dist/png/repair.js +335 -0
  117. package/dist/png/repair.js.map +1 -0
  118. package/dist/sqlite/diagnose.d.ts +31 -0
  119. package/dist/sqlite/diagnose.d.ts.map +1 -0
  120. package/dist/sqlite/diagnose.js +169 -0
  121. package/dist/sqlite/diagnose.js.map +1 -0
  122. package/dist/sqlite/format.d.ts +103 -0
  123. package/dist/sqlite/format.d.ts.map +1 -0
  124. package/dist/sqlite/format.js +237 -0
  125. package/dist/sqlite/format.js.map +1 -0
  126. package/dist/sqlite/index.d.ts +24 -0
  127. package/dist/sqlite/index.d.ts.map +1 -0
  128. package/dist/sqlite/index.js +19 -0
  129. package/dist/sqlite/index.js.map +1 -0
  130. package/dist/sqlite/recover.d.ts +66 -0
  131. package/dist/sqlite/recover.d.ts.map +1 -0
  132. package/dist/sqlite/recover.js +305 -0
  133. package/dist/sqlite/recover.js.map +1 -0
  134. package/dist/sqlite/scan.d.ts +94 -0
  135. package/dist/sqlite/scan.d.ts.map +1 -0
  136. package/dist/sqlite/scan.js +356 -0
  137. package/dist/sqlite/scan.js.map +1 -0
  138. package/dist/sqlite/sqlite-host.d.ts +37 -0
  139. package/dist/sqlite/sqlite-host.d.ts.map +1 -0
  140. package/dist/sqlite/sqlite-host.js +80 -0
  141. package/dist/sqlite/sqlite-host.js.map +1 -0
  142. package/dist/sqlite/wal.d.ts +14 -0
  143. package/dist/sqlite/wal.d.ts.map +1 -0
  144. package/dist/sqlite/wal.js +79 -0
  145. package/dist/sqlite/wal.js.map +1 -0
  146. package/dist/types.d.ts +2 -0
  147. package/dist/types.d.ts.map +1 -0
  148. package/dist/types.js +2 -0
  149. package/dist/types.js.map +1 -0
  150. package/dist/video/diagnose.d.ts +41 -0
  151. package/dist/video/diagnose.d.ts.map +1 -0
  152. package/dist/video/diagnose.js +188 -0
  153. package/dist/video/diagnose.js.map +1 -0
  154. package/dist/video/format.d.ts +87 -0
  155. package/dist/video/format.d.ts.map +1 -0
  156. package/dist/video/format.js +273 -0
  157. package/dist/video/format.js.map +1 -0
  158. package/dist/video/index.d.ts +21 -0
  159. package/dist/video/index.d.ts.map +1 -0
  160. package/dist/video/index.js +17 -0
  161. package/dist/video/index.js.map +1 -0
  162. package/dist/video/libav-host.d.ts +88 -0
  163. package/dist/video/libav-host.d.ts.map +1 -0
  164. package/dist/video/libav-host.js +66 -0
  165. package/dist/video/libav-host.js.map +1 -0
  166. package/dist/video/mp4-rebuild.d.ts +167 -0
  167. package/dist/video/mp4-rebuild.d.ts.map +1 -0
  168. package/dist/video/mp4-rebuild.js +270 -0
  169. package/dist/video/mp4-rebuild.js.map +1 -0
  170. package/dist/video/mp4box-host.d.ts +62 -0
  171. package/dist/video/mp4box-host.d.ts.map +1 -0
  172. package/dist/video/mp4box-host.js +209 -0
  173. package/dist/video/mp4box-host.js.map +1 -0
  174. package/dist/video/reconstruct.d.ts +97 -0
  175. package/dist/video/reconstruct.d.ts.map +1 -0
  176. package/dist/video/reconstruct.js +271 -0
  177. package/dist/video/reconstruct.js.map +1 -0
  178. package/dist/video/remux.d.ts +85 -0
  179. package/dist/video/remux.d.ts.map +1 -0
  180. package/dist/video/remux.js +350 -0
  181. package/dist/video/remux.js.map +1 -0
  182. package/dist/zip/diagnose.d.ts +22 -0
  183. package/dist/zip/diagnose.d.ts.map +1 -0
  184. package/dist/zip/diagnose.js +126 -0
  185. package/dist/zip/diagnose.js.map +1 -0
  186. package/dist/zip/format.d.ts +79 -0
  187. package/dist/zip/format.d.ts.map +1 -0
  188. package/dist/zip/format.js +129 -0
  189. package/dist/zip/format.js.map +1 -0
  190. package/dist/zip/repair.d.ts +32 -0
  191. package/dist/zip/repair.d.ts.map +1 -0
  192. package/dist/zip/repair.js +82 -0
  193. package/dist/zip/repair.js.map +1 -0
  194. package/dist/zip/salvage.d.ts +23 -0
  195. package/dist/zip/salvage.d.ts.map +1 -0
  196. package/dist/zip/salvage.js +140 -0
  197. package/dist/zip/salvage.js.map +1 -0
  198. package/dist/zip/scan.d.ts +64 -0
  199. package/dist/zip/scan.d.ts.map +1 -0
  200. package/dist/zip/scan.js +386 -0
  201. package/dist/zip/scan.js.map +1 -0
  202. package/dist/zip/writer.d.ts +14 -0
  203. package/dist/zip/writer.d.ts.map +1 -0
  204. package/dist/zip/writer.js +131 -0
  205. package/dist/zip/writer.js.map +1 -0
  206. package/package.json +71 -0
  207. package/src/archive/LICENSE-unrar.txt +53 -0
@@ -0,0 +1,305 @@
1
+ import { MemorySource } from '../byte-source.js';
2
+ import { diagnoseSqlite } from './diagnose.js';
3
+ import { parseHeader } from './format.js';
4
+ import { PageReader, parseCreateTableColumns, parseSchema, rawScanLeafPages, walkTableBtree, } from './scan.js';
5
+ import { buildFreshDatabase } from './sqlite-host.js';
6
+ import { parseWal } from './wal.js';
7
+ const LOST_AND_FOUND = 'lost_and_found';
8
+ const MAX_LAF_COLUMNS = 32;
9
+ /**
10
+ * Recover a SQLite database into a fresh one. Returns the new database bytes
11
+ * (omitted only when nothing could be produced) and an honest report.
12
+ */
13
+ export async function recoverSqlite(src, opts = {}) {
14
+ const walBytes = opts.wal ? await toBytes(opts.wal) : undefined;
15
+ const diagnosis = await diagnoseSqlite(src, { walPresent: walBytes !== undefined });
16
+ const notes = [...diagnosis.notes];
17
+ const caveats = [];
18
+ const fail = (extra) => {
19
+ if (extra)
20
+ notes.push(extra);
21
+ return {
22
+ report: {
23
+ outcome: 'failed',
24
+ damageClass: diagnosis.damageClass,
25
+ strategy: null,
26
+ tablesRecovered: 0,
27
+ rowsRecovered: 0,
28
+ orphanCount: 0,
29
+ rowsFailedInsert: 0,
30
+ cellsDropped: 0,
31
+ tables: [],
32
+ caveats,
33
+ notes,
34
+ walApplied: false,
35
+ bytesIn: src.size,
36
+ bytesOut: 0,
37
+ },
38
+ };
39
+ };
40
+ if (diagnosis.damageClass === 'not-sqlite') {
41
+ return fail('input is not a SQLite database; recovery not attempted');
42
+ }
43
+ if (diagnosis.damageClass === 'encrypted') {
44
+ return fail('database appears encrypted (SQLCipher/SEE); recovery requires the key and is not attempted');
45
+ }
46
+ const bytes = await src.read(0, src.size);
47
+ const header = parseHeader(bytes);
48
+ if (!header) {
49
+ return fail('the database header is destroyed; the page size cannot be established, so pages cannot be located');
50
+ }
51
+ const textEncoding = header.textEncoding >= 1 && header.textEncoding <= 3 ? header.textEncoding : 1;
52
+ // Layer the -wal overlay if present.
53
+ let overlay;
54
+ let walApplied = false;
55
+ if (walBytes) {
56
+ const wal = parseWal(walBytes);
57
+ notes.push(...wal.notes);
58
+ if (wal.valid && wal.pages.size > 0 && wal.pageSize === header.pageSize) {
59
+ overlay = wal.pages;
60
+ walApplied = true;
61
+ }
62
+ else if (wal.valid && wal.pageSize !== header.pageSize) {
63
+ notes.push('-wal page size does not match the database; overlay skipped');
64
+ }
65
+ }
66
+ const reader = new PageReader(bytes, header.pageSize, header.reservedBytes, overlay);
67
+ if (reader.maxPage < 1) {
68
+ return fail('file is smaller than a single page; nothing to recover');
69
+ }
70
+ const schema = parseSchema(reader, textEncoding);
71
+ notes.push(...schema.notes);
72
+ const skip = new Set(schema.schemaPages);
73
+ skip.add(1);
74
+ const working = [];
75
+ let strategy = 'btree-walk';
76
+ if (schema.ok) {
77
+ for (const entry of schema.entries) {
78
+ if (entry.type !== 'table' || entry.name.startsWith('sqlite_'))
79
+ continue;
80
+ const cols = parseCreateTableColumns(entry.sql);
81
+ if (!cols) {
82
+ notes.push(`table "${entry.name}": CREATE statement could not be parsed; its rows will go to ${LOST_AND_FOUND}`);
83
+ continue;
84
+ }
85
+ const walk = walkTableBtree(reader, entry.rootpage, textEncoding);
86
+ for (const p of walk.visitedPages)
87
+ skip.add(p);
88
+ working.push({
89
+ entry: { name: entry.name, rootpage: entry.rootpage, sql: entry.sql },
90
+ columns: cols.columns,
91
+ ipkColumn: cols.ipkColumn,
92
+ rows: walk.rows,
93
+ viaRawScan: false,
94
+ complete: walk.complete,
95
+ droppedCells: walk.droppedCells,
96
+ });
97
+ }
98
+ }
99
+ else {
100
+ strategy = 'dump-fallback';
101
+ notes.push('schema unreadable: performing a .dump-style raw extraction into lost_and_found');
102
+ }
103
+ // Pointer-free sweep for everything the walks did not reach.
104
+ const orphansRaw = rawScanLeafPages(reader, textEncoding, skip);
105
+ // Attribute orphan rows to a table when the column count is unambiguous.
106
+ const byColCount = new Map();
107
+ for (const t of working) {
108
+ const list = byColCount.get(t.columns.length) ?? [];
109
+ list.push(t);
110
+ byColCount.set(t.columns.length, list);
111
+ }
112
+ const orphans = [];
113
+ for (const rec of orphansRaw) {
114
+ const candidates = byColCount.get(rec.values.length);
115
+ if (candidates && candidates.length === 1) {
116
+ const target = candidates[0];
117
+ target.rows.push({ rowid: rec.rowid, values: rec.values });
118
+ target.viaRawScan = true;
119
+ if (strategy === 'btree-walk')
120
+ strategy = 'raw-page-scan';
121
+ }
122
+ else {
123
+ orphans.push(rec);
124
+ }
125
+ }
126
+ const anyData = working.some((t) => t.rows.length > 0) || orphans.length > 0;
127
+ if (!anyData) {
128
+ return fail('no decodable rows were found anywhere in the file');
129
+ }
130
+ // Assemble the fresh-database build spec.
131
+ const statements = [];
132
+ const tableReports = [];
133
+ let rowsAttempted = 0;
134
+ for (const t of working) {
135
+ const rowsForTable = t.rows.length;
136
+ // Only skip empty non-recovered tables when nothing came out at all.
137
+ statements.push({ sql: buildCreateTable(t) });
138
+ if (rowsForTable > 0) {
139
+ const insert = buildInsert(t);
140
+ statements.push({ sql: insert.sql, rows: t.rows.map((r) => insert.bind(r)) });
141
+ rowsAttempted += rowsForTable;
142
+ }
143
+ tableReports.push({
144
+ name: t.entry.name,
145
+ columns: t.columns.length,
146
+ rowsRecovered: rowsForTable,
147
+ viaRawScan: t.viaRawScan,
148
+ complete: t.complete,
149
+ droppedCells: t.droppedCells,
150
+ });
151
+ }
152
+ if (orphans.length > 0) {
153
+ const maxFields = Math.min(MAX_LAF_COLUMNS, orphans.reduce((m, o) => Math.max(m, o.values.length), 0));
154
+ statements.push({ sql: buildLostAndFoundTable(maxFields) });
155
+ const lafSql = buildLostAndFoundInsert(maxFields);
156
+ statements.push({
157
+ sql: lafSql,
158
+ rows: orphans.map((o) => bindLostAndFound(o, maxFields)),
159
+ });
160
+ rowsAttempted += orphans.length;
161
+ }
162
+ const built = await buildFreshDatabase({ statements });
163
+ // Compose the report.
164
+ const rowsRecovered = built.rowsInserted;
165
+ const rowsFailedInsert = built.rowsFailed;
166
+ const tablesRecovered = tableReports.length;
167
+ const truncated = diagnosis.damageClass === 'truncated';
168
+ const anyIncomplete = working.some((t) => !t.complete || t.viaRawScan);
169
+ const droppedCells = working.reduce((sum, t) => sum + t.droppedCells, 0);
170
+ if (droppedCells > 0) {
171
+ notes.push(`${droppedCells} cell(s) present on intact pages could not be decoded (bit-rot) and were dropped`);
172
+ caveats.push(`${droppedCells} row(s) were present but too corrupted to decode; they are missing from the recovered database.`);
173
+ }
174
+ caveats.push("SQLite's own guidance: data recovered from a corrupt database is always suspect. Verify it against a known-good source before relying on it.");
175
+ caveats.push('Deleted rows may reappear: the scan reads freelist and unvacuumed pages, so previously-deleted records can resurface.');
176
+ caveats.push('Values reflect on-disk storage classes, not the original declared column affinities; a column’s type may shift.');
177
+ if (truncated) {
178
+ caveats.push('The file was truncated: any data beyond the cut is physically gone and cannot be recovered.');
179
+ }
180
+ if (orphans.length > 0) {
181
+ caveats.push(`${orphans.length} record(s) could not be attributed to a table and were placed in the ${LOST_AND_FOUND} table.`);
182
+ }
183
+ if (walApplied) {
184
+ caveats.push('A -wal sidecar was overlaid; recovered state reflects the last committed transaction in the WAL.');
185
+ }
186
+ if (rowsFailedInsert > 0) {
187
+ notes.push(`${rowsFailedInsert} row(s) were rejected by the fresh database (e.g. duplicate rowids) and dropped`);
188
+ }
189
+ let outcome;
190
+ if (diagnosis.damageClass === 'none' &&
191
+ !truncated &&
192
+ !anyIncomplete &&
193
+ orphans.length === 0 &&
194
+ rowsFailedInsert === 0 &&
195
+ droppedCells === 0 &&
196
+ strategy === 'btree-walk') {
197
+ outcome = 'success';
198
+ }
199
+ else {
200
+ outcome = 'partial';
201
+ if (truncated)
202
+ notes.push('truncated input: recovered what physically survived the cut');
203
+ if (anyIncomplete)
204
+ notes.push('some tables were reconstructed by the pointer-free scan after b-tree damage');
205
+ }
206
+ return {
207
+ db: built.bytes,
208
+ report: {
209
+ outcome,
210
+ damageClass: diagnosis.damageClass,
211
+ strategy,
212
+ tablesRecovered,
213
+ rowsRecovered,
214
+ orphanCount: orphans.length,
215
+ rowsFailedInsert,
216
+ cellsDropped: droppedCells,
217
+ tables: tableReports,
218
+ caveats,
219
+ notes,
220
+ walApplied,
221
+ bytesIn: src.size,
222
+ bytesOut: built.bytes.length,
223
+ },
224
+ };
225
+ }
226
+ async function toBytes(x) {
227
+ if (x instanceof Uint8Array)
228
+ return x;
229
+ return x.read(0, x.size);
230
+ }
231
+ function quoteIdent(name) {
232
+ return `"${name.replace(/"/g, '""')}"`;
233
+ }
234
+ /**
235
+ * Synthesize a permissive CREATE TABLE: original column names, INTEGER PRIMARY
236
+ * KEY preserved so the rowid alias round-trips, but no NOT NULL/UNIQUE/CHECK/FK
237
+ * constraints that could reject resurrected rows (real .recover relaxes too).
238
+ */
239
+ function buildCreateTable(t) {
240
+ const cols = t.columns.map((c, i) => i === t.ipkColumn ? `${quoteIdent(c)} INTEGER PRIMARY KEY` : quoteIdent(c));
241
+ return `CREATE TABLE ${quoteIdent(t.entry.name)} (${cols.join(', ')})`;
242
+ }
243
+ /**
244
+ * Build the INSERT plan for a table. When there is an INTEGER PRIMARY KEY the
245
+ * rowid is written into that column; otherwise the rowid is written into the
246
+ * `_rowid_` pseudo-column so it is preserved faithfully.
247
+ */
248
+ function buildInsert(t) {
249
+ const n = t.columns.length;
250
+ if (t.ipkColumn !== null) {
251
+ const colList = t.columns.map(quoteIdent).join(', ');
252
+ const placeholders = t.columns.map(() => '?').join(', ');
253
+ const ipk = t.ipkColumn;
254
+ return {
255
+ sql: `INSERT OR IGNORE INTO ${quoteIdent(t.entry.name)} (${colList}) VALUES (${placeholders})`,
256
+ bind: (row) => {
257
+ const vals = normalizeRow(row.values, n);
258
+ vals[ipk] = coerceRowid(row.rowid);
259
+ return vals;
260
+ },
261
+ };
262
+ }
263
+ const colList = ['"_rowid_"', ...t.columns.map(quoteIdent)].join(', ');
264
+ const placeholders = new Array(n + 1).fill('?').join(', ');
265
+ return {
266
+ sql: `INSERT OR IGNORE INTO ${quoteIdent(t.entry.name)} (${colList}) VALUES (${placeholders})`,
267
+ bind: (row) => [coerceRowid(row.rowid), ...normalizeRow(row.values, n)],
268
+ };
269
+ }
270
+ /** Pad/truncate a decoded row to the table's column count. */
271
+ function normalizeRow(values, n) {
272
+ if (values.length === n)
273
+ return values.slice();
274
+ const out = values.slice(0, n);
275
+ while (out.length < n)
276
+ out.push(null);
277
+ return out;
278
+ }
279
+ function coerceRowid(rowid) {
280
+ return rowid;
281
+ }
282
+ function buildLostAndFoundTable(maxFields) {
283
+ const cols = ['"pgno" INTEGER', '"cellidx" INTEGER', '"nfield" INTEGER', '"rowid" INTEGER'];
284
+ for (let i = 0; i < maxFields; i++)
285
+ cols.push(quoteIdent(`c${i}`));
286
+ return `CREATE TABLE ${quoteIdent(LOST_AND_FOUND)} (${cols.join(', ')})`;
287
+ }
288
+ function buildLostAndFoundInsert(maxFields) {
289
+ const cols = ['"pgno"', '"cellidx"', '"nfield"', '"rowid"'];
290
+ for (let i = 0; i < maxFields; i++)
291
+ cols.push(quoteIdent(`c${i}`));
292
+ const placeholders = new Array(cols.length).fill('?').join(', ');
293
+ return `INSERT INTO ${quoteIdent(LOST_AND_FOUND)} (${cols.join(', ')}) VALUES (${placeholders})`;
294
+ }
295
+ function bindLostAndFound(o, maxFields) {
296
+ const out = [o.pageNo, o.cellIndex, o.values.length, coerceRowid(o.rowid)];
297
+ for (let i = 0; i < maxFields; i++)
298
+ out.push(o.values[i] ?? null);
299
+ return out;
300
+ }
301
+ /** Convenience wrapper for callers holding raw bytes. */
302
+ export function recoverSqliteBytes(bytes, opts) {
303
+ return recoverSqlite(new MemorySource(bytes), opts);
304
+ }
305
+ //# sourceMappingURL=recover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recover.js","sourceRoot":"","sources":["../../src/sqlite/recover.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Raw b-tree / page scanner: the recovery brain. It reads a (possibly corrupt)
3
+ * database at the byte level and extracts rows two ways:
4
+ *
5
+ * 1. `walkTableBtree` follows a table's b-tree from its root page, the way a
6
+ * healthy reader would — fast and exact when the pointers are intact.
7
+ * 2. `rawScanLeafPages` ignores all pointers and treats every table-leaf page
8
+ * in the file as a bag of records. This is what SQLite's own `.recover`
9
+ * does via the dbdata/dbptr virtual tables: it survives zeroed interior
10
+ * pages, freelisted pages and dropped tables, at the cost of not knowing
11
+ * which table a stray page belonged to.
12
+ *
13
+ * Pure and dependency-free: works identically in Node and the browser.
14
+ */
15
+ import { type SqlValue } from './format.js';
16
+ /** Random access to database pages, with an optional `-wal` overlay layered on top. */
17
+ export declare class PageReader {
18
+ private readonly bytes;
19
+ private readonly overlay?;
20
+ readonly pageSize: number;
21
+ readonly usableSize: number;
22
+ readonly filePageCount: number;
23
+ constructor(bytes: Uint8Array, pageSize: number, reservedBytes: number, overlay?: Map<number, Uint8Array> | undefined);
24
+ /** Highest page number reachable from the file or the WAL overlay. */
25
+ get maxPage(): number;
26
+ /** Bytes of a page (1-based). The last page may be short after a truncation. */
27
+ page(pageNo: number): Uint8Array | null;
28
+ }
29
+ export interface RecoveredRow {
30
+ rowid: number | bigint;
31
+ values: SqlValue[];
32
+ }
33
+ export interface TableWalkResult {
34
+ rows: RecoveredRow[];
35
+ /** Pages visited (so a later raw scan can skip them). */
36
+ visitedPages: Set<number>;
37
+ /** False when a page was missing/invalid mid-walk (partial subtree lost). */
38
+ complete: boolean;
39
+ /** Cells present on visited leaves that could not be decoded (bit-rot). */
40
+ droppedCells: number;
41
+ }
42
+ /**
43
+ * Walk a table b-tree from `rootpage`, collecting every decodable leaf row.
44
+ * Robust to loops (visited set), missing pages and bad subtrees: any failure
45
+ * degrades the walk to `complete: false` rather than throwing.
46
+ */
47
+ export declare function walkTableBtree(reader: PageReader, rootpage: number, textEncoding: number): TableWalkResult;
48
+ export interface OrphanRecord {
49
+ pageNo: number;
50
+ cellIndex: number;
51
+ rowid: number | bigint;
52
+ values: SqlValue[];
53
+ serialTypes: number[];
54
+ }
55
+ /**
56
+ * Pointer-free sweep: every table-leaf page in the file (except `skip`) is read
57
+ * as an independent bag of records. This is how rows survive a zeroed interior
58
+ * page or a dropped table. Records here are un-attributed — the caller decides
59
+ * whether a shape matches a known table or must land in lost_and_found.
60
+ */
61
+ export declare function rawScanLeafPages(reader: PageReader, textEncoding: number, skip: Set<number>): OrphanRecord[];
62
+ export interface MasterEntry {
63
+ type: string;
64
+ name: string;
65
+ tblName: string;
66
+ rootpage: number;
67
+ sql: string;
68
+ }
69
+ export interface SchemaParse {
70
+ entries: MasterEntry[];
71
+ ok: boolean;
72
+ /** Pages consumed by the schema b-tree (page 1 and any overflow/interior). */
73
+ schemaPages: Set<number>;
74
+ notes: string[];
75
+ }
76
+ /**
77
+ * Read the schema table (`sqlite_master`, rooted at page 1). Each row is
78
+ * (type, name, tbl_name, rootpage, sql). Failure to walk page 1 yields ok:false
79
+ * so the caller can fall back to a pure raw scan.
80
+ */
81
+ export declare function parseSchema(reader: PageReader, textEncoding: number): SchemaParse;
82
+ export interface TableColumns {
83
+ columns: string[];
84
+ /** Index of the INTEGER PRIMARY KEY column (the rowid alias), or null. */
85
+ ipkColumn: number | null;
86
+ }
87
+ /**
88
+ * Light CREATE TABLE column parser for the common case: pulls column names from
89
+ * the top-level column list and flags an INTEGER PRIMARY KEY rowid alias.
90
+ * Exotic DDL (generated columns, unusual quoting) may not parse — recovery
91
+ * degrades to lost_and_found rather than guessing, and says so.
92
+ */
93
+ export declare function parseCreateTableColumns(sql: string): TableColumns | null;
94
+ //# sourceMappingURL=scan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../src/sqlite/scan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAGL,KAAK,QAAQ,EAQd,MAAM,aAAa,CAAC;AAErB,uFAAuF;AACvF,qBAAa,UAAU;IAMnB,OAAO,CAAC,QAAQ,CAAC,KAAK;IAGtB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;IAR3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;gBAGZ,KAAK,EAAE,UAAU,EAClC,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,EACJ,OAAO,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,YAAA;IAOpD,sEAAsE;IACtE,IAAI,OAAO,IAAI,MAAM,CAIpB;IAED,gFAAgF;IAChF,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI;CAQxC;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,MAAM,EAAE,QAAQ,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,YAAY,EAAE,CAAC;IACrB,yDAAyD;IACzD,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC1B,6EAA6E;IAC7E,QAAQ,EAAE,OAAO,CAAC;IAClB,2EAA2E;IAC3E,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,UAAU,EAClB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,GACnB,eAAe,CA2CjB;AAwFD,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,MAAM,EAAE,QAAQ,EAAE,CAAC;IACnB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,UAAU,EAClB,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,GAChB,YAAY,EAAE,CAgBhB;AAiCD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,EAAE,EAAE,OAAO,CAAC;IACZ,8EAA8E;IAC9E,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACzB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,GAAG,WAAW,CAqBjF;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,0EAA0E;IAC1E,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAwCxE"}