@nitpicker/crawler 0.11.0 → 0.13.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 (387) hide show
  1. package/README.md +6 -4
  2. package/lib/archive/archive-accessor.d.ts +2 -2
  3. package/lib/archive/archive-accessor.js +2 -2
  4. package/lib/archive/archive-lock.d.ts +7 -0
  5. package/lib/archive/archive-lock.js +7 -0
  6. package/lib/archive/archive.d.ts +175 -13
  7. package/lib/archive/archive.js +198 -14
  8. package/lib/archive/cache/compute-archive-cache-key.d.ts +39 -0
  9. package/lib/archive/cache/compute-archive-cache-key.js +95 -0
  10. package/lib/archive/cache/extract-archive-to-cache.d.ts +43 -0
  11. package/lib/archive/cache/extract-archive-to-cache.js +309 -0
  12. package/lib/archive/cache/get-archive-cache-root.d.ts +20 -0
  13. package/lib/archive/cache/get-archive-cache-root.js +53 -0
  14. package/lib/archive/cache/is-archive-cache-disabled.d.ts +24 -0
  15. package/lib/archive/cache/is-archive-cache-disabled.js +34 -0
  16. package/lib/archive/cache/resolve-archive-cache-dir.d.ts +26 -0
  17. package/lib/archive/cache/resolve-archive-cache-dir.js +32 -0
  18. package/lib/archive/create-adjunct-tables.d.ts +43 -0
  19. package/lib/archive/create-adjunct-tables.js +213 -0
  20. package/lib/archive/create-entity-tables.d.ts +173 -0
  21. package/lib/archive/create-entity-tables.js +318 -0
  22. package/lib/archive/create-progress-reporter.d.ts +30 -0
  23. package/lib/archive/create-progress-reporter.js +38 -0
  24. package/lib/archive/create-ref-tables.d.ts +35 -0
  25. package/lib/archive/create-ref-tables.js +188 -0
  26. package/lib/archive/database.d.ts +130 -182
  27. package/lib/archive/database.js +524 -1777
  28. package/lib/archive/db-ops/_shared/clear-write-ref-caches.d.ts +27 -0
  29. package/lib/archive/db-ops/_shared/clear-write-ref-caches.js +34 -0
  30. package/lib/archive/db-ops/_shared/create-write-ref-caches.d.ts +17 -0
  31. package/lib/archive/db-ops/_shared/create-write-ref-caches.js +26 -0
  32. package/lib/archive/db-ops/_shared/decode-json-ref.d.ts +17 -0
  33. package/lib/archive/db-ops/_shared/decode-json-ref.js +31 -0
  34. package/lib/archive/db-ops/_shared/load-response-headers-by-set-ids.d.ts +20 -0
  35. package/lib/archive/db-ops/_shared/load-response-headers-by-set-ids.js +53 -0
  36. package/lib/archive/db-ops/_shared/resolve-content-item-id.d.ts +61 -0
  37. package/lib/archive/db-ops/_shared/resolve-content-item-id.js +111 -0
  38. package/lib/archive/db-ops/_shared/resolve-url-or-blob.d.ts +23 -0
  39. package/lib/archive/db-ops/_shared/resolve-url-or-blob.js +29 -0
  40. package/lib/archive/db-ops/_shared/retry-setting.d.ts +16 -0
  41. package/lib/archive/db-ops/_shared/retry-setting.js +18 -0
  42. package/lib/archive/db-ops/_shared/safe-parse-json.d.ts +11 -0
  43. package/lib/archive/db-ops/_shared/safe-parse-json.js +18 -0
  44. package/lib/archive/db-ops/_shared/types.d.ts +53 -0
  45. package/lib/archive/db-ops/_shared/types.js +1 -0
  46. package/lib/archive/db-ops/_shared/upsert-blob-ref.d.ts +25 -0
  47. package/lib/archive/db-ops/_shared/upsert-blob-ref.js +48 -0
  48. package/lib/archive/db-ops/_shared/upsert-content-type-ref.d.ts +30 -0
  49. package/lib/archive/db-ops/_shared/upsert-content-type-ref.js +45 -0
  50. package/lib/archive/db-ops/_shared/upsert-json-ref.d.ts +22 -0
  51. package/lib/archive/db-ops/_shared/upsert-json-ref.js +41 -0
  52. package/lib/archive/db-ops/_shared/upsert-response-headers.d.ts +35 -0
  53. package/lib/archive/db-ops/_shared/upsert-response-headers.js +49 -0
  54. package/lib/archive/db-ops/_shared/upsert-url-ref.d.ts +39 -0
  55. package/lib/archive/db-ops/_shared/upsert-url-ref.js +62 -0
  56. package/lib/archive/db-ops/analysis/replace-analysis-violations.d.ts +28 -0
  57. package/lib/archive/db-ops/analysis/replace-analysis-violations.js +152 -0
  58. package/lib/archive/db-ops/anchors/get-anchors-on-page.d.ts +10 -0
  59. package/lib/archive/db-ops/anchors/get-anchors-on-page.js +21 -0
  60. package/lib/archive/db-ops/config/get-base-url.d.ts +8 -0
  61. package/lib/archive/db-ops/config/get-base-url.js +14 -0
  62. package/lib/archive/db-ops/config/get-config.d.ts +10 -0
  63. package/lib/archive/db-ops/config/get-config.js +27 -0
  64. package/lib/archive/db-ops/config/get-name.d.ts +8 -0
  65. package/lib/archive/db-ops/config/get-name.js +14 -0
  66. package/lib/archive/db-ops/config/info-column-allowlist.d.ts +7 -0
  67. package/lib/archive/db-ops/config/info-column-allowlist.js +26 -0
  68. package/lib/archive/db-ops/config/info-json-columns.d.ts +5 -0
  69. package/lib/archive/db-ops/config/info-json-columns.js +10 -0
  70. package/lib/archive/db-ops/config/set-config.d.ts +12 -0
  71. package/lib/archive/db-ops/config/set-config.js +21 -0
  72. package/lib/archive/db-ops/config/update-config.d.ts +17 -0
  73. package/lib/archive/db-ops/config/update-config.js +36 -0
  74. package/lib/archive/db-ops/errors/insert-crawl-error.d.ts +15 -0
  75. package/lib/archive/db-ops/errors/insert-crawl-error.js +21 -0
  76. package/lib/archive/db-ops/errors/insert-page-error.d.ts +21 -0
  77. package/lib/archive/db-ops/errors/insert-page-error.js +28 -0
  78. package/lib/archive/db-ops/errors/list-dns-burned-host-candidates.d.ts +22 -0
  79. package/lib/archive/db-ops/errors/list-dns-burned-host-candidates.js +141 -0
  80. package/lib/archive/db-ops/html/get-html-of-page-by-id.d.ts +18 -0
  81. package/lib/archive/db-ops/html/get-html-of-page-by-id.js +29 -0
  82. package/lib/archive/db-ops/inventory/record-inventory-run.d.ts +21 -0
  83. package/lib/archive/db-ops/inventory/record-inventory-run.js +38 -0
  84. package/lib/archive/db-ops/lifecycle/checkpoint.d.ts +8 -0
  85. package/lib/archive/db-ops/lifecycle/checkpoint.js +9 -0
  86. package/lib/archive/db-ops/lifecycle/destroy.d.ts +6 -0
  87. package/lib/archive/db-ops/lifecycle/destroy.js +7 -0
  88. package/lib/archive/db-ops/lifecycle/init.d.ts +22 -0
  89. package/lib/archive/db-ops/lifecycle/init.js +42 -0
  90. package/lib/archive/db-ops/meta/get-jsonld-of-page.d.ts +13 -0
  91. package/lib/archive/db-ops/meta/get-jsonld-of-page.js +27 -0
  92. package/lib/archive/db-ops/meta/get-tags-of-page.d.ts +12 -0
  93. package/lib/archive/db-ops/meta/get-tags-of-page.js +28 -0
  94. package/lib/archive/db-ops/pages/order/set-url-order.d.ts +8 -0
  95. package/lib/archive/db-ops/pages/order/set-url-order.js +32 -0
  96. package/lib/archive/db-ops/pages/read/build-page-query.d.ts +18 -0
  97. package/lib/archive/db-ops/pages/read/build-page-query.js +40 -0
  98. package/lib/archive/db-ops/pages/read/get-crawling-state.d.ts +70 -0
  99. package/lib/archive/db-ops/pages/read/get-crawling-state.js +98 -0
  100. package/lib/archive/db-ops/pages/read/get-existing-page-urls.d.ts +15 -0
  101. package/lib/archive/db-ops/pages/read/get-existing-page-urls.js +30 -0
  102. package/lib/archive/db-ops/pages/read/get-page-count.d.ts +12 -0
  103. package/lib/archive/db-ops/pages/read/get-page-count.js +21 -0
  104. package/lib/archive/db-ops/pages/read/get-page-source-by-url.d.ts +24 -0
  105. package/lib/archive/db-ops/pages/read/get-page-source-by-url.js +28 -0
  106. package/lib/archive/db-ops/pages/read/get-pages-with-rels.d.ts +38 -0
  107. package/lib/archive/db-ops/pages/read/get-pages-with-rels.js +107 -0
  108. package/lib/archive/db-ops/pages/read/get-pages.d.ts +11 -0
  109. package/lib/archive/db-ops/pages/read/get-pages.js +51 -0
  110. package/lib/archive/db-ops/pages/read/get-scraped-html-page-count.d.ts +18 -0
  111. package/lib/archive/db-ops/pages/read/get-scraped-html-page-count.js +25 -0
  112. package/lib/archive/db-ops/pages/read/reconstruct-page-rows.d.ts +31 -0
  113. package/lib/archive/db-ops/pages/read/reconstruct-page-rows.js +32 -0
  114. package/lib/archive/db-ops/pages/reset/repromote-external-pages.d.ts +24 -0
  115. package/lib/archive/db-ops/pages/reset/repromote-external-pages.js +93 -0
  116. package/lib/archive/db-ops/pages/reset/reset-failed-pages.d.ts +47 -0
  117. package/lib/archive/db-ops/pages/reset/reset-failed-pages.js +124 -0
  118. package/lib/archive/db-ops/pages/write/insert-inventory-seeds.d.ts +37 -0
  119. package/lib/archive/db-ops/pages/write/insert-inventory-seeds.js +72 -0
  120. package/lib/archive/db-ops/pages/write/insert-jsonld.d.ts +17 -0
  121. package/lib/archive/db-ops/pages/write/insert-jsonld.js +49 -0
  122. package/lib/archive/db-ops/pages/write/insert-page.d.ts +36 -0
  123. package/lib/archive/db-ops/pages/write/insert-page.js +208 -0
  124. package/lib/archive/db-ops/pages/write/insert-tags.d.ts +16 -0
  125. package/lib/archive/db-ops/pages/write/insert-tags.js +34 -0
  126. package/lib/archive/db-ops/pages/write/link-redirect-sources.d.ts +36 -0
  127. package/lib/archive/db-ops/pages/write/link-redirect-sources.js +93 -0
  128. package/lib/archive/db-ops/pages/write/record-redirect.d.ts +35 -0
  129. package/lib/archive/db-ops/pages/write/record-redirect.js +100 -0
  130. package/lib/archive/db-ops/pages/write/set-skipped-page.d.ts +13 -0
  131. package/lib/archive/db-ops/pages/write/set-skipped-page.js +22 -0
  132. package/lib/archive/db-ops/pages/write/update-page.d.ts +29 -0
  133. package/lib/archive/db-ops/pages/write/update-page.js +334 -0
  134. package/lib/archive/db-ops/pages/write/write-page-html-blob.d.ts +19 -0
  135. package/lib/archive/db-ops/pages/write/write-page-html-blob.js +41 -0
  136. package/lib/archive/db-ops/referrers/get-redirects-for-pages.d.ts +9 -0
  137. package/lib/archive/db-ops/referrers/get-redirects-for-pages.js +15 -0
  138. package/lib/archive/db-ops/referrers/get-referrers-of-page.d.ts +17 -0
  139. package/lib/archive/db-ops/referrers/get-referrers-of-page.js +32 -0
  140. package/lib/archive/db-ops/referrers/get-referrers-of-resource.d.ts +8 -0
  141. package/lib/archive/db-ops/referrers/get-referrers-of-resource.js +15 -0
  142. package/lib/archive/db-ops/resources/build-resource-query.d.ts +25 -0
  143. package/lib/archive/db-ops/resources/build-resource-query.js +29 -0
  144. package/lib/archive/db-ops/resources/get-existing-resource-urls.d.ts +9 -0
  145. package/lib/archive/db-ops/resources/get-existing-resource-urls.js +24 -0
  146. package/lib/archive/db-ops/resources/get-resource-by-url.d.ts +13 -0
  147. package/lib/archive/db-ops/resources/get-resource-by-url.js +22 -0
  148. package/lib/archive/db-ops/resources/get-resource-url-list.d.ts +9 -0
  149. package/lib/archive/db-ops/resources/get-resource-url-list.js +13 -0
  150. package/lib/archive/db-ops/resources/get-resources.d.ts +8 -0
  151. package/lib/archive/db-ops/resources/get-resources.js +11 -0
  152. package/lib/archive/db-ops/resources/insert-inventory-resources.d.ts +24 -0
  153. package/lib/archive/db-ops/resources/insert-inventory-resources.js +64 -0
  154. package/lib/archive/db-ops/resources/insert-resource-referrers.d.ts +15 -0
  155. package/lib/archive/db-ops/resources/insert-resource-referrers.js +54 -0
  156. package/lib/archive/db-ops/resources/insert-resource.d.ts +34 -0
  157. package/lib/archive/db-ops/resources/insert-resource.js +73 -0
  158. package/lib/archive/db-ops/resources/reconstruct-resource-rows.d.ts +26 -0
  159. package/lib/archive/db-ops/resources/reconstruct-resource-rows.js +30 -0
  160. package/lib/archive/decode-html-blob.d.ts +18 -0
  161. package/lib/archive/decode-html-blob.js +31 -0
  162. package/lib/archive/derive-lineage-from-parent.d.ts +37 -0
  163. package/lib/archive/derive-lineage-from-parent.js +42 -0
  164. package/lib/archive/drop-legacy-tables.d.ts +45 -0
  165. package/lib/archive/drop-legacy-tables.js +56 -0
  166. package/lib/archive/filesystem/rename.js +1 -1
  167. package/lib/archive/get-failed-page-messages.d.ts +44 -0
  168. package/lib/archive/get-failed-page-messages.js +132 -0
  169. package/lib/archive/init-schema.d.ts +35 -39
  170. package/lib/archive/init-schema.js +111 -320
  171. package/lib/archive/is-inventory-source.d.ts +21 -0
  172. package/lib/archive/is-inventory-source.js +22 -0
  173. package/lib/archive/limited-page-ids.d.ts +2 -1
  174. package/lib/archive/limited-page-ids.js +5 -4
  175. package/lib/archive/meta/assert-compatible-version.d.ts +24 -3
  176. package/lib/archive/meta/assert-compatible-version.js +24 -3
  177. package/lib/archive/meta/types.d.ts +87 -1
  178. package/lib/archive/meta/types.js +34 -2
  179. package/lib/archive/migrate-entity-tables.d.ts +45 -0
  180. package/lib/archive/migrate-entity-tables.js +56 -0
  181. package/lib/archive/migrate-ref-tables.d.ts +25 -0
  182. package/lib/archive/migrate-ref-tables.js +38 -0
  183. package/lib/archive/page-meta-column-maps.d.ts +32 -0
  184. package/lib/archive/page-meta-column-maps.js +43 -0
  185. package/lib/archive/page.d.ts +6 -6
  186. package/lib/archive/page.js +5 -5
  187. package/lib/archive/peek-archive-lock.d.ts +2 -2
  188. package/lib/archive/peek-archive-lock.js +2 -2
  189. package/lib/archive/populate-entity-tables/collapse-anchor-rows.d.ts +41 -0
  190. package/lib/archive/populate-entity-tables/collapse-anchor-rows.js +87 -0
  191. package/lib/archive/populate-entity-tables/derive-dom-path.d.ts +35 -0
  192. package/lib/archive/populate-entity-tables/derive-dom-path.js +72 -0
  193. package/lib/archive/populate-entity-tables/is-blob-ref-value.d.ts +16 -0
  194. package/lib/archive/populate-entity-tables/is-blob-ref-value.js +19 -0
  195. package/lib/archive/populate-entity-tables/match-images-to-dom-paths.d.ts +66 -0
  196. package/lib/archive/populate-entity-tables/match-images-to-dom-paths.js +96 -0
  197. package/lib/archive/populate-entity-tables/populate-anchor-edges.d.ts +33 -0
  198. package/lib/archive/populate-entity-tables/populate-anchor-edges.js +153 -0
  199. package/lib/archive/populate-entity-tables/populate-content-items.d.ts +40 -0
  200. package/lib/archive/populate-entity-tables/populate-content-items.js +141 -0
  201. package/lib/archive/populate-entity-tables/populate-entities.d.ts +81 -0
  202. package/lib/archive/populate-entity-tables/populate-entities.js +111 -0
  203. package/lib/archive/populate-entity-tables/populate-image-items.d.ts +91 -0
  204. package/lib/archive/populate-entity-tables/populate-image-items.js +223 -0
  205. package/lib/archive/populate-entity-tables/populate-page-meta.d.ts +33 -0
  206. package/lib/archive/populate-entity-tables/populate-page-meta.js +267 -0
  207. package/lib/archive/populate-entity-tables/populate-resource-items.d.ts +22 -0
  208. package/lib/archive/populate-entity-tables/populate-resource-items.js +114 -0
  209. package/lib/archive/populate-entity-tables/populate-resource-ref-edges.d.ts +31 -0
  210. package/lib/archive/populate-entity-tables/populate-resource-ref-edges.js +33 -0
  211. package/lib/archive/populate-entity-tables/resolve-blob-refs.d.ts +31 -0
  212. package/lib/archive/populate-entity-tables/resolve-blob-refs.js +100 -0
  213. package/lib/archive/populate-entity-tables/resolve-content-type-refs.d.ts +22 -0
  214. package/lib/archive/populate-entity-tables/resolve-content-type-refs.js +27 -0
  215. package/lib/archive/populate-entity-tables/resolve-header-sets.d.ts +49 -0
  216. package/lib/archive/populate-entity-tables/resolve-header-sets.js +122 -0
  217. package/lib/archive/populate-entity-tables/resolve-json-refs.d.ts +25 -0
  218. package/lib/archive/populate-entity-tables/resolve-json-refs.js +67 -0
  219. package/lib/archive/populate-entity-tables/resolve-text-refs.d.ts +30 -0
  220. package/lib/archive/populate-entity-tables/resolve-text-refs.js +61 -0
  221. package/lib/archive/populate-entity-tables/resolve-url-or-blob-from-maps.d.ts +21 -0
  222. package/lib/archive/populate-entity-tables/resolve-url-or-blob-from-maps.js +27 -0
  223. package/lib/archive/populate-entity-tables/resolve-url-refs.d.ts +33 -0
  224. package/lib/archive/populate-entity-tables/resolve-url-refs.js +60 -0
  225. package/lib/archive/populate-entity-tables/test-utils/count-rows.d.ts +17 -0
  226. package/lib/archive/populate-entity-tables/test-utils/count-rows.js +20 -0
  227. package/lib/archive/populate-entity-tables/test-utils/seed-content-items.d.ts +25 -0
  228. package/lib/archive/populate-entity-tables/test-utils/seed-content-items.js +42 -0
  229. package/lib/archive/populate-entity-tables/test-utils/setup-entities-db.d.ts +23 -0
  230. package/lib/archive/populate-entity-tables/test-utils/setup-entities-db.js +178 -0
  231. package/lib/archive/populate-entity-tables/types.d.ts +157 -0
  232. package/lib/archive/populate-entity-tables/types.js +12 -0
  233. package/lib/archive/populate-entity-tables/upsert-text-refs.d.ts +38 -0
  234. package/lib/archive/populate-entity-tables/upsert-text-refs.js +78 -0
  235. package/lib/archive/populate-ref-tables/classify-content-type.d.ts +16 -0
  236. package/lib/archive/populate-ref-tables/classify-content-type.js +52 -0
  237. package/lib/archive/populate-ref-tables/compute-content-hash.d.ts +22 -0
  238. package/lib/archive/populate-ref-tables/compute-content-hash.js +26 -0
  239. package/lib/archive/populate-ref-tables/compute-header-flags.d.ts +16 -0
  240. package/lib/archive/populate-ref-tables/compute-header-flags.js +70 -0
  241. package/lib/archive/populate-ref-tables/content-type-rules.d.ts +38 -0
  242. package/lib/archive/populate-ref-tables/content-type-rules.js +133 -0
  243. package/lib/archive/populate-ref-tables/create-header-table-caches.d.ts +25 -0
  244. package/lib/archive/populate-ref-tables/create-header-table-caches.js +49 -0
  245. package/lib/archive/populate-ref-tables/data-uri-url-refs-limit.d.ts +15 -0
  246. package/lib/archive/populate-ref-tables/data-uri-url-refs-limit.js +15 -0
  247. package/lib/archive/populate-ref-tables/decode-data-uri.d.ts +21 -0
  248. package/lib/archive/populate-ref-tables/decode-data-uri.js +126 -0
  249. package/lib/archive/populate-ref-tables/decompose-header-set.d.ts +29 -0
  250. package/lib/archive/populate-ref-tables/decompose-header-set.js +157 -0
  251. package/lib/archive/populate-ref-tables/decompose-url.d.ts +25 -0
  252. package/lib/archive/populate-ref-tables/decompose-url.js +70 -0
  253. package/lib/archive/populate-ref-tables/header-stability.d.ts +19 -0
  254. package/lib/archive/populate-ref-tables/header-stability.js +22 -0
  255. package/lib/archive/populate-ref-tables/header-value-cache-key.d.ts +17 -0
  256. package/lib/archive/populate-ref-tables/header-value-cache-key.js +19 -0
  257. package/lib/archive/populate-ref-tables/normalize-mime.d.ts +24 -0
  258. package/lib/archive/populate-ref-tables/normalize-mime.js +36 -0
  259. package/lib/archive/populate-ref-tables/populate-blob-refs.d.ts +38 -0
  260. package/lib/archive/populate-ref-tables/populate-blob-refs.js +134 -0
  261. package/lib/archive/populate-ref-tables/populate-content-type-refs.d.ts +27 -0
  262. package/lib/archive/populate-ref-tables/populate-content-type-refs.js +70 -0
  263. package/lib/archive/populate-ref-tables/populate-header-tables.d.ts +35 -0
  264. package/lib/archive/populate-ref-tables/populate-header-tables.js +80 -0
  265. package/lib/archive/populate-ref-tables/populate-json-refs.d.ts +29 -0
  266. package/lib/archive/populate-ref-tables/populate-json-refs.js +101 -0
  267. package/lib/archive/populate-ref-tables/populate-refs.d.ts +51 -0
  268. package/lib/archive/populate-ref-tables/populate-refs.js +62 -0
  269. package/lib/archive/populate-ref-tables/populate-text-refs.d.ts +32 -0
  270. package/lib/archive/populate-ref-tables/populate-text-refs.js +133 -0
  271. package/lib/archive/populate-ref-tables/populate-url-refs.d.ts +28 -0
  272. package/lib/archive/populate-ref-tables/populate-url-refs.js +148 -0
  273. package/lib/archive/populate-ref-tables/test-utils/count-rows.d.ts +15 -0
  274. package/lib/archive/populate-ref-tables/test-utils/count-rows.js +17 -0
  275. package/lib/archive/populate-ref-tables/types.d.ts +197 -0
  276. package/lib/archive/populate-ref-tables/types.js +7 -0
  277. package/lib/archive/populate-ref-tables/upsert-one-header-set.d.ts +34 -0
  278. package/lib/archive/populate-ref-tables/upsert-one-header-set.js +208 -0
  279. package/lib/archive/populate-ref-tables/volatile-header-names.d.ts +20 -0
  280. package/lib/archive/populate-ref-tables/volatile-header-names.js +33 -0
  281. package/lib/archive/redirect-table.d.ts +4 -2
  282. package/lib/archive/redirect-table.js +15 -10
  283. package/lib/archive/resolve-redirect-chain.d.ts +3 -3
  284. package/lib/archive/resolve-redirect-chain.js +2 -2
  285. package/lib/archive/resource.d.ts +1 -1
  286. package/lib/archive/retarget-legacy-fk-tables.d.ts +47 -0
  287. package/lib/archive/retarget-legacy-fk-tables.js +107 -0
  288. package/lib/archive/test-utils/fk-parent-tables.d.ts +15 -0
  289. package/lib/archive/test-utils/fk-parent-tables.js +19 -0
  290. package/lib/archive/test-utils/seed-content-item.d.ts +35 -0
  291. package/lib/archive/test-utils/seed-content-item.js +42 -0
  292. package/lib/archive/test-utils/setup-legacy-fk-db.d.ts +33 -0
  293. package/lib/archive/test-utils/setup-legacy-fk-db.js +270 -0
  294. package/lib/archive/types.d.ts +151 -15
  295. package/lib/archive/verify-migration/capture-rejection.d.ts +24 -0
  296. package/lib/archive/verify-migration/capture-rejection.js +31 -0
  297. package/lib/archive/verify-migration/check-anchor-edges-count.d.ts +34 -0
  298. package/lib/archive/verify-migration/check-anchor-edges-count.js +72 -0
  299. package/lib/archive/verify-migration/check-anchor-edges-sum.d.ts +13 -0
  300. package/lib/archive/verify-migration/check-anchor-edges-sum.js +27 -0
  301. package/lib/archive/verify-migration/check-content-items-count.d.ts +16 -0
  302. package/lib/archive/verify-migration/check-content-items-count.js +30 -0
  303. package/lib/archive/verify-migration/check-content-type-preservation.d.ts +22 -0
  304. package/lib/archive/verify-migration/check-content-type-preservation.js +40 -0
  305. package/lib/archive/verify-migration/check-foreign-key-integrity.d.ts +31 -0
  306. package/lib/archive/verify-migration/check-foreign-key-integrity.js +47 -0
  307. package/lib/archive/verify-migration/check-image-items-count.d.ts +12 -0
  308. package/lib/archive/verify-migration/check-image-items-count.js +26 -0
  309. package/lib/archive/verify-migration/check-page-meta-count.d.ts +15 -0
  310. package/lib/archive/verify-migration/check-page-meta-count.js +31 -0
  311. package/lib/archive/verify-migration/check-reader-parity.d.ts +23 -0
  312. package/lib/archive/verify-migration/check-reader-parity.js +211 -0
  313. package/lib/archive/verify-migration/check-resource-items-count.d.ts +17 -0
  314. package/lib/archive/verify-migration/check-resource-items-count.js +33 -0
  315. package/lib/archive/verify-migration/check-url-round-trip.d.ts +43 -0
  316. package/lib/archive/verify-migration/check-url-round-trip.js +112 -0
  317. package/lib/archive/verify-migration/types.d.ts +70 -0
  318. package/lib/archive/verify-migration/types.js +63 -0
  319. package/lib/archive/verify-migration/verify-migration.d.ts +41 -0
  320. package/lib/archive/verify-migration/verify-migration.js +120 -0
  321. package/lib/classify-error-kind.d.ts +19 -0
  322. package/lib/classify-error-kind.js +122 -0
  323. package/lib/crawler/build-js-redirect-edge.d.ts +68 -0
  324. package/lib/crawler/build-js-redirect-edge.js +57 -0
  325. package/lib/crawler/build-redirect-event.d.ts +24 -0
  326. package/lib/crawler/build-redirect-event.js +28 -0
  327. package/lib/crawler/capture-image-dom-paths.d.ts +33 -0
  328. package/lib/crawler/capture-image-dom-paths.js +39 -0
  329. package/lib/crawler/clear-dns-burned-host-cache.d.ts +6 -0
  330. package/lib/crawler/clear-dns-burned-host-cache.js +11 -0
  331. package/lib/crawler/collect-image-dom-paths.d.ts +23 -0
  332. package/lib/crawler/collect-image-dom-paths.js +64 -0
  333. package/lib/crawler/crawler.d.ts +22 -1
  334. package/lib/crawler/crawler.js +679 -117
  335. package/lib/crawler/derive-js-redirect-target.d.ts +68 -0
  336. package/lib/crawler/derive-js-redirect-target.js +129 -0
  337. package/lib/crawler/derive-resource-source.d.ts +25 -15
  338. package/lib/crawler/derive-resource-source.js +28 -17
  339. package/lib/crawler/dns-burned-host-cache.d.ts +26 -0
  340. package/lib/crawler/dns-burned-host-cache.js +25 -0
  341. package/lib/crawler/dns-burned-host-short-circuit-counter.d.ts +13 -0
  342. package/lib/crawler/dns-burned-host-short-circuit-counter.js +11 -0
  343. package/lib/crawler/fetch-destination.d.ts +12 -4
  344. package/lib/crawler/fetch-destination.js +94 -16
  345. package/lib/crawler/inject-scope-auth.d.ts +1 -1
  346. package/lib/crawler/inject-scope-auth.js +1 -1
  347. package/lib/crawler/is-js-redirect-error-shape.d.ts +40 -0
  348. package/lib/crawler/is-js-redirect-error-shape.js +53 -0
  349. package/lib/crawler/is-puppeteer-fallback-candidate.d.ts +16 -0
  350. package/lib/crawler/is-puppeteer-fallback-candidate.js +63 -0
  351. package/lib/crawler/link-list.d.ts +21 -1
  352. package/lib/crawler/link-list.js +23 -3
  353. package/lib/crawler/normalize-content-type.d.ts +1 -1
  354. package/lib/crawler/normalize-content-type.js +1 -1
  355. package/lib/crawler/plan-sub-resource-emits.d.ts +63 -0
  356. package/lib/crawler/plan-sub-resource-emits.js +44 -0
  357. package/lib/crawler/preload-short-circuit-error.d.ts +22 -0
  358. package/lib/crawler/preload-short-circuit-error.js +25 -0
  359. package/lib/crawler/should-burn-host.d.ts +78 -0
  360. package/lib/crawler/should-burn-host.js +61 -0
  361. package/lib/crawler/should-get-fallback-on-head-failure.d.ts +38 -0
  362. package/lib/crawler/should-get-fallback-on-head-failure.js +46 -0
  363. package/lib/crawler/types.d.ts +108 -1
  364. package/lib/crawler-orchestrator.d.ts +22 -3
  365. package/lib/crawler-orchestrator.js +312 -73
  366. package/lib/crawler.d.ts +15 -2
  367. package/lib/crawler.js +24 -1
  368. package/lib/permanent-error-kinds.d.ts +43 -0
  369. package/lib/permanent-error-kinds.js +48 -0
  370. package/lib/types.d.ts +84 -0
  371. package/lib/utils/compute-file-sha256.d.ts +24 -0
  372. package/lib/utils/compute-file-sha256.js +56 -0
  373. package/lib/utils/error/emit-error-with-retry.d.ts +40 -0
  374. package/lib/utils/error/emit-error-with-retry.js +44 -0
  375. package/lib/utils/error/emit-error.d.ts +39 -0
  376. package/lib/utils/error/emit-error.js +41 -0
  377. package/package.json +12 -12
  378. package/lib/archive/migrate-crawl-errors.d.ts +0 -20
  379. package/lib/archive/migrate-crawl-errors.js +0 -38
  380. package/lib/archive/migrate-html-blob-tables.d.ts +0 -24
  381. package/lib/archive/migrate-html-blob-tables.js +0 -53
  382. package/lib/archive/migrate-page-errors.d.ts +0 -16
  383. package/lib/archive/migrate-page-errors.js +0 -35
  384. package/lib/archive/migrate-pages-resources-source.d.ts +0 -16
  385. package/lib/archive/migrate-pages-resources-source.js +0 -46
  386. package/lib/utils/error/error-emitter.d.ts +0 -18
  387. package/lib/utils/error/error-emitter.js +0 -29
