@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,356 @@
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 { PAGE_LEAF_TABLE, decodeRecord, parseBtreePageHeader, readCellPointers, readU32, readVarint, toSafeInt, } from './format.js';
16
+ /** Random access to database pages, with an optional `-wal` overlay layered on top. */
17
+ export class PageReader {
18
+ bytes;
19
+ overlay;
20
+ pageSize;
21
+ usableSize;
22
+ filePageCount;
23
+ constructor(bytes, pageSize, reservedBytes, overlay) {
24
+ this.bytes = bytes;
25
+ this.overlay = overlay;
26
+ this.pageSize = pageSize;
27
+ this.usableSize = pageSize - reservedBytes;
28
+ this.filePageCount = Math.floor(bytes.length / pageSize);
29
+ }
30
+ /** Highest page number reachable from the file or the WAL overlay. */
31
+ get maxPage() {
32
+ let m = this.filePageCount;
33
+ if (this.overlay)
34
+ for (const p of this.overlay.keys())
35
+ if (p > m)
36
+ m = p;
37
+ return m;
38
+ }
39
+ /** Bytes of a page (1-based). The last page may be short after a truncation. */
40
+ page(pageNo) {
41
+ if (pageNo < 1)
42
+ return null;
43
+ const ov = this.overlay?.get(pageNo);
44
+ if (ov)
45
+ return ov;
46
+ const start = (pageNo - 1) * this.pageSize;
47
+ if (start >= this.bytes.length)
48
+ return null;
49
+ return this.bytes.subarray(start, Math.min(start + this.pageSize, this.bytes.length));
50
+ }
51
+ }
52
+ /**
53
+ * Walk a table b-tree from `rootpage`, collecting every decodable leaf row.
54
+ * Robust to loops (visited set), missing pages and bad subtrees: any failure
55
+ * degrades the walk to `complete: false` rather than throwing.
56
+ */
57
+ export function walkTableBtree(reader, rootpage, textEncoding) {
58
+ const rows = [];
59
+ const visitedPages = new Set();
60
+ let complete = true;
61
+ let droppedCells = 0;
62
+ const visit = (pageNo) => {
63
+ if (pageNo < 1 || pageNo > reader.maxPage || visitedPages.has(pageNo)) {
64
+ if (pageNo >= 1)
65
+ complete = false;
66
+ return;
67
+ }
68
+ visitedPages.add(pageNo);
69
+ const page = reader.page(pageNo);
70
+ if (!page) {
71
+ complete = false;
72
+ return;
73
+ }
74
+ const hdr = parseBtreePageHeader(page, pageNo);
75
+ if (!hdr) {
76
+ complete = false;
77
+ return;
78
+ }
79
+ if (hdr.type === PAGE_LEAF_TABLE) {
80
+ const before = rows.length;
81
+ for (const row of readTableLeafCells(reader, page, hdr, textEncoding))
82
+ rows.push(row);
83
+ droppedCells += Math.max(0, hdr.cellCount - (rows.length - before));
84
+ return;
85
+ }
86
+ if (hdr.type === 0x05) {
87
+ // Interior table page: descend into every child then the rightmost.
88
+ const ptrs = readCellPointers(page, hdr);
89
+ for (const ptr of ptrs) {
90
+ const child = readU32(page, ptr);
91
+ visit(child);
92
+ }
93
+ if (hdr.rightMostPointer > 0)
94
+ visit(hdr.rightMostPointer);
95
+ return;
96
+ }
97
+ // Index pages carry no table rows; ignore for row recovery.
98
+ };
99
+ visit(rootpage);
100
+ return { rows, visitedPages, complete, droppedCells };
101
+ }
102
+ /** Decode every table-leaf cell on a page (following overflow chains). */
103
+ function readTableLeafCells(reader, page, hdr, textEncoding) {
104
+ const rows = [];
105
+ for (const ptr of readCellPointers(page, hdr)) {
106
+ const cell = readTableLeafCell(reader, page, ptr, textEncoding);
107
+ if (cell)
108
+ rows.push(cell);
109
+ }
110
+ return rows;
111
+ }
112
+ /**
113
+ * Read a single table-leaf cell at `ptr`: varint payload length, varint rowid,
114
+ * then the record payload (local bytes plus any overflow-page chain). Returns
115
+ * null on any structural inconsistency so a single bad cell never aborts a page.
116
+ */
117
+ function readTableLeafCell(reader, page, ptr, textEncoding) {
118
+ const payloadLenV = readVarint(page, ptr);
119
+ if (payloadLenV.length === 0)
120
+ return null;
121
+ const payloadLength = Number(payloadLenV.value);
122
+ if (payloadLength <= 0 || payloadLength > 1 << 30)
123
+ return null;
124
+ const rowidV = readVarint(page, ptr + payloadLenV.length);
125
+ if (rowidV.length === 0)
126
+ return null;
127
+ const rowid = toSafeInt(rowidV.value);
128
+ const headerBytes = payloadLenV.length + rowidV.length;
129
+ const U = reader.usableSize;
130
+ const X = U - 35; // Max local payload for a table leaf.
131
+ const dataStart = ptr + headerBytes;
132
+ let payload;
133
+ if (payloadLength <= X) {
134
+ payload = page.subarray(dataStart, dataStart + payloadLength);
135
+ }
136
+ else {
137
+ // Spilled record: local portion + 4-byte first-overflow pointer.
138
+ const M = Math.floor(((U - 12) * 32) / 255) - 23;
139
+ let localSize = M + ((payloadLength - M) % (U - 4));
140
+ if (localSize > X)
141
+ localSize = M;
142
+ const local = page.subarray(dataStart, dataStart + localSize);
143
+ const firstOverflow = readU32(page, dataStart + localSize);
144
+ payload = assembleOverflow(reader, local, firstOverflow, payloadLength);
145
+ }
146
+ const record = decodeRecord(payload, textEncoding);
147
+ if (!record)
148
+ return null;
149
+ return { rowid, values: record.values };
150
+ }
151
+ /** Follow an overflow-page chain, appending each page's payload after `local`. */
152
+ function assembleOverflow(reader, local, firstOverflow, payloadLength) {
153
+ const parts = [local.slice()];
154
+ let total = local.length;
155
+ let next = firstOverflow;
156
+ const seen = new Set();
157
+ while (next > 0 && total < payloadLength && !seen.has(next)) {
158
+ seen.add(next);
159
+ const page = reader.page(next);
160
+ if (!page || page.length < 4)
161
+ break;
162
+ next = readU32(page, 0);
163
+ const chunk = page.subarray(4, Math.min(page.length, 4 + (payloadLength - total)));
164
+ parts.push(chunk.slice());
165
+ total += chunk.length;
166
+ }
167
+ const out = new Uint8Array(total);
168
+ let o = 0;
169
+ for (const part of parts) {
170
+ out.set(part, o);
171
+ o += part.length;
172
+ }
173
+ return out;
174
+ }
175
+ /**
176
+ * Pointer-free sweep: every table-leaf page in the file (except `skip`) is read
177
+ * as an independent bag of records. This is how rows survive a zeroed interior
178
+ * page or a dropped table. Records here are un-attributed — the caller decides
179
+ * whether a shape matches a known table or must land in lost_and_found.
180
+ */
181
+ export function rawScanLeafPages(reader, textEncoding, skip) {
182
+ const out = [];
183
+ const maxPage = reader.maxPage;
184
+ for (let pageNo = 1; pageNo <= maxPage; pageNo++) {
185
+ if (skip.has(pageNo))
186
+ continue;
187
+ const page = reader.page(pageNo);
188
+ if (!page)
189
+ continue;
190
+ const hdr = parseBtreePageHeader(page, pageNo);
191
+ if (!hdr || hdr.type !== PAGE_LEAF_TABLE)
192
+ continue;
193
+ const ptrs = readCellPointers(page, hdr);
194
+ ptrs.forEach((ptr, cellIndex) => {
195
+ const cell = readOrphanCell(reader, page, ptr, textEncoding);
196
+ if (cell)
197
+ out.push({ pageNo, cellIndex, ...cell });
198
+ });
199
+ }
200
+ return out;
201
+ }
202
+ function readOrphanCell(reader, page, ptr, textEncoding) {
203
+ const payloadLenV = readVarint(page, ptr);
204
+ if (payloadLenV.length === 0)
205
+ return null;
206
+ const payloadLength = Number(payloadLenV.value);
207
+ if (payloadLength <= 0 || payloadLength > 1 << 30)
208
+ return null;
209
+ const rowidV = readVarint(page, ptr + payloadLenV.length);
210
+ if (rowidV.length === 0)
211
+ return null;
212
+ const U = reader.usableSize;
213
+ const X = U - 35;
214
+ const dataStart = ptr + payloadLenV.length + rowidV.length;
215
+ let payload;
216
+ if (payloadLength <= X) {
217
+ payload = page.subarray(dataStart, dataStart + payloadLength);
218
+ }
219
+ else {
220
+ const M = Math.floor(((U - 12) * 32) / 255) - 23;
221
+ let localSize = M + ((payloadLength - M) % (U - 4));
222
+ if (localSize > X)
223
+ localSize = M;
224
+ const local = page.subarray(dataStart, dataStart + localSize);
225
+ payload = assembleOverflow(reader, local, readU32(page, dataStart + localSize), payloadLength);
226
+ }
227
+ const record = decodeRecord(payload, textEncoding);
228
+ if (!record || record.values.length === 0)
229
+ return null;
230
+ return { rowid: toSafeInt(rowidV.value), values: record.values, serialTypes: record.serialTypes };
231
+ }
232
+ /**
233
+ * Read the schema table (`sqlite_master`, rooted at page 1). Each row is
234
+ * (type, name, tbl_name, rootpage, sql). Failure to walk page 1 yields ok:false
235
+ * so the caller can fall back to a pure raw scan.
236
+ */
237
+ export function parseSchema(reader, textEncoding) {
238
+ const notes = [];
239
+ const walk = walkTableBtree(reader, 1, textEncoding);
240
+ if (walk.rows.length === 0 && !walk.complete) {
241
+ notes.push('schema page (page 1) could not be walked; falling back to a raw page scan');
242
+ return { entries: [], ok: false, schemaPages: walk.visitedPages, notes };
243
+ }
244
+ const entries = [];
245
+ for (const row of walk.rows) {
246
+ const [type, name, tblName, rootpage, sql] = row.values;
247
+ if (typeof type !== 'string' || typeof name !== 'string')
248
+ continue;
249
+ entries.push({
250
+ type,
251
+ name,
252
+ tblName: typeof tblName === 'string' ? tblName : name,
253
+ rootpage: typeof rootpage === 'number' ? rootpage : Number(rootpage ?? 0),
254
+ sql: typeof sql === 'string' ? sql : '',
255
+ });
256
+ }
257
+ if (entries.length === 0)
258
+ notes.push('schema table parsed but held no usable entries');
259
+ return { entries, ok: entries.length > 0, schemaPages: walk.visitedPages, notes };
260
+ }
261
+ /**
262
+ * Light CREATE TABLE column parser for the common case: pulls column names from
263
+ * the top-level column list and flags an INTEGER PRIMARY KEY rowid alias.
264
+ * Exotic DDL (generated columns, unusual quoting) may not parse — recovery
265
+ * degrades to lost_and_found rather than guessing, and says so.
266
+ */
267
+ export function parseCreateTableColumns(sql) {
268
+ const open = sql.indexOf('(');
269
+ if (open === -1)
270
+ return null;
271
+ // Find the matching close paren for the top-level column list.
272
+ let depth = 0;
273
+ let close = -1;
274
+ let inStr = null;
275
+ for (let i = open; i < sql.length; i++) {
276
+ const ch = sql[i];
277
+ if (inStr) {
278
+ if (ch === inStr)
279
+ inStr = null;
280
+ continue;
281
+ }
282
+ if (ch === '"' || ch === "'" || ch === '`')
283
+ inStr = ch;
284
+ else if (ch === '(')
285
+ depth++;
286
+ else if (ch === ')') {
287
+ depth--;
288
+ if (depth === 0) {
289
+ close = i;
290
+ break;
291
+ }
292
+ }
293
+ }
294
+ if (close === -1)
295
+ return null;
296
+ const inner = sql.slice(open + 1, close);
297
+ const parts = splitTopLevel(inner);
298
+ const columns = [];
299
+ let ipkColumn = null;
300
+ const constraintKeywords = /^(PRIMARY|UNIQUE|CHECK|FOREIGN|CONSTRAINT)\b/i;
301
+ for (const raw of parts) {
302
+ const part = raw.trim();
303
+ if (part === '' || constraintKeywords.test(part))
304
+ continue;
305
+ const name = firstIdentifier(part);
306
+ if (name === null)
307
+ continue;
308
+ if (/\bINTEGER\s+PRIMARY\s+KEY\b/i.test(part))
309
+ ipkColumn = columns.length;
310
+ columns.push(name);
311
+ }
312
+ if (columns.length === 0)
313
+ return null;
314
+ return { columns, ipkColumn };
315
+ }
316
+ function splitTopLevel(s) {
317
+ const out = [];
318
+ let depth = 0;
319
+ let inStr = null;
320
+ let start = 0;
321
+ for (let i = 0; i < s.length; i++) {
322
+ const ch = s[i];
323
+ if (inStr) {
324
+ if (ch === inStr)
325
+ inStr = null;
326
+ continue;
327
+ }
328
+ if (ch === '"' || ch === "'" || ch === '`')
329
+ inStr = ch;
330
+ else if (ch === '(')
331
+ depth++;
332
+ else if (ch === ')')
333
+ depth--;
334
+ else if (ch === ',' && depth === 0) {
335
+ out.push(s.slice(start, i));
336
+ start = i + 1;
337
+ }
338
+ }
339
+ out.push(s.slice(start));
340
+ return out;
341
+ }
342
+ function firstIdentifier(part) {
343
+ const s = part.trimStart();
344
+ const quote = s[0];
345
+ if (quote === '"' || quote === '`') {
346
+ const end = s.indexOf(quote, 1);
347
+ return end === -1 ? null : s.slice(1, end);
348
+ }
349
+ if (quote === '[') {
350
+ const end = s.indexOf(']', 1);
351
+ return end === -1 ? null : s.slice(1, end);
352
+ }
353
+ const m = /^[A-Za-z_][A-Za-z0-9_$]*/.exec(s);
354
+ return m ? m[0] : null;
355
+ }
356
+ //# sourceMappingURL=scan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan.js","sourceRoot":"","sources":["../../src/sqlite/scan.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Isolated, injectable host for building the *fresh* output database. Recovery
3
+ * itself is pure TypeScript (see scan.ts); this host is only the writer that
4
+ * serializes recovered rows into a real, openable SQLite file.
5
+ *
6
+ * Loading is injectable, exactly like the qpdf host: in Node the default loader
7
+ * uses the built-in `node:sqlite` module (real SQLite, byte-faithful output);
8
+ * a browser host calls setSqliteBuilderLoader() with a sqlite-wasm-backed
9
+ * builder before recovering. Nothing else in the package imports node:sqlite,
10
+ * and it is only loaded on first use, so browser bundles stay clean.
11
+ */
12
+ import type { SqlValue } from './format.js';
13
+ export interface SqliteBuildStatement {
14
+ /** A single SQL statement. With `rows`, it is a parameterized INSERT run once per row. */
15
+ sql: string;
16
+ /** Positional parameter rows for a prepared statement. */
17
+ rows?: SqlValue[][];
18
+ }
19
+ export interface SqliteBuildSpec {
20
+ statements: SqliteBuildStatement[];
21
+ }
22
+ export interface SqliteBuildResult {
23
+ bytes: Uint8Array;
24
+ rowsInserted: number;
25
+ rowsFailed: number;
26
+ }
27
+ export interface SqliteBuilder {
28
+ build(spec: SqliteBuildSpec): Promise<SqliteBuildResult>;
29
+ }
30
+ export type SqliteBuilderLoader = () => Promise<SqliteBuilder>;
31
+ /** Inject how the fresh-database builder is obtained (browser hosts / tests). */
32
+ export declare function setSqliteBuilderLoader(load: SqliteBuilderLoader): void;
33
+ /** Drop the cached builder (tests). */
34
+ export declare function resetSqliteHost(): void;
35
+ /** Build a fresh database from DDL + row inserts, returning its serialized bytes. */
36
+ export declare function buildFreshDatabase(spec: SqliteBuildSpec): Promise<SqliteBuildResult>;
37
+ //# sourceMappingURL=sqlite-host.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite-host.d.ts","sourceRoot":"","sources":["../../src/sqlite/sqlite-host.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,WAAW,oBAAoB;IACnC,0FAA0F;IAC1F,GAAG,EAAE,MAAM,CAAC;IACZ,0DAA0D;IAC1D,IAAI,CAAC,EAAE,QAAQ,EAAE,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,oBAAoB,EAAE,CAAC;CACpC;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,UAAU,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;CAC1D;AAED,MAAM,MAAM,mBAAmB,GAAG,MAAM,OAAO,CAAC,aAAa,CAAC,CAAC;AAK/D,iFAAiF;AACjF,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,mBAAmB,GAAG,IAAI,CAGtE;AAED,uCAAuC;AACvC,wBAAgB,eAAe,IAAI,IAAI,CAEtC;AAED,qFAAqF;AACrF,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAMpF"}
@@ -0,0 +1,80 @@
1
+ let loaderOverride = null;
2
+ let loaderPromise = null;
3
+ /** Inject how the fresh-database builder is obtained (browser hosts / tests). */
4
+ export function setSqliteBuilderLoader(load) {
5
+ loaderOverride = load;
6
+ loaderPromise = null;
7
+ }
8
+ /** Drop the cached builder (tests). */
9
+ export function resetSqliteHost() {
10
+ loaderPromise = null;
11
+ }
12
+ /** Build a fresh database from DDL + row inserts, returning its serialized bytes. */
13
+ export function buildFreshDatabase(spec) {
14
+ loaderPromise ??= (loaderOverride ?? defaultNodeLoader)().catch((e) => {
15
+ loaderPromise = null;
16
+ throw e;
17
+ });
18
+ return loaderPromise.then((builder) => builder.build(spec));
19
+ }
20
+ let tmpCounter = 0;
21
+ async function defaultNodeLoader() {
22
+ const isNode = typeof process !== 'undefined' && !!process.versions?.node;
23
+ if (!isNode) {
24
+ throw new Error('sqlite host: no builder configured. In the browser, call setSqliteBuilderLoader() with a sqlite-wasm builder before recovering databases.');
25
+ }
26
+ const [{ DatabaseSync }, { tmpdir }, { join }, fs] = await Promise.all([
27
+ import('node:sqlite'),
28
+ import('node:os'),
29
+ import('node:path'),
30
+ import('node:fs'),
31
+ ]);
32
+ return {
33
+ async build(spec) {
34
+ const path = join(tmpdir(), `intactfile-recover-${process.pid}-${Date.now()}-${tmpCounter++}.db`);
35
+ cleanup(fs, path);
36
+ const db = new DatabaseSync(path);
37
+ let rowsInserted = 0;
38
+ let rowsFailed = 0;
39
+ try {
40
+ db.exec('PRAGMA journal_mode = MEMORY');
41
+ db.exec('BEGIN');
42
+ for (const stmt of spec.statements) {
43
+ if (stmt.rows === undefined) {
44
+ db.exec(stmt.sql);
45
+ continue;
46
+ }
47
+ const prepared = db.prepare(stmt.sql);
48
+ const run = prepared.run.bind(prepared);
49
+ for (const row of stmt.rows) {
50
+ try {
51
+ run(...row);
52
+ rowsInserted++;
53
+ }
54
+ catch {
55
+ rowsFailed++;
56
+ }
57
+ }
58
+ }
59
+ db.exec('COMMIT');
60
+ }
61
+ finally {
62
+ db.close();
63
+ }
64
+ const bytes = new Uint8Array(fs.readFileSync(path));
65
+ cleanup(fs, path);
66
+ return { bytes, rowsInserted, rowsFailed };
67
+ },
68
+ };
69
+ }
70
+ function cleanup(fs, path) {
71
+ for (const suffix of ['', '-wal', '-journal', '-shm']) {
72
+ try {
73
+ fs.unlinkSync(path + suffix);
74
+ }
75
+ catch {
76
+ // Not present; nothing to remove.
77
+ }
78
+ }
79
+ }
80
+ //# sourceMappingURL=sqlite-host.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite-host.js","sourceRoot":"","sources":["../../src/sqlite/sqlite-host.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ export interface WalOverlay {
2
+ valid: boolean;
3
+ pageSize: number;
4
+ /** Page number -> latest committed page image. */
5
+ pages: Map<number, Uint8Array>;
6
+ /** db size in pages recorded by the last commit frame, or 0. */
7
+ committedPageCount: number;
8
+ /** Count of committed frames applied. */
9
+ framesApplied: number;
10
+ notes: string[];
11
+ }
12
+ /** Parse a `-wal` sidecar into an overlay of committed page images. */
13
+ export declare function parseWal(wal: Uint8Array): WalOverlay;
14
+ //# sourceMappingURL=wal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wal.d.ts","sourceRoot":"","sources":["../../src/sqlite/wal.ts"],"names":[],"mappings":"AAmBA,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,kDAAkD;IAClD,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC/B,gEAAgE;IAChE,kBAAkB,EAAE,MAAM,CAAC;IAC3B,yCAAyC;IACzC,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,uEAAuE;AACvE,wBAAgB,QAAQ,CAAC,GAAG,EAAE,UAAU,GAAG,UAAU,CAkEpD"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Minimal write-ahead log (`-wal`) overlay. When a database is copied while a
3
+ * checkpoint was pending, the newest committed page images live in the sidecar
4
+ * `-wal` file, not the main database. Recovery reads better when those frames
5
+ * are layered on top of the base pages first.
6
+ *
7
+ * Format reference: https://sqlite.org/fileformat2.html#the_write_ahead_log
8
+ * Frames whose salts do not match the WAL header are stale (from an earlier
9
+ * checkpoint generation) and ignored. Only frames up to and including the last
10
+ * commit frame are applied. Frame checksums are not verified — recovery is
11
+ * deliberately permissive and records that in its notes.
12
+ */
13
+ import { readU32 } from './format.js';
14
+ const WAL_MAGIC_LE = 0x377f0682;
15
+ const WAL_MAGIC_BE = 0x377f0683;
16
+ const WAL_HEADER_SIZE = 32;
17
+ const FRAME_HEADER_SIZE = 24;
18
+ /** Parse a `-wal` sidecar into an overlay of committed page images. */
19
+ export function parseWal(wal) {
20
+ const notes = [];
21
+ const empty = {
22
+ valid: false,
23
+ pageSize: 0,
24
+ pages: new Map(),
25
+ committedPageCount: 0,
26
+ framesApplied: 0,
27
+ notes,
28
+ };
29
+ if (wal.length < WAL_HEADER_SIZE) {
30
+ notes.push('-wal sidecar is too small to contain a header');
31
+ return empty;
32
+ }
33
+ const magic = readU32(wal, 0);
34
+ if (magic !== WAL_MAGIC_LE && magic !== WAL_MAGIC_BE) {
35
+ notes.push('-wal sidecar has an unrecognized magic; ignored');
36
+ return empty;
37
+ }
38
+ const pageSize = readU32(wal, 8);
39
+ if (pageSize < 512 || (pageSize & (pageSize - 1)) !== 0) {
40
+ notes.push('-wal sidecar declares an implausible page size; ignored');
41
+ return empty;
42
+ }
43
+ const salt1 = readU32(wal, 16);
44
+ const salt2 = readU32(wal, 20);
45
+ const frameStride = FRAME_HEADER_SIZE + pageSize;
46
+ const frames = [];
47
+ let lastCommit = -1;
48
+ let committedPageCount = 0;
49
+ for (let off = WAL_HEADER_SIZE; off + frameStride <= wal.length; off += frameStride) {
50
+ const fSalt1 = readU32(wal, off + 8);
51
+ const fSalt2 = readU32(wal, off + 12);
52
+ if (fSalt1 !== salt1 || fSalt2 !== salt2)
53
+ continue; // Stale generation.
54
+ const pageNo = readU32(wal, off + 0);
55
+ const dbSize = readU32(wal, off + 4);
56
+ const data = wal.subarray(off + FRAME_HEADER_SIZE, off + frameStride).slice();
57
+ frames.push({ pageNo, data, isCommit: dbSize !== 0 });
58
+ if (dbSize !== 0) {
59
+ lastCommit = frames.length - 1;
60
+ committedPageCount = dbSize;
61
+ }
62
+ }
63
+ const pages = new Map();
64
+ let framesApplied = 0;
65
+ for (let i = 0; i <= lastCommit; i++) {
66
+ const f = frames[i];
67
+ if (!f)
68
+ continue;
69
+ pages.set(f.pageNo, f.data);
70
+ framesApplied++;
71
+ }
72
+ if (lastCommit === -1) {
73
+ notes.push('-wal sidecar has no committed frames; nothing to overlay');
74
+ return { ...empty, pageSize, valid: true };
75
+ }
76
+ notes.push(`-wal overlay applied: ${pages.size} page(s) from ${framesApplied} committed frame(s)`);
77
+ return { valid: true, pageSize, pages, committedPageCount, framesApplied, notes };
78
+ }
79
+ //# sourceMappingURL=wal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wal.js","sourceRoot":"","sources":["../../src/sqlite/wal.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export type Confidence = 'high' | 'medium' | 'low';
2
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}