@@ -0,0 +1,270 @@
1
+ /**
2
+ * Provisions the pre-0.13 legacy table shape on a test database:
3
+ * the five legacy write-model tables (`pages` / `anchors` / `images` /
4
+ * `resources` / `resources-referrers`) plus the five adjunct tables in
5
+ * their old form whose FK columns still point at `pages(id)`
6
+ * (`page_html_ref` / `page_tags` / `page_jsonld` / `page_errors` /
7
+ * `analysis_violations`, with their companion tables `page_html_blobs` /
8
+ * `analysis_text_refs`).
9
+ *
10
+ * `initSchema` no longer creates any of these shapes — fresh archives get
11
+ * neither the legacy write-model tables nor `pages(id)`-referencing
12
+ * adjunct tables — so specs that exercise the migration input format
13
+ * (`scripts/migrate-to-0.13.mjs` integration, `retargetLegacyFkTables`,
14
+ * `dropLegacyTables`) build it through this helper instead. The DDL is a
15
+ * verbatim copy of what pre-0.13 archives actually contain: the legacy
16
+ * write-model tables match the pre-0.13 `initSchema`, and the adjunct
17
+ * tables match the `scripts/migrate-to-0.10.mjs` / lazy-runtime-migration
18
+ * output of that era.
19
+ *
20
+ * Any current-form adjunct tables already present (e.g. created by
21
+ * `Archive.create()` on the current schema) are dropped first so the
22
+ * old-FK versions can take their place — callers get a deterministic
23
+ * "genuine pre-0.13 archive" shape regardless of how the underlying DB
24
+ * was provisioned.
25
+ * @param db - Knex connected to the test DB (or a transaction).
26
+ * @example
27
+ * await createRefTables(db);
28
+ * await createEntityTables(db);
29
+ * await setupLegacyFkDb(db);
30
+ * await db('pages').insert({ url: 'https://example.com/', scraped: 1, isTarget: 1 });
31
+ */
32
+ export async function setupLegacyFkDb(db) {
33
+ // Children before parents so the drops never trip FK enforcement
34
+ // when the caller has `PRAGMA foreign_keys = ON`.
35
+ await db.raw('DROP TABLE IF EXISTS "page_html_ref"');
36
+ await db.raw('DROP TABLE IF EXISTS "page_html_blobs"');
37
+ await db.raw('DROP TABLE IF EXISTS "analysis_violations"');
38
+ await db.raw('DROP TABLE IF EXISTS "analysis_text_refs"');
39
+ await db.raw('DROP TABLE IF EXISTS "page_tags"');
40
+ await db.raw('DROP TABLE IF EXISTS "page_jsonld"');
41
+ await db.raw('DROP TABLE IF EXISTS "page_errors"');
42
+ await db.schema
43
+ .createTable('pages', (t) => {
44
+ t.increments('id');
45
+ t.string('url', 8190).notNullable().unique();
46
+ t.integer('redirectDestId').unsigned().references('pages.id').defaultTo(null);
47
+ t.boolean('scraped').notNullable();
48
+ t.boolean('isTarget').notNullable();
49
+ t.boolean('isExternal');
50
+ t.integer('status');
51
+ t.string('statusText');
52
+ t.string('contentType').nullable();
53
+ t.integer('contentLength').unsigned().nullable();
54
+ t.json('responseHeaders').nullable();
55
+ // Document basics
56
+ t.string('lang');
57
+ t.string('dir');
58
+ t.string('charset');
59
+ t.string('baseHref');
60
+ t.text('viewport_raw');
61
+ t.string('themeColor');
62
+ t.string('applicationName');
63
+ t.string('author');
64
+ t.string('generator');
65
+ t.string('publisher');
66
+ // Title / description / keywords (top-level Meta fields)
67
+ t.string('title');
68
+ t.text('description');
69
+ t.text('keywords');
70
+ // Robots
71
+ t.text('robots_raw');
72
+ t.integer('robots_noindex');
73
+ t.integer('robots_nofollow');
74
+ t.integer('robots_noarchive');
75
+ t.integer('robots_noimageindex');
76
+ t.string('googlebot');
77
+ // Link (1:1 only — array shapes live in meta_extras)
78
+ t.string('canonical', 8190);
79
+ t.string('amphtml', 8190);
80
+ t.string('manifest', 8190);
81
+ t.string('icon_href', 8190);
82
+ t.string('appleTouchIcon_href', 8190);
83
+ // Open Graph
84
+ t.string('og_type');
85
+ t.string('og_title');
86
+ t.string('og_url', 8190);
87
+ t.string('og_site_name');
88
+ t.text('og_description');
89
+ t.string('og_image', 8190);
90
+ t.string('og_image_alt');
91
+ t.string('og_image_width');
92
+ t.string('og_image_height');
93
+ t.string('og_locale');
94
+ t.string('og_article_published_time');
95
+ t.string('og_article_modified_time');
96
+ // Twitter
97
+ t.string('twitter_card');
98
+ t.string('twitter_site');
99
+ t.string('twitter_creator');
100
+ t.string('twitter_title');
101
+ t.text('twitter_description');
102
+ t.string('twitter_image', 8190);
103
+ // One-offs
104
+ t.string('fb_app_id');
105
+ t.string('verification_google');
106
+ t.integer('formatDetection_telephone');
107
+ // Within-archive observation timestamps (UNIX ms)
108
+ t.integer('firstCrawledAt');
109
+ t.integer('lastCrawledAt');
110
+ // Denormalised aggregates
111
+ t.integer('tag_count');
112
+ t.integer('jsonld_count');
113
+ t.text('tags_providers_csv');
114
+ // Catch-all JSON for nested Meta sub-objects not flattened above
115
+ t.json('meta_extras');
116
+ // Crawl lifecycle
117
+ t.boolean('isSkipped');
118
+ t.string('skipReason');
119
+ t.integer('order').unsigned().nullable();
120
+ t.string('source').notNullable().defaultTo('crawled');
121
+ t.index('isExternal');
122
+ t.index('contentType');
123
+ t.index('scraped');
124
+ t.index('redirectDestId');
125
+ t.index('order');
126
+ t.index('robots_noindex');
127
+ t.index('og_type');
128
+ t.index('source');
129
+ })
130
+ .createTable('anchors', (t) => {
131
+ t.increments('id');
132
+ t.integer('pageId').notNullable().unsigned().references('pages.id');
133
+ t.integer('hrefId').notNullable().unsigned().references('pages.id');
134
+ t.string('hash');
135
+ t.string('textContent').nullable();
136
+ t.index('pageId');
137
+ t.index('hrefId');
138
+ })
139
+ .createTable('images', (t) => {
140
+ t.increments('id');
141
+ t.integer('pageId').notNullable().unsigned().references('pages.id');
142
+ t.string('src', 8190);
143
+ t.string('currentSrc', 8190);
144
+ t.string('alt');
145
+ t.float('width').unsigned().notNullable();
146
+ t.float('height').unsigned().notNullable();
147
+ t.integer('naturalWidth').unsigned().notNullable();
148
+ t.integer('naturalHeight').unsigned().notNullable();
149
+ t.boolean('isLazy');
150
+ t.integer('viewportWidth').unsigned().notNullable();
151
+ t.string('sourceCode');
152
+ t.index('pageId');
153
+ })
154
+ .createTable('resources', (t) => {
155
+ t.increments('id');
156
+ t.string('url', 8190).notNullable().unique();
157
+ t.boolean('isExternal');
158
+ t.integer('status');
159
+ t.string('statusText');
160
+ t.string('contentType').nullable();
161
+ t.integer('contentLength').unsigned().nullable();
162
+ t.string('compress').nullable();
163
+ t.string('cdn').nullable();
164
+ t.json('responseHeaders').nullable();
165
+ t.string('source').notNullable().defaultTo('crawled');
166
+ t.index('source');
167
+ })
168
+ .createTable('resources-referrers', (t) => {
169
+ t.increments('id');
170
+ t.integer('resourceId').notNullable().unsigned().references('resources.id');
171
+ t.integer('pageId').notNullable().unsigned().references('pages.id');
172
+ t.unique(['resourceId', 'pageId']);
173
+ t.index('resourceId');
174
+ t.index('pageId');
175
+ });
176
+ // Adjunct tables in their pre-0.13 shape: FK columns point at
177
+ // `pages(id)` — the exact declarations that
178
+ // `scripts/migrate-to-0.10.mjs` and the runtime lazy migrations of
179
+ // that era produced.
180
+ await db.schema.createTable('page_errors', (t) => {
181
+ t.increments('id');
182
+ t.integer('pageId').notNullable().unsigned().references('pages.id');
183
+ t.string('phase').notNullable();
184
+ t.text('message').notNullable();
185
+ t.integer('createdAt').notNullable();
186
+ t.index('pageId');
187
+ });
188
+ await db.schema.createTable('page_tags', (t) => {
189
+ t.increments('id');
190
+ t.integer('pageId')
191
+ .notNullable()
192
+ .unsigned()
193
+ .references('pages.id')
194
+ .onDelete('CASCADE');
195
+ t.string('provider').notNullable();
196
+ t.string('category');
197
+ t.string('externalId');
198
+ t.string('version');
199
+ t.integer('confidence');
200
+ t.json('categories');
201
+ t.json('sources');
202
+ t.index('pageId');
203
+ t.index('provider');
204
+ t.index('externalId');
205
+ });
206
+ await db.raw('CREATE INDEX page_tags_provider_extId ON page_tags(provider, externalId)');
207
+ await db.raw('CREATE INDEX page_tags_provider_pageId ON page_tags(provider, pageId)');
208
+ await db.schema.createTable('page_jsonld', (t) => {
209
+ t.increments('id');
210
+ t.integer('pageId')
211
+ .notNullable()
212
+ .unsigned()
213
+ .references('pages.id')
214
+ .onDelete('CASCADE');
215
+ t.string('kind').notNullable();
216
+ t.string('type');
217
+ t.text('raw').notNullable();
218
+ t.json('parsed');
219
+ t.text('parseError');
220
+ t.index('pageId');
221
+ t.index('type');
222
+ });
223
+ await db.raw('CREATE INDEX page_jsonld_type_pageId ON page_jsonld(type, pageId)');
224
+ await db.raw(`
225
+ CREATE TABLE analysis_text_refs (
226
+ id integer primary key,
227
+ text text not null,
228
+ sha256 text not null,
229
+ unique(sha256, text)
230
+ )
231
+ `);
232
+ await db.raw(`
233
+ CREATE TABLE analysis_violations (
234
+ id integer primary key,
235
+ page_id integer not null references pages(id),
236
+ validator text not null,
237
+ severity text not null,
238
+ rule text not null,
239
+ message_text_id integer not null references analysis_text_refs(id),
240
+ code_text_id integer references analysis_text_refs(id),
241
+ page_url_sort_key text not null,
242
+ message_sort_key text not null,
243
+ code_sort_key text not null
244
+ )
245
+ `);
246
+ await db.raw('CREATE INDEX av_url_order ON analysis_violations(page_url_sort_key, id)');
247
+ await db.raw('CREATE INDEX av_filter_url ON analysis_violations(validator, severity, rule, page_url_sort_key, id)');
248
+ await db.raw('CREATE INDEX av_validator_url ON analysis_violations(validator, page_url_sort_key, id)');
249
+ await db.raw('CREATE INDEX av_severity_url ON analysis_violations(severity, page_url_sort_key, id)');
250
+ await db.raw('CREATE INDEX av_rule_url ON analysis_violations(rule, page_url_sort_key, id)');
251
+ await db.raw('CREATE INDEX av_message_order ON analysis_violations(message_sort_key, id)');
252
+ await db.raw('CREATE INDEX av_code_order ON analysis_violations(code_sort_key, id)');
253
+ await db.raw('CREATE INDEX av_page ON analysis_violations(page_id, id)');
254
+ await db.raw(`
255
+ CREATE TABLE page_html_blobs (
256
+ hash BLOB PRIMARY KEY,
257
+ body BLOB NOT NULL,
258
+ codec TEXT NOT NULL CHECK(codec IN ('zstd', 'none')),
259
+ size_raw INTEGER NOT NULL,
260
+ size_stored INTEGER NOT NULL
261
+ ) WITHOUT ROWID
262
+ `);
263
+ await db.raw(`
264
+ CREATE TABLE page_html_ref (
265
+ page_id INTEGER PRIMARY KEY REFERENCES pages(id) ON DELETE CASCADE,
266
+ hash BLOB NOT NULL REFERENCES page_html_blobs(hash)
267
+ ) WITHOUT ROWID
268
+ `);
269
+ await db.raw('CREATE INDEX idx_page_html_ref_hash ON page_html_ref(hash)');
270
+ }
@@ -1,6 +1,25 @@
1
+ import type { DomPathCandidate } from './populate-entity-tables/types.js';
2
+ import type { PageData } from '../utils/types/types.js';
1
3
  import type { ParseURLOptions } from '@d-zero/shared/parse-url';
4
+ /**
5
+ * A scraped page payload optionally enriched with the in-browser
6
+ * dom-path capture (`crawler/capture-image-dom-paths.ts`): every `<img>`
7
+ * of the rendered document as `{ outerHTML, path }` pairs in document
8
+ * order. The write path matches these against `imageList[].sourceCode`
9
+ * to resolve `image_items.dom_path_text_id`; when absent (capture
10
+ * failed, metadata-only scrape, or a caller that never renders), every
11
+ * image falls back to the synthetic `unknown/<n>` marker.
12
+ */
13
+ export type PageDataWithDomPaths = PageData & {
14
+ /** In-browser dom-path capture for the rendered document's images. */
15
+ imageDomPaths?: readonly DomPathCandidate[];
16
+ };
2
17
  /**
3
18
  * Event map for database-related events emitted by the Database and ArchiveAccessor classes.
19
+ * @example
20
+ * archive.on('error', (error) => {
21
+ * console.error('database failure:', error.message);
22
+ * });
4
23
  */
5
24
  export interface DatabaseEvent {
6
25
  /** An error that occurred during a database operation. */
@@ -9,6 +28,9 @@ export interface DatabaseEvent {
9
28
  /**
10
29
  * Configuration stored in the archive database's `info` table.
11
30
  * Represents all crawling options that were used for the crawl session.
31
+ * @example
32
+ * const config = await archive.getConfig();
33
+ * console.log(config.roots, config.userAgent, config.parallels);
12
34
  */
13
35
  export interface Config extends Required<Pick<ParseURLOptions, 'disableQueries'>> {
14
36
  /** The starting URL for the crawl. Stored as a denormalised mirror of `roots[0]` so summary consumers can read a single URL without parsing the array. */
@@ -48,12 +70,11 @@ export interface Config extends Required<Pick<ParseURLOptions, 'disableQueries'>
48
70
  }
49
71
  /**
50
72
  * Provenance of a page or resource row — which crawler channel originally
51
- * inserted it. Stored as `pages.source` / `resources.source` in the
52
- * SQLite schema (NOT NULL DEFAULT `'crawled'`).
73
+ * inserted it. Stored as `content_items.source` / `resource_items.source`
74
+ * in the SQLite schema (NOT NULL DEFAULT `'crawled'`).
53
75
  *
54
76
  * - `'crawled'` — discovered via the recursive crawl rooted at `info.roots`.
55
- * Default for pre-`--inventory` archives after the
56
- * `migratePagesResourcesSource` runtime migration.
77
+ * Default for rows that predate the `--inventory` feature.
57
78
  * - `'inventory-seed'` — supplied directly by a `crawl --inventory` URL
58
79
  * list. For pages this is the HTML URL that was rendered; for resources
59
80
  * this is a non-HTML URL handed in by the list (HEAD-fetched without
@@ -66,8 +87,55 @@ export interface Config extends Required<Pick<ParseURLOptions, 'disableQueries'>
66
87
  * Isolation queries (`listIsolatedPages` / `listUnusedResources`) judge
67
88
  * orphans by `referrer = 0`, NOT by this value — `source` only labels
68
89
  * the row.
90
+ * @example
91
+ * if (page.source !== 'crawled') {
92
+ * // Row was introduced by a `crawl --inventory` pass.
93
+ * }
69
94
  */
70
95
  export type PageSource = 'crawled' | 'inventory-seed' | 'inventory-discovered';
96
+ /**
97
+ * One row written to the `inventory_runs` audit table on each successful
98
+ * `--inventory <list>` invocation.
99
+ *
100
+ * Schema-mirror interface: every column on `inventory_runs` is represented
101
+ * here. Only `ran_at` is required — every other field is nullable so a
102
+ * raw-SQL backfill (a one-off `sqlite3 INSERT` recording an inventory
103
+ * pass that predates this table) can omit summary
104
+ * stats it cannot reconstruct.
105
+ *
106
+ * The audit log is append-only: there is intentionally no UPDATE path,
107
+ * no UNIQUE constraint on `source_file_sha256`, and no FK to pages /
108
+ * resources — re-applying the same list yields a second row. Duplicate
109
+ * detection is a read-side concern; `source_file_sha256` is recorded as
110
+ * the content-identity key it would use.
111
+ * @example
112
+ * await archive.recordInventoryRun({
113
+ * ran_at: new Date().toISOString(),
114
+ * list_label: 'prod-2026-06',
115
+ * total_lines: 113_268,
116
+ * new_pages: 1234,
117
+ * new_resources: 56,
118
+ * scope_skipped: 7,
119
+ * });
120
+ */
121
+ export interface InventoryRunMeta {
122
+ /** ISO 8601 timestamp at which the run completed (e.g. `'2026-06-21T11:30:00+09:00'`). */
123
+ ran_at: string;
124
+ /** Human-readable identifier (e.g. `'prod-2026-06-21'`). `null` when the caller did not supply one. */
125
+ list_label?: string | null;
126
+ /** SHA-256 hex digest of the source file. `null` if hashing failed (e.g. file vanished mid-run). */
127
+ source_file_sha256?: string | null;
128
+ /** Number of non-empty lines in the input list (= URL count before scope filtering). */
129
+ total_lines?: number | null;
130
+ /** Number of new HTML seeds inserted as `content_items` rows by this run. */
131
+ new_pages?: number | null;
132
+ /** Number of new non-HTML URLs inserted as `resource_items` rows by this run. */
133
+ new_resources?: number | null;
134
+ /** Number of input URLs dropped because they fell outside the archived scope. */
135
+ scope_skipped?: number | null;
136
+ /** Free-form text for backfill annotations or operator notes. */
137
+ notes?: string | null;
138
+ }
71
139
  /**
72
140
  * Filter type for querying pages from the database.
73
141
  *
@@ -78,16 +146,28 @@ export type PageSource = 'crawled' | 'inventory-seed' | 'inventory-discovered';
78
146
  * - `'no-page'` - Non-HTML resources (e.g., images, PDFs)
79
147
  * - `'external-no-page'` - External non-HTML resources
80
148
  * - `'internal-no-page'` - Internal non-HTML resources
149
+ * @example
150
+ * const internalHtmlPages = await accessor.getPages('internal-page');
81
151
  */
82
152
  export type PageFilter = 'page' | 'page-included-no-target' | 'external-page' | 'internal-page' | 'no-page' | 'external-no-page' | 'internal-no-page';
83
153
  /**
84
- * Raw database row representing a crawled page in the `pages` table (v2 schema).
154
+ * Flat page-row shape.
85
155
  *
86
- * Maps 1:1 to the columns defined by `archive/init-schema.ts`. Most meta
87
- * fields are derived from beholder 3.0.0's nested {@link import('@d-zero/beholder').Meta}
88
- * via `archive/meta/derive-flat-from-meta.ts` and are stored as plain
89
- * scalars for SQL-level filter / projection. The catch-all `meta_extras`
90
- * JSON column preserves nested sub-objects not flattened above.
156
+ * Serves two roles: (1) the read shape that
157
+ * `db-ops/pages/read/reconstruct-page-rows.ts` rebuilds by joining the
158
+ * entity / ref tables (`content_items` / `page_meta` / `url_refs` …), and
159
+ * (2) the raw row shape of the pre-0.13 legacy `pages` table, which only
160
+ * exists inside pre-0.13 input archives and is read by the 0.13 migration
161
+ * populate code. Most meta fields are derived from beholder 3.0.0's nested
162
+ * {@link import('@d-zero/beholder').Meta} via
163
+ * `archive/meta/derive-flat-from-meta.ts` and are stored as plain scalars
164
+ * for SQL-level filter / projection. The catch-all `meta_extras` JSON
165
+ * column preserves nested sub-objects not flattened above.
166
+ * @example
167
+ * const pages = await accessor.getPages('page');
168
+ * for (const page of pages) {
169
+ * console.log(page.url, page.status, page.title);
170
+ * }
91
171
  */
92
172
  export interface DB_Page {
93
173
  /** Auto-incremented primary key. */
@@ -228,6 +308,12 @@ export interface DB_Page {
228
308
  /**
229
309
  * Raw database row representing a redirect relationship.
230
310
  * Maps a source page to its redirect destination.
311
+ * @example
312
+ * const redirect: DB_Redirect = {
313
+ * pageId: 9, // destination page id
314
+ * from: 'http://example.com/old',
315
+ * fromId: 3,
316
+ * };
231
317
  */
232
318
  export interface DB_Redirect {
233
319
  /** The ID of the destination page after redirect. */
@@ -238,8 +324,12 @@ export interface DB_Redirect {
238
324
  fromId: number;
239
325
  }
240
326
  /**
241
- * Raw database row representing an anchor (link) found on a page.
242
- * Combines data from the `anchors` table and the linked `pages` table.
327
+ * Flat anchor-row shape reconstructed by joining `anchor_edges` with the
328
+ * destination's `content_items` row and the ref tables. Also mirrors the
329
+ * pre-0.13 legacy `anchors` join shape read by the migration populate code.
330
+ * @example
331
+ * const anchors = await accessor.getAnchorsOnPage(pageId);
332
+ * const brokenLinks = anchors.filter((a) => a.status === 404);
243
333
  */
244
334
  export interface DB_Anchor {
245
335
  /** The ID of the page that contains this anchor. */
@@ -266,6 +356,10 @@ export interface DB_Anchor {
266
356
  /**
267
357
  * Raw database row representing a referrer relationship.
268
358
  * Indicates which page links to which other page, potentially through redirects.
359
+ * @example
360
+ * const referrers = await accessor.getReferrersOfPage(pageId);
361
+ * // `through` differs from the destination URL when the link passed
362
+ * // through a redirect source.
269
363
  */
270
364
  export interface DB_Referrer {
271
365
  /** The ID of the page being referred to. */
@@ -282,7 +376,15 @@ export interface DB_Referrer {
282
376
  textContent: string | null;
283
377
  }
284
378
  /**
285
- * Raw database row representing an image element found on a page in the `images` table.
379
+ * Raw database row of the pre-0.13 legacy `images` table. The table only
380
+ * exists inside pre-0.13 input archives; current archives store images in
381
+ * `image_items`. This type is read exclusively by the 0.13 migration
382
+ * populate code (`populate-image-items.ts`), which converts these rows
383
+ * into `image_items` before the legacy table is dropped.
384
+ * @example
385
+ * // Inside migration populate code reading a pre-0.13 input archive:
386
+ * const images: DB_Image[] = await trx('images').where('pageId', pageId);
387
+ * const missingAlt = images.filter((img) => img.alt === null);
286
388
  */
287
389
  export interface DB_Image {
288
390
  /** Auto-incremented primary key. */
@@ -312,6 +414,14 @@ export interface DB_Image {
312
414
  }
313
415
  /**
314
416
  * Represents a page that links to another page (an incoming link).
417
+ * @example
418
+ * const referrer: Referrer = {
419
+ * url: 'https://example.com/from',
420
+ * through: 'https://example.com/old',
421
+ * throughId: 3,
422
+ * hash: null,
423
+ * textContent: 'Link text',
424
+ * };
315
425
  */
316
426
  export interface Referrer {
317
427
  /** The URL of the referring page. */
@@ -327,6 +437,18 @@ export interface Referrer {
327
437
  }
328
438
  /**
329
439
  * Represents an outgoing link (anchor element) found on a page.
440
+ * @example
441
+ * const anchor: Anchor = {
442
+ * url: 'https://example.com/about',
443
+ * href: '/about',
444
+ * isExternal: false,
445
+ * title: null,
446
+ * status: 200,
447
+ * statusText: 'OK',
448
+ * contentType: 'text/html',
449
+ * hash: null,
450
+ * textContent: 'About us',
451
+ * };
330
452
  */
331
453
  export interface Anchor {
332
454
  /** The resolved destination URL of the anchor. */
@@ -350,6 +472,8 @@ export interface Anchor {
350
472
  }
351
473
  /**
352
474
  * Represents a page that redirects to this page.
475
+ * @example
476
+ * const redirect: Redirect = { url: 'http://example.com/old', pageId: 3 };
353
477
  */
354
478
  export interface Redirect {
355
479
  /** The URL of the redirect source page. */
@@ -359,12 +483,19 @@ export interface Redirect {
359
483
  }
360
484
  /**
361
485
  * Raw database row representing a sub-resource (CSS, JS, image, etc.) in the `resources` table.
486
+ * @example
487
+ * const resources = await accessor.getResources();
488
+ * const notFound = resources.filter((r) => r.status === 404);
362
489
  */
363
490
  export interface DB_Resource {
364
491
  /** Auto-incremented primary key. */
365
492
  id: number;
366
- /** The URL of the resource. */
367
- url: string;
493
+ /**
494
+ * The URL of the resource, or `null` when its identity URL is a large
495
+ * `data:` URI routed to `blob_refs` instead of `url_refs` (mirrors
496
+ * `image_items`' src/blob convention — see `build-resource-query.ts`).
497
+ */
498
+ url: string | null;
368
499
  /** Whether the resource is hosted on an external domain (1) or internal (0). */
369
500
  isExternal: 0 | 1;
370
501
  /** HTTP response status code, or null if not yet fetched. */
@@ -386,6 +517,11 @@ export interface DB_Resource {
386
517
  }
387
518
  /**
388
519
  * Connection options for the archive's libsql-backed database.
520
+ * @example
521
+ * const db = await Database.connect({
522
+ * filename: '/path/to/._nitpicker-site/db.sqlite',
523
+ * readOnly: true,
524
+ * });
389
525
  */
390
526
  export interface DatabaseOption {
391
527
  /** The absolute file path to the SQLite database file. */
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Awaits a rejecting promise and returns the thrown value. Fails the caller
3
+ * with a descriptive error if the promise resolves. Lets assertions treat
4
+ * the caught value as a normal object without needing a try/catch in the
5
+ * test body — the qa-engineer rule bans `if` / `switch` / try-catch inside
6
+ * test code because control flow inside a test hides which assertion is
7
+ * actually running when a check fails.
8
+ *
9
+ * The sentinel is a fresh `Symbol` per invocation so a genuine rejection
10
+ * whose reason is `undefined` is still correctly distinguished from a
11
+ * resolution to `undefined`.
12
+ *
13
+ * Shared by `check-reader-parity.spec.ts` and `verify-migration.spec.ts`
14
+ * (and any future verify-migration spec that needs to inspect a rejection
15
+ * reason). Not exported from the package — this is a test-only utility
16
+ * kept next to its callers.
17
+ * @param promise - The promise expected to reject.
18
+ * @returns The rejection reason.
19
+ * @example
20
+ * const error = await captureRejection(verifyMigration(db));
21
+ * expect(error).toBeInstanceOf(MigrationVerificationError);
22
+ * expect((error as MigrationVerificationError).details.check).toContain('#1');
23
+ */
24
+ export declare function captureRejection(promise: Promise<unknown>): Promise<unknown>;
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Awaits a rejecting promise and returns the thrown value. Fails the caller
3
+ * with a descriptive error if the promise resolves. Lets assertions treat
4
+ * the caught value as a normal object without needing a try/catch in the
5
+ * test body — the qa-engineer rule bans `if` / `switch` / try-catch inside
6
+ * test code because control flow inside a test hides which assertion is
7
+ * actually running when a check fails.
8
+ *
9
+ * The sentinel is a fresh `Symbol` per invocation so a genuine rejection
10
+ * whose reason is `undefined` is still correctly distinguished from a
11
+ * resolution to `undefined`.
12
+ *
13
+ * Shared by `check-reader-parity.spec.ts` and `verify-migration.spec.ts`
14
+ * (and any future verify-migration spec that needs to inspect a rejection
15
+ * reason). Not exported from the package — this is a test-only utility
16
+ * kept next to its callers.
17
+ * @param promise - The promise expected to reject.
18
+ * @returns The rejection reason.
19
+ * @example
20
+ * const error = await captureRejection(verifyMigration(db));
21
+ * expect(error).toBeInstanceOf(MigrationVerificationError);
22
+ * expect((error as MigrationVerificationError).details.check).toContain('#1');
23
+ */
24
+ export async function captureRejection(promise) {
25
+ const sentinel = Symbol('did-not-throw');
26
+ const value = await promise.then(() => sentinel, (error) => error);
27
+ if (value === sentinel) {
28
+ throw new Error('captureRejection: promise resolved but was expected to reject — the code path under test is silently succeeding');
29
+ }
30
+ return value;
31
+ }
@@ -0,0 +1,34 @@
1
+ import type { Knex } from 'knex';
2
+ /**
3
+ * Verifies 0.13 invariant #3: the `anchor_edges` dedup does not
4
+ * eliminate rows and does not create phantom rows.
5
+ *
6
+ * `populateAnchorEdges` collapses N `anchors` rows per `(pageId, hrefId)`
7
+ * pair into a single `anchor_edges` row with `count = N`. Two ways it
8
+ * could go wrong:
9
+ *
10
+ * - `count(anchor_edges) == 0 && count(anchors) > 0` — dedup annihilated
11
+ * the graph. A populate bug or a group-by mis-key would trip this.
12
+ * - `count(anchor_edges) > count(anchors)` — dedup produced more rows than
13
+ * inputs. Impossible under a correct `GROUP BY` but a phantom-insert bug
14
+ * in the populate loop would trip this.
15
+ *
16
+ * `count(anchor_edges) == count(anchors)` is **not** a failure. Issue #194
17
+ * spelled the upper bound as `< count(anchors)` (strict), but a legitimate
18
+ * small crawl where every `(pageId, hrefId)` pair is unique produces one
19
+ * edge per anchor (count=1) and satisfies the identity naturally. Enforcing
20
+ * strict `<` would refuse to migrate such archives even though every other
21
+ * invariant holds; the true invariant is "no rows added or dropped by
22
+ * dedup" (`anchor_edges <= anchors`), so the code enforces the weaker,
23
+ * correct clause. Check #4 (`SUM(count) == count(anchors)`) already
24
+ * establishes that no rows were silently discarded when the counts happen
25
+ * to match.
26
+ *
27
+ * A trivial archive with zero `anchors` legitimately produces zero
28
+ * `anchor_edges`, so both counts being zero passes; a non-zero `anchor_edges`
29
+ * with a zero `anchors` still throws — that would mean rows appeared from
30
+ * nowhere.
31
+ * @param trx - Knex instance or transaction connected to the populated archive.
32
+ * @throws {MigrationVerificationError} when the invariant is violated.
33
+ */
34
+ export declare function checkAnchorEdgesCount(trx: Knex): Promise<void>;