@mailwoman/corpus 10.0.0 → 10.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 (1372) hide show
  1. package/README.md +120 -34
  2. package/data/PROVENANCE.md +623 -17
  3. package/data/address-source-register.json +14249 -0
  4. package/data/builds/v0.7.0-de-holdout/inputs.json +22 -0
  5. package/data/builds/v0.8.0-registers/inputs.json +92 -0
  6. package/data/license-decisions.json +1603 -0
  7. package/data/licenses/PROVENANCE.md +65 -0
  8. package/data/licenses/cdla-permissive-2.0.md +43 -0
  9. package/data/licenses/geonames-publication.md +34 -0
  10. package/data/licenses/licence-ouverte-2.0.md +36 -0
  11. package/data/licenses/national-address-database.md +46 -0
  12. package/data/licenses/nlod-2.0.md +90 -0
  13. package/data/licenses/sirene-publication.md +38 -0
  14. package/data/licenses/whosonfirst-licenses.md +65 -0
  15. package/data/source-resolutions.json +804 -0
  16. package/data/sub-venue-lexicon.json +1 -1
  17. package/data/training-manifests/v0.7.0-de-holdout.effective.json +477 -0
  18. package/data/training-manifests/v0.7.0-de-holdout.json +78 -0
  19. package/lib/adapters/cordis/adapter.ts +785 -0
  20. package/lib/adapters/dedup-key.ts +40 -0
  21. package/lib/adapters/errors.ts +21 -0
  22. package/lib/adapters/geonames/adapter.ts +42 -52
  23. package/lib/adapters/geonames/postal/adapter.ts +31 -37
  24. package/lib/adapters/gleif/adapter.ts +828 -0
  25. package/lib/adapters/libpostal-dictionary.ts +39 -0
  26. package/lib/adapters/openaddresses/adapter.ts +51 -55
  27. package/lib/adapters/osm/adapter.ts +148 -70
  28. package/lib/adapters/overture/adapter.ts +52 -43
  29. package/lib/adapters/po-box/adapter.ts +202 -0
  30. package/lib/adapters/registry.ts +79 -0
  31. package/lib/adapters/sha256-stream.ts +49 -0
  32. package/lib/adapters/source-id.ts +49 -0
  33. package/lib/adapters/street-line.ts +135 -0
  34. package/lib/adapters/wof/admin/json/adapter.ts +48 -33
  35. package/lib/adapters/wof/json-rows.ts +56 -26
  36. package/lib/adapters/wof/postalcode-json/adapter.ts +57 -59
  37. package/lib/adapters.ts +230 -0
  38. package/lib/au/adapters/gnaf/adapter.ts +35 -43
  39. package/lib/au/adapters/gnaf/assemble.ts +31 -51
  40. package/lib/be/adapters/brussels/adapter.ts +566 -0
  41. package/lib/be/adapters/vlaanderen/adapter.ts +670 -0
  42. package/lib/be/adapters/wallonie/adapter.ts +537 -0
  43. package/lib/be/tools/fetch/brussels.ts +239 -0
  44. package/lib/be/tools/fetch/wallonie.ts +274 -0
  45. package/lib/build/adapters.ts +110 -0
  46. package/lib/build/align.ts +364 -0
  47. package/lib/build/checkpoint.ts +131 -0
  48. package/lib/build/eligibility.ts +96 -0
  49. package/lib/build/heap.ts +53 -0
  50. package/lib/build/inputs.ts +81 -0
  51. package/lib/build/rows.ts +21 -0
  52. package/lib/build/types.ts +232 -0
  53. package/lib/build.ts +127 -315
  54. package/lib/cn/recipes/organizational-units.ts +20 -41
  55. package/lib/cz/adapters/cuzk/adapter.ts +317 -0
  56. package/lib/cz/recipes/pcfirst-preposition.ts +40 -27
  57. package/lib/cz/tools/fetch/cuzk.ts +699 -0
  58. package/lib/de/recipes/locale.ts +68 -58
  59. package/lib/directory.ts +31 -0
  60. package/lib/dk/adapters/inspire/adapter.ts +345 -0
  61. package/lib/dk/tools/fetch/inspire.ts +321 -0
  62. package/lib/ee/adapters/ads/adapter.ts +246 -0
  63. package/lib/ee/tools/fetch/ads.ts +270 -0
  64. package/lib/env.ts +6 -2
  65. package/lib/es/adapters/bizkaia/adapter.ts +388 -0
  66. package/lib/es/adapters/catastro/adapter.ts +343 -0
  67. package/lib/es/adapters/gipuzkoa/adapter.ts +263 -0
  68. package/lib/es/adapters/navarra/adapter.ts +289 -0
  69. package/lib/es/cadastre.ts +194 -0
  70. package/lib/es/tools/fetch/bizkaia.ts +748 -0
  71. package/lib/es/tools/fetch/catastro.ts +754 -0
  72. package/lib/es/tools/fetch/gipuzkoa.ts +336 -0
  73. package/lib/es/tools/fetch/navarra.ts +488 -0
  74. package/lib/fi/adapters/ryhti/adapter.ts +323 -0
  75. package/lib/fi/tools/fetch/ryhti.ts +476 -0
  76. package/lib/fingerprints.ts +154 -0
  77. package/lib/fr/adapters/annuaire-education/adapter.ts +598 -0
  78. package/lib/fr/adapters/ban/adapter.ts +87 -59
  79. package/lib/fr/adapters/finess/adapter.ts +618 -0
  80. package/lib/fr/adapters/finess/postal-lines.ts +157 -0
  81. package/lib/fr/adapters/finess/voie-type.ts +200 -0
  82. package/lib/fr/insee-country.ts +62 -0
  83. package/lib/fr/recipes/admin-split.ts +38 -60
  84. package/lib/fr/recipes/bare-street.ts +37 -50
  85. package/lib/fr/recipes/fragment.ts +59 -142
  86. package/lib/fr/recipes/lieudit.ts +109 -73
  87. package/lib/fr/recipes/order.ts +32 -59
  88. package/lib/fr/{adapters/ban/street-decompose.ts → street-decompose.ts} +4 -3
  89. package/lib/fr/tools/fetch/annuaire-education.ts +306 -0
  90. package/lib/fr/tools/fetch/ban.ts +28 -19
  91. package/lib/fr/tools/fetch/finess.ts +352 -0
  92. package/lib/gauntlet-inputs.ts +92 -0
  93. package/lib/index.ts +9 -3
  94. package/lib/inspire/address.ts +457 -0
  95. package/lib/inspire/archive.ts +44 -0
  96. package/lib/inspire/errors.ts +71 -0
  97. package/lib/inspire/stream.ts +262 -0
  98. package/lib/international/recipes/locale.ts +134 -176
  99. package/lib/it/adapters/anac/adapter.ts +522 -0
  100. package/lib/it/tools/fetch/anac.ts +394 -0
  101. package/lib/jp/adapters/wof-admin/adapter.ts +27 -17
  102. package/lib/jp/tools/fetch/houjin.ts +16 -18
  103. package/lib/kr/adapters/juso/label-rows.ts +24 -44
  104. package/lib/kr/adapters/localdata/align.ts +20 -31
  105. package/lib/kr/adapters/localdata/key-index.ts +17 -25
  106. package/lib/kr/adapters/localdata/permit-rows.ts +33 -26
  107. package/lib/kr/tools/fetch/juso.ts +19 -21
  108. package/lib/kr/tools/fetch/localdata.ts +28 -29
  109. package/lib/lu/adapters/bd-adresses/adapter.ts +240 -0
  110. package/lib/lu/tools/fetch/bd-adresses.ts +351 -0
  111. package/lib/lv/adapters/varis/adapter.ts +499 -0
  112. package/lib/lv/tools/fetch/varis.ts +214 -0
  113. package/lib/nl/adapters/kadaster/adapter.ts +386 -0
  114. package/lib/nl/recipes/postcode.ts +46 -24
  115. package/lib/nl/tools/fetch/kadaster.ts +298 -0
  116. package/lib/no/adapters/matrikkelen/adapter.ts +187 -0
  117. package/lib/no/recipes/fragment.ts +34 -58
  118. package/lib/no/recipes/street/led.ts +44 -25
  119. package/lib/no/recipes/{street/index.ts → street.ts} +29 -11
  120. package/lib/no/tools/fetch/matrikkelen.ts +519 -0
  121. package/lib/parquet/duckdb.ts +144 -0
  122. package/lib/parquet/readers.ts +86 -0
  123. package/lib/parquet/schema.ts +214 -0
  124. package/lib/parquet/shuffle.ts +59 -0
  125. package/lib/parquet/span-sql.ts +54 -0
  126. package/lib/parquet/streams.ts +113 -0
  127. package/lib/parquet/writers.ts +451 -0
  128. package/lib/pl/adapters/emuia/adapter.ts +202 -0
  129. package/lib/pl/tools/fetch/emuia.ts +360 -0
  130. package/lib/recipes/anchor-absorption.ts +30 -19
  131. package/lib/recipes/bare/country.ts +24 -32
  132. package/lib/recipes/bare/postcode/eval.ts +1 -1
  133. package/lib/recipes/bare/postcode.ts +346 -0
  134. package/lib/recipes/boundary-stress.ts +36 -19
  135. package/lib/recipes/country-balanced.ts +66 -86
  136. package/lib/recipes/house-venue.ts +31 -13
  137. package/lib/recipes/intersection.ts +82 -60
  138. package/lib/recipes/po/box/cedex/au-nz.ts +3 -3
  139. package/lib/recipes/po/box/cedex/ca.ts +3 -2
  140. package/lib/recipes/po/box/cedex/fr.ts +4 -3
  141. package/lib/recipes/po/box/cedex/phrases.ts +7 -6
  142. package/lib/recipes/po/box/cedex/recipe.ts +28 -16
  143. package/lib/recipes/po/box/cedex/sources.ts +3 -3
  144. package/lib/recipes/po/box/cedex/us.ts +7 -2
  145. package/lib/recipes/po/{box/index.ts → box.ts} +39 -18
  146. package/lib/recipes/scaffold.ts +252 -153
  147. package/lib/recipes/sources.ts +399 -0
  148. package/lib/recipes/street/affix.ts +54 -154
  149. package/lib/recipes/street/bare.ts +28 -15
  150. package/lib/recipes/street.ts +32 -8
  151. package/lib/recipes/sub/venue/context.ts +30 -23
  152. package/lib/recipes/sub/venue/render.ts +170 -0
  153. package/lib/recipes/sub/venue/sources.ts +68 -219
  154. package/lib/recipes/sub/venue.ts +801 -0
  155. package/lib/recipes/trailing-region.ts +69 -85
  156. package/lib/recipes/unit/sources.ts +44 -0
  157. package/lib/recipes/unit.ts +101 -89
  158. package/lib/{recipes/index.ts → recipes.ts} +13 -11
  159. package/lib/registers.ts +278 -0
  160. package/lib/ro/adapters/retea-scolara/adapter.ts +264 -0
  161. package/lib/ro/tools/fetch/retea-scolara.ts +187 -0
  162. package/lib/runner.ts +220 -84
  163. package/lib/sg/recipes/register.ts +46 -52
  164. package/lib/sg/tools/fetch/acra.ts +20 -25
  165. package/lib/si/recipes/bare-village.ts +34 -17
  166. package/lib/sk/adapters/inspire/adapter.ts +395 -0
  167. package/lib/sk/tools/fetch/inspire.ts +402 -0
  168. package/lib/source-register/effective-manifest.ts +659 -0
  169. package/lib/source-register/register.ts +539 -0
  170. package/lib/source-register/training-manifest.ts +218 -0
  171. package/lib/source-register/types.ts +590 -0
  172. package/lib/source-register.ts +71 -0
  173. package/lib/south-asia/recipes/register.ts +45 -26
  174. package/lib/subvenue/harvest.ts +251 -0
  175. package/lib/{tools/sub/venue → subvenue}/promotions.ts +33 -70
  176. package/lib/subvenue/surfaces.ts +94 -0
  177. package/lib/subvenue/table.ts +264 -0
  178. package/lib/surfaces/locale.ts +246 -0
  179. package/lib/synthesizers/anchor-absorption.ts +55 -91
  180. package/lib/synthesizers/boundary-stress.ts +49 -131
  181. package/lib/synthesizers/house-venue.ts +44 -102
  182. package/lib/synthesizers/intersection.ts +37 -26
  183. package/lib/synthesizers/no-street.ts +70 -119
  184. package/lib/synthesizers/po-box.ts +90 -105
  185. package/lib/synthesizers/street.ts +46 -34
  186. package/lib/synthesizers/utils.ts +64 -218
  187. package/lib/test-kit/corpus-recipe.ts +45 -28
  188. package/lib/test-kit.ts +116 -0
  189. package/lib/tools/align-canonical.ts +64 -0
  190. package/lib/tools/audit.ts +113 -118
  191. package/lib/tools/corpus-stats.ts +44 -30
  192. package/lib/tools/fetch/atom.ts +164 -0
  193. package/lib/tools/fetch/cordis.ts +318 -0
  194. package/lib/tools/fetch/download/manifest.ts +34 -22
  195. package/lib/tools/fetch/download/network.ts +55 -31
  196. package/lib/tools/fetch/download/retry.ts +26 -25
  197. package/lib/tools/fetch/geonames/dump.ts +72 -54
  198. package/lib/tools/fetch/geonames/postal.ts +27 -62
  199. package/lib/tools/fetch/gleif.ts +360 -0
  200. package/lib/tools/fetch/header.ts +69 -0
  201. package/lib/tools/fetch/inspire-addresses.ts +495 -0
  202. package/lib/tools/fetch/openaddresses.ts +22 -111
  203. package/lib/tools/fetch/ourairports.ts +18 -51
  204. package/lib/tools/fetch/ppd.ts +10 -8
  205. package/lib/tools/fetch/vlaanderen-ad.ts +435 -0
  206. package/lib/tools/fetch/wfs-harvest.ts +943 -0
  207. package/lib/tools/fetch/wikidata-subvenue.ts +45 -145
  208. package/lib/tools/fetch/zip-archive.ts +100 -0
  209. package/lib/tools/fetch.ts +143 -0
  210. package/lib/tools/golden/expand.ts +74 -43
  211. package/lib/tools/golden/promote.ts +41 -32
  212. package/lib/tools/golden/relabel-street/directory.ts +63 -36
  213. package/lib/tools/golden/relabel-street/row.ts +28 -106
  214. package/lib/tools/ingest-csv.ts +45 -48
  215. package/lib/tools/jsonl-to-parquet.ts +59 -98
  216. package/lib/tools/lint/recipe-output/vocab.ts +366 -0
  217. package/lib/tools/lint/{slice/index.ts → recipe-output.ts} +107 -121
  218. package/lib/tools/migrate/overlay-parquet.ts +173 -0
  219. package/lib/tools/migrate/recipe-output.ts +153 -0
  220. package/lib/tools/migrate/source-names.ts +161 -0
  221. package/lib/tools/{slice → overlay}/kryptonite.ts +43 -36
  222. package/lib/tools/overlay/manifest.ts +407 -0
  223. package/lib/tools/overlay/merge-source.ts +138 -0
  224. package/lib/tools/overlay/split-slice.ts +144 -0
  225. package/lib/tools/{slice → overlay}/translit.ts +74 -58
  226. package/lib/tools/overture-subvenue.ts +17 -90
  227. package/lib/tools/postcode-triples.ts +281 -210
  228. package/lib/tools/source-register/build.ts +819 -0
  229. package/lib/tools/sub/venue/head-nouns.ts +38 -75
  230. package/lib/tools/sub/venue/lexicon.ts +71 -106
  231. package/lib/tools/sub/venue/wikidata.ts +13 -10
  232. package/lib/tools.ts +31 -0
  233. package/lib/tw/tools/fetch/gcis.ts +17 -16
  234. package/lib/types.ts +304 -101
  235. package/lib/us/adapters/fcc-bdc/adapter.ts +26 -41
  236. package/lib/us/adapters/state/hi-schools/adapter.ts +28 -17
  237. package/lib/us/adapters/state/hi-schools/workbook.ts +7 -2
  238. package/lib/us/adapters/state/ia-contractors/adapter.ts +27 -15
  239. package/lib/us/adapters/state/ny-notaries/adapter.ts +24 -25
  240. package/lib/us/adapters/state/tx-notaries/adapter.ts +21 -15
  241. package/lib/us/adapters/tiger/adapter.ts +19 -44
  242. package/lib/us/adapters/tiger/street-decompose.ts +7 -17
  243. package/lib/us/adapters/usgov/hrsa-fqhc/adapter.ts +49 -34
  244. package/lib/us/adapters/usgov/imls-pls/adapter.ts +25 -19
  245. package/lib/us/adapters/usgov/irs-bmf/adapter.ts +32 -23
  246. package/lib/us/adapters/usgov/nad/adapter.ts +51 -112
  247. package/lib/us/adapters/usgov/nppes/adapter.ts +72 -35
  248. package/lib/us/adapters/usgov/samhsa-treatment-locator/adapter.ts +43 -30
  249. package/lib/us/fips-state.ts +17 -8
  250. package/lib/us/tools/fetch/hrsa.ts +7 -8
  251. package/lib/us/tools/fetch/imls-pls.ts +17 -35
  252. package/lib/us/tools/fetch/nad.ts +50 -32
  253. package/lib/us/tools/fetch/nppes.ts +23 -35
  254. package/lib/us/tools/fetch/state/hi-schools.ts +22 -16
  255. package/lib/us/tools/fetch/state/sources.ts +12 -12
  256. package/lib/us/tools/fetch/tiger-full.ts +21 -73
  257. package/lib/utils/align.ts +42 -52
  258. package/lib/utils/{slice-stats.ts → cooccurrence-stats.ts} +22 -16
  259. package/lib/utils/golden.ts +34 -49
  260. package/lib/utils/license.ts +238 -26
  261. package/lib/utils/split.ts +205 -88
  262. package/lib/utils/tokenize.ts +22 -34
  263. package/lib/utils/wof-json.ts +129 -76
  264. package/lib/{utils/index.ts → utils.ts} +0 -1
  265. package/lib/ve/recipes/reviewed-postcode-tail.ts +40 -13
  266. package/out/adapters/cordis/adapter.d.ts +324 -0
  267. package/out/adapters/cordis/adapter.d.ts.map +1 -0
  268. package/out/adapters/cordis/adapter.js +616 -0
  269. package/out/adapters/cordis/adapter.js.map +1 -0
  270. package/out/adapters/dedup-key.d.ts +30 -0
  271. package/out/adapters/dedup-key.d.ts.map +1 -0
  272. package/out/adapters/dedup-key.js +35 -0
  273. package/out/adapters/dedup-key.js.map +1 -0
  274. package/out/adapters/errors.d.ts +17 -0
  275. package/out/adapters/errors.d.ts.map +1 -0
  276. package/out/adapters/errors.js +20 -0
  277. package/out/adapters/errors.js.map +1 -0
  278. package/out/adapters/geonames/adapter.d.ts +26 -28
  279. package/out/adapters/geonames/adapter.d.ts.map +1 -1
  280. package/out/adapters/geonames/adapter.js +39 -49
  281. package/out/adapters/geonames/adapter.js.map +1 -1
  282. package/out/adapters/geonames/postal/adapter.d.ts +14 -27
  283. package/out/adapters/geonames/postal/adapter.d.ts.map +1 -1
  284. package/out/adapters/geonames/postal/adapter.js +30 -35
  285. package/out/adapters/geonames/postal/adapter.js.map +1 -1
  286. package/out/adapters/gleif/adapter.d.ts +293 -0
  287. package/out/adapters/gleif/adapter.d.ts.map +1 -0
  288. package/out/adapters/gleif/adapter.js +684 -0
  289. package/out/adapters/gleif/adapter.js.map +1 -0
  290. package/out/adapters/libpostal-dictionary.d.ts +22 -0
  291. package/out/adapters/libpostal-dictionary.d.ts.map +1 -0
  292. package/out/adapters/libpostal-dictionary.js +36 -0
  293. package/out/adapters/libpostal-dictionary.js.map +1 -0
  294. package/out/adapters/openaddresses/adapter.d.ts +28 -43
  295. package/out/adapters/openaddresses/adapter.d.ts.map +1 -1
  296. package/out/adapters/openaddresses/adapter.js +34 -46
  297. package/out/adapters/openaddresses/adapter.js.map +1 -1
  298. package/out/adapters/osm/adapter.d.ts +48 -42
  299. package/out/adapters/osm/adapter.d.ts.map +1 -1
  300. package/out/adapters/osm/adapter.js +116 -67
  301. package/out/adapters/osm/adapter.js.map +1 -1
  302. package/out/adapters/overture/adapter.d.ts +11 -37
  303. package/out/adapters/overture/adapter.d.ts.map +1 -1
  304. package/out/adapters/overture/adapter.js +45 -42
  305. package/out/adapters/overture/adapter.js.map +1 -1
  306. package/out/adapters/po-box/adapter.d.ts +63 -0
  307. package/out/adapters/po-box/adapter.d.ts.map +1 -0
  308. package/out/adapters/{synth-po-box → po-box}/adapter.js +45 -46
  309. package/out/adapters/po-box/adapter.js.map +1 -0
  310. package/out/adapters/registry.d.ts +55 -0
  311. package/out/adapters/registry.d.ts.map +1 -0
  312. package/out/adapters/registry.js +43 -0
  313. package/out/adapters/registry.js.map +1 -0
  314. package/out/adapters/sha256-stream.d.ts +26 -0
  315. package/out/adapters/sha256-stream.d.ts.map +1 -0
  316. package/out/adapters/sha256-stream.js +34 -0
  317. package/out/adapters/sha256-stream.js.map +1 -0
  318. package/out/adapters/source-id.d.ts +33 -0
  319. package/out/adapters/source-id.d.ts.map +1 -0
  320. package/out/adapters/source-id.js +42 -0
  321. package/out/adapters/source-id.js.map +1 -0
  322. package/out/adapters/street-line.d.ts +102 -0
  323. package/out/adapters/street-line.d.ts.map +1 -0
  324. package/out/adapters/street-line.js +117 -0
  325. package/out/adapters/street-line.js.map +1 -0
  326. package/out/adapters/wof/admin/json/adapter.d.ts +27 -18
  327. package/out/adapters/wof/admin/json/adapter.d.ts.map +1 -1
  328. package/out/adapters/wof/admin/json/adapter.js +47 -31
  329. package/out/adapters/wof/admin/json/adapter.js.map +1 -1
  330. package/out/adapters/wof/json-rows.d.ts +35 -19
  331. package/out/adapters/wof/json-rows.d.ts.map +1 -1
  332. package/out/adapters/wof/json-rows.js +35 -15
  333. package/out/adapters/wof/json-rows.js.map +1 -1
  334. package/out/adapters/wof/postalcode-json/adapter.d.ts +22 -38
  335. package/out/adapters/wof/postalcode-json/adapter.d.ts.map +1 -1
  336. package/out/adapters/wof/postalcode-json/adapter.js +55 -57
  337. package/out/adapters/wof/postalcode-json/adapter.js.map +1 -1
  338. package/out/adapters.d.ts +75 -0
  339. package/out/adapters.d.ts.map +1 -0
  340. package/out/adapters.js +167 -0
  341. package/out/adapters.js.map +1 -0
  342. package/out/au/adapters/gnaf/adapter.d.ts +15 -27
  343. package/out/au/adapters/gnaf/adapter.d.ts.map +1 -1
  344. package/out/au/adapters/gnaf/adapter.js +34 -42
  345. package/out/au/adapters/gnaf/adapter.js.map +1 -1
  346. package/out/au/adapters/gnaf/assemble.d.ts +15 -26
  347. package/out/au/adapters/gnaf/assemble.d.ts.map +1 -1
  348. package/out/au/adapters/gnaf/assemble.js +26 -46
  349. package/out/au/adapters/gnaf/assemble.js.map +1 -1
  350. package/out/be/adapters/brussels/adapter.d.ts +212 -0
  351. package/out/be/adapters/brussels/adapter.d.ts.map +1 -0
  352. package/out/be/adapters/brussels/adapter.js +435 -0
  353. package/out/be/adapters/brussels/adapter.js.map +1 -0
  354. package/out/be/adapters/vlaanderen/adapter.d.ts +233 -0
  355. package/out/be/adapters/vlaanderen/adapter.d.ts.map +1 -0
  356. package/out/be/adapters/vlaanderen/adapter.js +416 -0
  357. package/out/be/adapters/vlaanderen/adapter.js.map +1 -0
  358. package/out/be/adapters/wallonie/adapter.d.ts +196 -0
  359. package/out/be/adapters/wallonie/adapter.d.ts.map +1 -0
  360. package/out/be/adapters/wallonie/adapter.js +437 -0
  361. package/out/be/adapters/wallonie/adapter.js.map +1 -0
  362. package/out/be/tools/fetch/brussels.d.ts +119 -0
  363. package/out/be/tools/fetch/brussels.d.ts.map +1 -0
  364. package/out/be/tools/fetch/brussels.js +146 -0
  365. package/out/be/tools/fetch/brussels.js.map +1 -0
  366. package/out/be/tools/fetch/wallonie.d.ts +119 -0
  367. package/out/be/tools/fetch/wallonie.d.ts.map +1 -0
  368. package/out/be/tools/fetch/wallonie.js +167 -0
  369. package/out/be/tools/fetch/wallonie.js.map +1 -0
  370. package/out/build/adapters.d.ts +33 -0
  371. package/out/build/adapters.d.ts.map +1 -0
  372. package/out/build/adapters.js +68 -0
  373. package/out/build/adapters.js.map +1 -0
  374. package/out/build/align.d.ts +73 -0
  375. package/out/build/align.d.ts.map +1 -0
  376. package/out/build/align.js +226 -0
  377. package/out/build/align.js.map +1 -0
  378. package/out/build/checkpoint.d.ts +94 -0
  379. package/out/build/checkpoint.d.ts.map +1 -0
  380. package/out/build/checkpoint.js +59 -0
  381. package/out/build/checkpoint.js.map +1 -0
  382. package/out/build/eligibility.d.ts +47 -0
  383. package/out/build/eligibility.d.ts.map +1 -0
  384. package/out/build/eligibility.js +80 -0
  385. package/out/build/eligibility.js.map +1 -0
  386. package/out/build/heap.d.ts +28 -0
  387. package/out/build/heap.d.ts.map +1 -0
  388. package/out/build/heap.js +47 -0
  389. package/out/build/heap.js.map +1 -0
  390. package/out/build/inputs.d.ts +52 -0
  391. package/out/build/inputs.d.ts.map +1 -0
  392. package/out/build/inputs.js +49 -0
  393. package/out/build/inputs.js.map +1 -0
  394. package/out/build/rows.d.ts +16 -0
  395. package/out/build/rows.d.ts.map +1 -0
  396. package/out/build/rows.js +19 -0
  397. package/out/build/rows.js.map +1 -0
  398. package/out/build/types.d.ts +220 -0
  399. package/out/build/types.d.ts.map +1 -0
  400. package/out/build/types.js +34 -0
  401. package/out/build/types.js.map +1 -0
  402. package/out/build.d.ts +6 -121
  403. package/out/build.d.ts.map +1 -1
  404. package/out/build.js +112 -207
  405. package/out/build.js.map +1 -1
  406. package/out/cn/recipes/organizational-units.d.ts +5 -22
  407. package/out/cn/recipes/organizational-units.d.ts.map +1 -1
  408. package/out/cn/recipes/organizational-units.js +20 -41
  409. package/out/cn/recipes/organizational-units.js.map +1 -1
  410. package/out/cz/adapters/cuzk/adapter.d.ts +52 -0
  411. package/out/cz/adapters/cuzk/adapter.d.ts.map +1 -0
  412. package/out/cz/adapters/cuzk/adapter.js +266 -0
  413. package/out/cz/adapters/cuzk/adapter.js.map +1 -0
  414. package/out/cz/recipes/pcfirst-preposition.d.ts +7 -11
  415. package/out/cz/recipes/pcfirst-preposition.d.ts.map +1 -1
  416. package/out/cz/recipes/pcfirst-preposition.js +36 -27
  417. package/out/cz/recipes/pcfirst-preposition.js.map +1 -1
  418. package/out/cz/tools/fetch/cuzk.d.ts +272 -0
  419. package/out/cz/tools/fetch/cuzk.d.ts.map +1 -0
  420. package/out/cz/tools/fetch/cuzk.js +446 -0
  421. package/out/cz/tools/fetch/cuzk.js.map +1 -0
  422. package/out/de/recipes/locale.d.ts +24 -26
  423. package/out/de/recipes/locale.d.ts.map +1 -1
  424. package/out/de/recipes/locale.js +66 -56
  425. package/out/de/recipes/locale.js.map +1 -1
  426. package/out/directory.d.ts +20 -0
  427. package/out/directory.d.ts.map +1 -0
  428. package/out/directory.js +27 -0
  429. package/out/directory.js.map +1 -0
  430. package/out/dk/adapters/inspire/adapter.d.ts +154 -0
  431. package/out/dk/adapters/inspire/adapter.d.ts.map +1 -0
  432. package/out/dk/adapters/inspire/adapter.js +258 -0
  433. package/out/dk/adapters/inspire/adapter.js.map +1 -0
  434. package/out/dk/tools/fetch/inspire.d.ts +100 -0
  435. package/out/dk/tools/fetch/inspire.d.ts.map +1 -0
  436. package/out/dk/tools/fetch/inspire.js +230 -0
  437. package/out/dk/tools/fetch/inspire.js.map +1 -0
  438. package/out/ee/adapters/ads/adapter.d.ts +109 -0
  439. package/out/ee/adapters/ads/adapter.d.ts.map +1 -0
  440. package/out/ee/adapters/ads/adapter.js +191 -0
  441. package/out/ee/adapters/ads/adapter.js.map +1 -0
  442. package/out/ee/tools/fetch/ads.d.ts +123 -0
  443. package/out/ee/tools/fetch/ads.d.ts.map +1 -0
  444. package/out/ee/tools/fetch/ads.js +195 -0
  445. package/out/ee/tools/fetch/ads.js.map +1 -0
  446. package/out/env.d.ts +6 -2
  447. package/out/env.d.ts.map +1 -1
  448. package/out/env.js +6 -2
  449. package/out/env.js.map +1 -1
  450. package/out/es/adapters/bizkaia/adapter.d.ts +143 -0
  451. package/out/es/adapters/bizkaia/adapter.d.ts.map +1 -0
  452. package/out/es/adapters/bizkaia/adapter.js +332 -0
  453. package/out/es/adapters/bizkaia/adapter.js.map +1 -0
  454. package/out/es/adapters/catastro/adapter.d.ts +104 -0
  455. package/out/es/adapters/catastro/adapter.d.ts.map +1 -0
  456. package/out/es/adapters/catastro/adapter.js +288 -0
  457. package/out/es/adapters/catastro/adapter.js.map +1 -0
  458. package/out/es/adapters/gipuzkoa/adapter.d.ts +91 -0
  459. package/out/es/adapters/gipuzkoa/adapter.d.ts.map +1 -0
  460. package/out/es/adapters/gipuzkoa/adapter.js +225 -0
  461. package/out/es/adapters/gipuzkoa/adapter.js.map +1 -0
  462. package/out/es/adapters/navarra/adapter.d.ts +105 -0
  463. package/out/es/adapters/navarra/adapter.d.ts.map +1 -0
  464. package/out/es/adapters/navarra/adapter.js +241 -0
  465. package/out/es/adapters/navarra/adapter.js.map +1 -0
  466. package/out/es/cadastre.d.ts +109 -0
  467. package/out/es/cadastre.d.ts.map +1 -0
  468. package/out/es/cadastre.js +130 -0
  469. package/out/es/cadastre.js.map +1 -0
  470. package/out/es/tools/fetch/bizkaia.d.ts +278 -0
  471. package/out/es/tools/fetch/bizkaia.d.ts.map +1 -0
  472. package/out/es/tools/fetch/bizkaia.js +477 -0
  473. package/out/es/tools/fetch/bizkaia.js.map +1 -0
  474. package/out/es/tools/fetch/catastro.d.ts +272 -0
  475. package/out/es/tools/fetch/catastro.d.ts.map +1 -0
  476. package/out/es/tools/fetch/catastro.js +486 -0
  477. package/out/es/tools/fetch/catastro.js.map +1 -0
  478. package/out/es/tools/fetch/gipuzkoa.d.ts +162 -0
  479. package/out/es/tools/fetch/gipuzkoa.d.ts.map +1 -0
  480. package/out/es/tools/fetch/gipuzkoa.js +209 -0
  481. package/out/es/tools/fetch/gipuzkoa.js.map +1 -0
  482. package/out/es/tools/fetch/navarra.d.ts +189 -0
  483. package/out/es/tools/fetch/navarra.d.ts.map +1 -0
  484. package/out/es/tools/fetch/navarra.js +316 -0
  485. package/out/es/tools/fetch/navarra.js.map +1 -0
  486. package/out/fi/adapters/ryhti/adapter.d.ts +115 -0
  487. package/out/fi/adapters/ryhti/adapter.d.ts.map +1 -0
  488. package/out/fi/adapters/ryhti/adapter.js +244 -0
  489. package/out/fi/adapters/ryhti/adapter.js.map +1 -0
  490. package/out/fi/tools/fetch/ryhti.d.ts +206 -0
  491. package/out/fi/tools/fetch/ryhti.d.ts.map +1 -0
  492. package/out/fi/tools/fetch/ryhti.js +327 -0
  493. package/out/fi/tools/fetch/ryhti.js.map +1 -0
  494. package/out/fingerprints.d.ts +68 -0
  495. package/out/fingerprints.d.ts.map +1 -0
  496. package/out/fingerprints.js +130 -0
  497. package/out/fingerprints.js.map +1 -0
  498. package/out/fr/adapters/annuaire-education/adapter.d.ts +236 -0
  499. package/out/fr/adapters/annuaire-education/adapter.d.ts.map +1 -0
  500. package/out/fr/adapters/annuaire-education/adapter.js +475 -0
  501. package/out/fr/adapters/annuaire-education/adapter.js.map +1 -0
  502. package/out/fr/adapters/ban/adapter.d.ts +19 -25
  503. package/out/fr/adapters/ban/adapter.d.ts.map +1 -1
  504. package/out/fr/adapters/ban/adapter.js +65 -54
  505. package/out/fr/adapters/ban/adapter.js.map +1 -1
  506. package/out/fr/adapters/finess/adapter.d.ts +276 -0
  507. package/out/fr/adapters/finess/adapter.d.ts.map +1 -0
  508. package/out/fr/adapters/finess/adapter.js +519 -0
  509. package/out/fr/adapters/finess/adapter.js.map +1 -0
  510. package/out/fr/adapters/finess/postal-lines.d.ts +61 -0
  511. package/out/fr/adapters/finess/postal-lines.d.ts.map +1 -0
  512. package/out/fr/adapters/finess/postal-lines.js +114 -0
  513. package/out/fr/adapters/finess/postal-lines.js.map +1 -0
  514. package/out/fr/adapters/finess/voie-type.d.ts +77 -0
  515. package/out/fr/adapters/finess/voie-type.d.ts.map +1 -0
  516. package/out/fr/adapters/finess/voie-type.js +172 -0
  517. package/out/fr/adapters/finess/voie-type.js.map +1 -0
  518. package/out/fr/insee-country.d.ts +45 -0
  519. package/out/fr/insee-country.d.ts.map +1 -0
  520. package/out/fr/insee-country.js +60 -0
  521. package/out/fr/insee-country.js.map +1 -0
  522. package/out/fr/recipes/admin-split.d.ts +4 -27
  523. package/out/fr/recipes/admin-split.d.ts.map +1 -1
  524. package/out/fr/recipes/admin-split.js +36 -58
  525. package/out/fr/recipes/admin-split.js.map +1 -1
  526. package/out/fr/recipes/bare-street.d.ts +2 -17
  527. package/out/fr/recipes/bare-street.d.ts.map +1 -1
  528. package/out/fr/recipes/bare-street.js +35 -50
  529. package/out/fr/recipes/bare-street.js.map +1 -1
  530. package/out/fr/recipes/fragment.d.ts +6 -65
  531. package/out/fr/recipes/fragment.d.ts.map +1 -1
  532. package/out/fr/recipes/fragment.js +55 -135
  533. package/out/fr/recipes/fragment.js.map +1 -1
  534. package/out/fr/recipes/lieudit.d.ts +17 -19
  535. package/out/fr/recipes/lieudit.d.ts.map +1 -1
  536. package/out/fr/recipes/lieudit.js +88 -68
  537. package/out/fr/recipes/lieudit.js.map +1 -1
  538. package/out/fr/recipes/order.d.ts +4 -27
  539. package/out/fr/recipes/order.d.ts.map +1 -1
  540. package/out/fr/recipes/order.js +31 -58
  541. package/out/fr/recipes/order.js.map +1 -1
  542. package/out/fr/{adapters/ban/street-decompose.d.ts → street-decompose.d.ts} +3 -2
  543. package/out/fr/street-decompose.d.ts.map +1 -0
  544. package/out/fr/{adapters/ban/street-decompose.js → street-decompose.js} +4 -3
  545. package/out/fr/street-decompose.js.map +1 -0
  546. package/out/fr/tools/fetch/annuaire-education.d.ts +130 -0
  547. package/out/fr/tools/fetch/annuaire-education.d.ts.map +1 -0
  548. package/out/fr/tools/fetch/annuaire-education.js +196 -0
  549. package/out/fr/tools/fetch/annuaire-education.js.map +1 -0
  550. package/out/fr/tools/fetch/ban.d.ts +9 -7
  551. package/out/fr/tools/fetch/ban.d.ts.map +1 -1
  552. package/out/fr/tools/fetch/ban.js +27 -18
  553. package/out/fr/tools/fetch/ban.js.map +1 -1
  554. package/out/fr/tools/fetch/finess.d.ts +145 -0
  555. package/out/fr/tools/fetch/finess.d.ts.map +1 -0
  556. package/out/fr/tools/fetch/finess.js +228 -0
  557. package/out/fr/tools/fetch/finess.js.map +1 -0
  558. package/out/gauntlet-inputs.d.ts +42 -0
  559. package/out/gauntlet-inputs.d.ts.map +1 -0
  560. package/out/gauntlet-inputs.js +78 -0
  561. package/out/gauntlet-inputs.js.map +1 -0
  562. package/out/index.d.ts +9 -3
  563. package/out/index.d.ts.map +1 -1
  564. package/out/index.js +9 -3
  565. package/out/index.js.map +1 -1
  566. package/out/inspire/address.d.ts +251 -0
  567. package/out/inspire/address.d.ts.map +1 -0
  568. package/out/inspire/address.js +384 -0
  569. package/out/inspire/address.js.map +1 -0
  570. package/out/inspire/archive.d.ts +36 -0
  571. package/out/inspire/archive.d.ts.map +1 -0
  572. package/out/inspire/archive.js +42 -0
  573. package/out/inspire/archive.js.map +1 -0
  574. package/out/inspire/errors.d.ts +55 -0
  575. package/out/inspire/errors.d.ts.map +1 -0
  576. package/out/inspire/errors.js +64 -0
  577. package/out/inspire/errors.js.map +1 -0
  578. package/out/inspire/stream.d.ts +137 -0
  579. package/out/inspire/stream.d.ts.map +1 -0
  580. package/out/inspire/stream.js +125 -0
  581. package/out/inspire/stream.js.map +1 -0
  582. package/out/international/recipes/locale.d.ts +38 -84
  583. package/out/international/recipes/locale.d.ts.map +1 -1
  584. package/out/international/recipes/locale.js +112 -151
  585. package/out/international/recipes/locale.js.map +1 -1
  586. package/out/it/adapters/anac/adapter.d.ts +267 -0
  587. package/out/it/adapters/anac/adapter.d.ts.map +1 -0
  588. package/out/it/adapters/anac/adapter.js +429 -0
  589. package/out/it/adapters/anac/adapter.js.map +1 -0
  590. package/out/it/tools/fetch/anac.d.ts +174 -0
  591. package/out/it/tools/fetch/anac.d.ts.map +1 -0
  592. package/out/it/tools/fetch/anac.js +272 -0
  593. package/out/it/tools/fetch/anac.js.map +1 -0
  594. package/out/jp/adapters/wof-admin/adapter.d.ts +14 -11
  595. package/out/jp/adapters/wof-admin/adapter.d.ts.map +1 -1
  596. package/out/jp/adapters/wof-admin/adapter.js +27 -16
  597. package/out/jp/adapters/wof-admin/adapter.js.map +1 -1
  598. package/out/jp/tools/fetch/houjin.d.ts +7 -4
  599. package/out/jp/tools/fetch/houjin.d.ts.map +1 -1
  600. package/out/jp/tools/fetch/houjin.js +15 -11
  601. package/out/jp/tools/fetch/houjin.js.map +1 -1
  602. package/out/kr/adapters/juso/label-rows.d.ts +17 -31
  603. package/out/kr/adapters/juso/label-rows.d.ts.map +1 -1
  604. package/out/kr/adapters/juso/label-rows.js +19 -41
  605. package/out/kr/adapters/juso/label-rows.js.map +1 -1
  606. package/out/kr/adapters/localdata/align.d.ts +4 -16
  607. package/out/kr/adapters/localdata/align.d.ts.map +1 -1
  608. package/out/kr/adapters/localdata/align.js +19 -30
  609. package/out/kr/adapters/localdata/align.js.map +1 -1
  610. package/out/kr/adapters/localdata/key-index.d.ts +13 -22
  611. package/out/kr/adapters/localdata/key-index.d.ts.map +1 -1
  612. package/out/kr/adapters/localdata/key-index.js +15 -21
  613. package/out/kr/adapters/localdata/key-index.js.map +1 -1
  614. package/out/kr/adapters/localdata/permit-rows.d.ts +21 -14
  615. package/out/kr/adapters/localdata/permit-rows.d.ts.map +1 -1
  616. package/out/kr/adapters/localdata/permit-rows.js +30 -25
  617. package/out/kr/adapters/localdata/permit-rows.js.map +1 -1
  618. package/out/kr/tools/fetch/juso.d.ts +11 -8
  619. package/out/kr/tools/fetch/juso.d.ts.map +1 -1
  620. package/out/kr/tools/fetch/juso.js +15 -14
  621. package/out/kr/tools/fetch/juso.js.map +1 -1
  622. package/out/kr/tools/fetch/localdata.d.ts +16 -9
  623. package/out/kr/tools/fetch/localdata.d.ts.map +1 -1
  624. package/out/kr/tools/fetch/localdata.js +23 -15
  625. package/out/kr/tools/fetch/localdata.js.map +1 -1
  626. package/out/lu/adapters/bd-adresses/adapter.d.ts +109 -0
  627. package/out/lu/adapters/bd-adresses/adapter.d.ts.map +1 -0
  628. package/out/lu/adapters/bd-adresses/adapter.js +196 -0
  629. package/out/lu/adapters/bd-adresses/adapter.js.map +1 -0
  630. package/out/lu/tools/fetch/bd-adresses.d.ts +163 -0
  631. package/out/lu/tools/fetch/bd-adresses.d.ts.map +1 -0
  632. package/out/lu/tools/fetch/bd-adresses.js +223 -0
  633. package/out/lu/tools/fetch/bd-adresses.js.map +1 -0
  634. package/out/lv/adapters/varis/adapter.d.ts +283 -0
  635. package/out/lv/adapters/varis/adapter.d.ts.map +1 -0
  636. package/out/lv/adapters/varis/adapter.js +404 -0
  637. package/out/lv/adapters/varis/adapter.js.map +1 -0
  638. package/out/lv/tools/fetch/varis.d.ts +80 -0
  639. package/out/lv/tools/fetch/varis.d.ts.map +1 -0
  640. package/out/lv/tools/fetch/varis.js +133 -0
  641. package/out/lv/tools/fetch/varis.js.map +1 -0
  642. package/out/nl/adapters/kadaster/adapter.d.ts +125 -0
  643. package/out/nl/adapters/kadaster/adapter.d.ts.map +1 -0
  644. package/out/nl/adapters/kadaster/adapter.js +310 -0
  645. package/out/nl/adapters/kadaster/adapter.js.map +1 -0
  646. package/out/nl/recipes/postcode.d.ts +12 -14
  647. package/out/nl/recipes/postcode.d.ts.map +1 -1
  648. package/out/nl/recipes/postcode.js +42 -24
  649. package/out/nl/recipes/postcode.js.map +1 -1
  650. package/out/nl/tools/fetch/kadaster.d.ts +155 -0
  651. package/out/nl/tools/fetch/kadaster.d.ts.map +1 -0
  652. package/out/nl/tools/fetch/kadaster.js +179 -0
  653. package/out/nl/tools/fetch/kadaster.js.map +1 -0
  654. package/out/no/adapters/matrikkelen/adapter.d.ts +44 -0
  655. package/out/no/adapters/matrikkelen/adapter.d.ts.map +1 -0
  656. package/out/no/adapters/matrikkelen/adapter.js +143 -0
  657. package/out/no/adapters/matrikkelen/adapter.js.map +1 -0
  658. package/out/no/recipes/fragment.d.ts +1 -33
  659. package/out/no/recipes/fragment.d.ts.map +1 -1
  660. package/out/no/recipes/fragment.js +23 -57
  661. package/out/no/recipes/fragment.js.map +1 -1
  662. package/out/no/recipes/street/led.d.ts +9 -12
  663. package/out/no/recipes/street/led.d.ts.map +1 -1
  664. package/out/no/recipes/street/led.js +34 -24
  665. package/out/no/recipes/street/led.js.map +1 -1
  666. package/out/no/recipes/street.d.ts +19 -0
  667. package/out/no/recipes/street.d.ts.map +1 -0
  668. package/out/no/recipes/{street/index.js → street.js} +28 -12
  669. package/out/no/recipes/street.js.map +1 -0
  670. package/out/no/tools/fetch/matrikkelen.d.ts +251 -0
  671. package/out/no/tools/fetch/matrikkelen.d.ts.map +1 -0
  672. package/out/no/tools/fetch/matrikkelen.js +345 -0
  673. package/out/no/tools/fetch/matrikkelen.js.map +1 -0
  674. package/out/parquet/duckdb.d.ts +100 -0
  675. package/out/parquet/duckdb.d.ts.map +1 -0
  676. package/out/parquet/duckdb.js +92 -0
  677. package/out/parquet/duckdb.js.map +1 -0
  678. package/out/parquet/readers.d.ts +44 -0
  679. package/out/parquet/readers.d.ts.map +1 -0
  680. package/out/parquet/readers.js +69 -0
  681. package/out/parquet/readers.js.map +1 -0
  682. package/out/parquet/schema.d.ts +95 -0
  683. package/out/parquet/schema.d.ts.map +1 -0
  684. package/out/parquet/schema.js +157 -0
  685. package/out/parquet/schema.js.map +1 -0
  686. package/out/parquet/shuffle.d.ts +25 -0
  687. package/out/parquet/shuffle.d.ts.map +1 -0
  688. package/out/parquet/shuffle.js +44 -0
  689. package/out/parquet/shuffle.js.map +1 -0
  690. package/out/parquet/span-sql.d.ts +49 -0
  691. package/out/parquet/span-sql.d.ts.map +1 -0
  692. package/out/parquet/span-sql.js +53 -0
  693. package/out/parquet/span-sql.js.map +1 -0
  694. package/out/parquet/streams.d.ts +47 -0
  695. package/out/parquet/streams.d.ts.map +1 -0
  696. package/out/parquet/streams.js +78 -0
  697. package/out/parquet/streams.js.map +1 -0
  698. package/out/parquet/writers.d.ts +124 -0
  699. package/out/parquet/writers.d.ts.map +1 -0
  700. package/out/parquet/writers.js +251 -0
  701. package/out/parquet/writers.js.map +1 -0
  702. package/out/pl/adapters/emuia/adapter.d.ts +81 -0
  703. package/out/pl/adapters/emuia/adapter.d.ts.map +1 -0
  704. package/out/pl/adapters/emuia/adapter.js +178 -0
  705. package/out/pl/adapters/emuia/adapter.js.map +1 -0
  706. package/out/pl/tools/fetch/emuia.d.ts +165 -0
  707. package/out/pl/tools/fetch/emuia.d.ts.map +1 -0
  708. package/out/pl/tools/fetch/emuia.js +260 -0
  709. package/out/pl/tools/fetch/emuia.js.map +1 -0
  710. package/out/recipes/anchor-absorption.d.ts +9 -9
  711. package/out/recipes/anchor-absorption.d.ts.map +1 -1
  712. package/out/recipes/anchor-absorption.js +29 -19
  713. package/out/recipes/anchor-absorption.js.map +1 -1
  714. package/out/recipes/bare/country.d.ts +2 -20
  715. package/out/recipes/bare/country.d.ts.map +1 -1
  716. package/out/recipes/bare/country.js +20 -31
  717. package/out/recipes/bare/country.js.map +1 -1
  718. package/out/recipes/bare/postcode/eval.d.ts +1 -1
  719. package/out/recipes/bare/postcode/eval.js +1 -1
  720. package/out/recipes/bare/postcode.d.ts +41 -0
  721. package/out/recipes/bare/postcode.d.ts.map +1 -0
  722. package/out/recipes/bare/{postcode/index.js → postcode.js} +91 -79
  723. package/out/recipes/bare/postcode.js.map +1 -0
  724. package/out/recipes/boundary-stress.d.ts +8 -8
  725. package/out/recipes/boundary-stress.d.ts.map +1 -1
  726. package/out/recipes/boundary-stress.js +36 -19
  727. package/out/recipes/boundary-stress.js.map +1 -1
  728. package/out/recipes/country-balanced.d.ts +3 -21
  729. package/out/recipes/country-balanced.d.ts.map +1 -1
  730. package/out/recipes/country-balanced.js +58 -76
  731. package/out/recipes/country-balanced.js.map +1 -1
  732. package/out/recipes/house-venue.d.ts +8 -6
  733. package/out/recipes/house-venue.d.ts.map +1 -1
  734. package/out/recipes/house-venue.js +29 -13
  735. package/out/recipes/house-venue.js.map +1 -1
  736. package/out/recipes/intersection.d.ts +20 -20
  737. package/out/recipes/intersection.d.ts.map +1 -1
  738. package/out/recipes/intersection.js +65 -53
  739. package/out/recipes/intersection.js.map +1 -1
  740. package/out/recipes/po/box/cedex/au-nz.d.ts.map +1 -1
  741. package/out/recipes/po/box/cedex/au-nz.js +3 -3
  742. package/out/recipes/po/box/cedex/au-nz.js.map +1 -1
  743. package/out/recipes/po/box/cedex/ca.d.ts.map +1 -1
  744. package/out/recipes/po/box/cedex/ca.js +2 -2
  745. package/out/recipes/po/box/cedex/ca.js.map +1 -1
  746. package/out/recipes/po/box/cedex/fr.d.ts.map +1 -1
  747. package/out/recipes/po/box/cedex/fr.js +3 -3
  748. package/out/recipes/po/box/cedex/fr.js.map +1 -1
  749. package/out/recipes/po/box/cedex/phrases.d.ts.map +1 -1
  750. package/out/recipes/po/box/cedex/phrases.js +7 -6
  751. package/out/recipes/po/box/cedex/phrases.js.map +1 -1
  752. package/out/recipes/po/box/cedex/recipe.d.ts +1 -1
  753. package/out/recipes/po/box/cedex/recipe.d.ts.map +1 -1
  754. package/out/recipes/po/box/cedex/recipe.js +25 -15
  755. package/out/recipes/po/box/cedex/recipe.js.map +1 -1
  756. package/out/recipes/po/box/cedex/sources.d.ts +12 -12
  757. package/out/recipes/po/box/cedex/sources.d.ts.map +1 -1
  758. package/out/recipes/po/box/cedex/sources.js +1 -1
  759. package/out/recipes/po/box/cedex/sources.js.map +1 -1
  760. package/out/recipes/po/box/cedex/us.d.ts.map +1 -1
  761. package/out/recipes/po/box/cedex/us.js +5 -2
  762. package/out/recipes/po/box/cedex/us.js.map +1 -1
  763. package/out/recipes/po/box.d.ts +18 -0
  764. package/out/recipes/po/box.d.ts.map +1 -0
  765. package/out/recipes/po/{box/index.js → box.js} +37 -19
  766. package/out/recipes/po/box.js.map +1 -0
  767. package/out/recipes/scaffold.d.ts +211 -138
  768. package/out/recipes/scaffold.d.ts.map +1 -1
  769. package/out/recipes/scaffold.js +72 -63
  770. package/out/recipes/scaffold.js.map +1 -1
  771. package/out/recipes/sources.d.ts +178 -0
  772. package/out/recipes/sources.d.ts.map +1 -0
  773. package/out/recipes/sources.js +348 -0
  774. package/out/recipes/sources.js.map +1 -0
  775. package/out/recipes/street/affix.d.ts +20 -50
  776. package/out/recipes/street/affix.d.ts.map +1 -1
  777. package/out/recipes/street/affix.js +45 -133
  778. package/out/recipes/street/affix.js.map +1 -1
  779. package/out/recipes/street/bare.d.ts +9 -7
  780. package/out/recipes/street/bare.d.ts.map +1 -1
  781. package/out/recipes/street/bare.js +25 -14
  782. package/out/recipes/street/bare.js.map +1 -1
  783. package/out/recipes/street.d.ts +6 -4
  784. package/out/recipes/street.d.ts.map +1 -1
  785. package/out/recipes/street.js +29 -8
  786. package/out/recipes/street.js.map +1 -1
  787. package/out/recipes/sub/venue/context.d.ts +12 -9
  788. package/out/recipes/sub/venue/context.d.ts.map +1 -1
  789. package/out/recipes/sub/venue/context.js +21 -17
  790. package/out/recipes/sub/venue/context.js.map +1 -1
  791. package/out/recipes/sub/venue/render.d.ts +58 -0
  792. package/out/recipes/sub/venue/render.d.ts.map +1 -0
  793. package/out/recipes/sub/venue/render.js +118 -0
  794. package/out/recipes/sub/venue/render.js.map +1 -0
  795. package/out/recipes/sub/venue/sources.d.ts +49 -92
  796. package/out/recipes/sub/venue/sources.d.ts.map +1 -1
  797. package/out/recipes/sub/venue/sources.js +43 -179
  798. package/out/recipes/sub/venue/sources.js.map +1 -1
  799. package/out/recipes/sub/venue.d.ts +176 -0
  800. package/out/recipes/sub/venue.d.ts.map +1 -0
  801. package/out/recipes/sub/venue.js +562 -0
  802. package/out/recipes/sub/venue.js.map +1 -0
  803. package/out/recipes/trailing-region.d.ts +9 -61
  804. package/out/recipes/trailing-region.d.ts.map +1 -1
  805. package/out/recipes/trailing-region.js +55 -85
  806. package/out/recipes/trailing-region.js.map +1 -1
  807. package/out/recipes/unit/sources.d.ts +28 -0
  808. package/out/recipes/unit/sources.d.ts.map +1 -0
  809. package/out/recipes/unit/sources.js +30 -0
  810. package/out/recipes/unit/sources.js.map +1 -0
  811. package/out/recipes/unit.d.ts +30 -17
  812. package/out/recipes/unit.d.ts.map +1 -1
  813. package/out/recipes/unit.js +90 -79
  814. package/out/recipes/unit.js.map +1 -1
  815. package/out/recipes.d.ts +26 -0
  816. package/out/recipes.d.ts.map +1 -0
  817. package/out/{recipes/index.js → recipes.js} +14 -12
  818. package/out/recipes.js.map +1 -0
  819. package/out/registers.d.ts +277 -0
  820. package/out/registers.d.ts.map +1 -0
  821. package/out/registers.js +273 -0
  822. package/out/registers.js.map +1 -0
  823. package/out/ro/adapters/retea-scolara/adapter.d.ts +114 -0
  824. package/out/ro/adapters/retea-scolara/adapter.d.ts.map +1 -0
  825. package/out/ro/adapters/retea-scolara/adapter.js +209 -0
  826. package/out/ro/adapters/retea-scolara/adapter.js.map +1 -0
  827. package/out/ro/tools/fetch/retea-scolara.d.ts +69 -0
  828. package/out/ro/tools/fetch/retea-scolara.d.ts.map +1 -0
  829. package/out/ro/tools/fetch/retea-scolara.js +117 -0
  830. package/out/ro/tools/fetch/retea-scolara.js.map +1 -0
  831. package/out/runner.d.ts +120 -60
  832. package/out/runner.d.ts.map +1 -1
  833. package/out/runner.js +130 -56
  834. package/out/runner.js.map +1 -1
  835. package/out/sg/recipes/register.d.ts +18 -32
  836. package/out/sg/recipes/register.d.ts.map +1 -1
  837. package/out/sg/recipes/register.js +44 -49
  838. package/out/sg/recipes/register.js.map +1 -1
  839. package/out/sg/tools/fetch/acra.d.ts +11 -14
  840. package/out/sg/tools/fetch/acra.d.ts.map +1 -1
  841. package/out/sg/tools/fetch/acra.js +16 -19
  842. package/out/sg/tools/fetch/acra.js.map +1 -1
  843. package/out/si/recipes/bare-village.d.ts +12 -13
  844. package/out/si/recipes/bare-village.d.ts.map +1 -1
  845. package/out/si/recipes/bare-village.js +31 -17
  846. package/out/si/recipes/bare-village.js.map +1 -1
  847. package/out/sk/adapters/inspire/adapter.d.ts +119 -0
  848. package/out/sk/adapters/inspire/adapter.d.ts.map +1 -0
  849. package/out/sk/adapters/inspire/adapter.js +318 -0
  850. package/out/sk/adapters/inspire/adapter.js.map +1 -0
  851. package/out/sk/tools/fetch/inspire.d.ts +195 -0
  852. package/out/sk/tools/fetch/inspire.d.ts.map +1 -0
  853. package/out/sk/tools/fetch/inspire.js +280 -0
  854. package/out/sk/tools/fetch/inspire.js.map +1 -0
  855. package/out/source-register/effective-manifest.d.ts +355 -0
  856. package/out/source-register/effective-manifest.d.ts.map +1 -0
  857. package/out/source-register/effective-manifest.js +355 -0
  858. package/out/source-register/effective-manifest.js.map +1 -0
  859. package/out/source-register/register.d.ts +79 -0
  860. package/out/source-register/register.d.ts.map +1 -0
  861. package/out/source-register/register.js +400 -0
  862. package/out/source-register/register.js.map +1 -0
  863. package/out/source-register/training-manifest.d.ts +111 -0
  864. package/out/source-register/training-manifest.d.ts.map +1 -0
  865. package/out/source-register/training-manifest.js +120 -0
  866. package/out/source-register/training-manifest.js.map +1 -0
  867. package/out/source-register/types.d.ts +539 -0
  868. package/out/source-register/types.d.ts.map +1 -0
  869. package/out/source-register/types.js +263 -0
  870. package/out/source-register/types.js.map +1 -0
  871. package/out/source-register.d.ts +19 -0
  872. package/out/source-register.d.ts.map +1 -0
  873. package/out/source-register.js +16 -0
  874. package/out/source-register.js.map +1 -0
  875. package/out/south-asia/recipes/register.d.ts +20 -17
  876. package/out/south-asia/recipes/register.d.ts.map +1 -1
  877. package/out/south-asia/recipes/register.js +44 -24
  878. package/out/south-asia/recipes/register.js.map +1 -1
  879. package/out/subvenue/harvest.d.ts +117 -0
  880. package/out/subvenue/harvest.d.ts.map +1 -0
  881. package/out/subvenue/harvest.js +172 -0
  882. package/out/subvenue/harvest.js.map +1 -0
  883. package/out/subvenue/promotions.d.ts +65 -0
  884. package/out/subvenue/promotions.d.ts.map +1 -0
  885. package/out/{tools/sub/venue → subvenue}/promotions.js +15 -55
  886. package/out/subvenue/promotions.js.map +1 -0
  887. package/out/subvenue/surfaces.d.ts +39 -0
  888. package/out/subvenue/surfaces.d.ts.map +1 -0
  889. package/out/subvenue/surfaces.js +75 -0
  890. package/out/subvenue/surfaces.js.map +1 -0
  891. package/out/subvenue/table.d.ts +212 -0
  892. package/out/subvenue/table.d.ts.map +1 -0
  893. package/out/subvenue/table.js +94 -0
  894. package/out/subvenue/table.js.map +1 -0
  895. package/out/surfaces/locale.d.ts +113 -0
  896. package/out/surfaces/locale.d.ts.map +1 -0
  897. package/out/surfaces/locale.js +136 -0
  898. package/out/surfaces/locale.js.map +1 -0
  899. package/out/synthesizers/anchor-absorption.d.ts +21 -30
  900. package/out/synthesizers/anchor-absorption.d.ts.map +1 -1
  901. package/out/synthesizers/anchor-absorption.js +30 -85
  902. package/out/synthesizers/anchor-absorption.js.map +1 -1
  903. package/out/synthesizers/boundary-stress.d.ts +17 -48
  904. package/out/synthesizers/boundary-stress.d.ts.map +1 -1
  905. package/out/synthesizers/boundary-stress.js +27 -121
  906. package/out/synthesizers/boundary-stress.js.map +1 -1
  907. package/out/synthesizers/house-venue.d.ts +22 -25
  908. package/out/synthesizers/house-venue.d.ts.map +1 -1
  909. package/out/synthesizers/house-venue.js +28 -97
  910. package/out/synthesizers/house-venue.js.map +1 -1
  911. package/out/synthesizers/intersection.d.ts +10 -8
  912. package/out/synthesizers/intersection.d.ts.map +1 -1
  913. package/out/synthesizers/intersection.js +33 -26
  914. package/out/synthesizers/intersection.js.map +1 -1
  915. package/out/synthesizers/no-street.d.ts +7 -37
  916. package/out/synthesizers/no-street.d.ts.map +1 -1
  917. package/out/synthesizers/no-street.js +55 -111
  918. package/out/synthesizers/no-street.js.map +1 -1
  919. package/out/synthesizers/po-box.d.ts +46 -45
  920. package/out/synthesizers/po-box.d.ts.map +1 -1
  921. package/out/synthesizers/po-box.js +57 -97
  922. package/out/synthesizers/po-box.js.map +1 -1
  923. package/out/synthesizers/street.d.ts +18 -12
  924. package/out/synthesizers/street.d.ts.map +1 -1
  925. package/out/synthesizers/street.js +36 -29
  926. package/out/synthesizers/street.js.map +1 -1
  927. package/out/synthesizers/utils.d.ts +32 -129
  928. package/out/synthesizers/utils.d.ts.map +1 -1
  929. package/out/synthesizers/utils.js +54 -166
  930. package/out/synthesizers/utils.js.map +1 -1
  931. package/out/test-kit/corpus-recipe.d.ts +29 -23
  932. package/out/test-kit/corpus-recipe.d.ts.map +1 -1
  933. package/out/test-kit/corpus-recipe.js +28 -13
  934. package/out/test-kit/corpus-recipe.js.map +1 -1
  935. package/out/test-kit.d.ts +63 -0
  936. package/out/test-kit.d.ts.map +1 -0
  937. package/out/test-kit.js +88 -0
  938. package/out/test-kit.js.map +1 -0
  939. package/out/tools/align-canonical.d.ts +7 -0
  940. package/out/tools/align-canonical.d.ts.map +1 -0
  941. package/out/tools/align-canonical.js +52 -0
  942. package/out/tools/align-canonical.js.map +1 -0
  943. package/out/tools/audit.d.ts +18 -11
  944. package/out/tools/audit.d.ts.map +1 -1
  945. package/out/tools/audit.js +86 -95
  946. package/out/tools/audit.js.map +1 -1
  947. package/out/tools/corpus-stats.d.ts +24 -15
  948. package/out/tools/corpus-stats.d.ts.map +1 -1
  949. package/out/tools/corpus-stats.js +33 -29
  950. package/out/tools/corpus-stats.js.map +1 -1
  951. package/out/tools/fetch/atom.d.ts +115 -0
  952. package/out/tools/fetch/atom.d.ts.map +1 -0
  953. package/out/tools/fetch/atom.js +84 -0
  954. package/out/tools/fetch/atom.js.map +1 -0
  955. package/out/tools/fetch/cordis.d.ts +123 -0
  956. package/out/tools/fetch/cordis.d.ts.map +1 -0
  957. package/out/tools/fetch/cordis.js +208 -0
  958. package/out/tools/fetch/cordis.js.map +1 -0
  959. package/out/tools/fetch/download/manifest.d.ts +27 -18
  960. package/out/tools/fetch/download/manifest.d.ts.map +1 -1
  961. package/out/tools/fetch/download/manifest.js +20 -13
  962. package/out/tools/fetch/download/manifest.js.map +1 -1
  963. package/out/tools/fetch/download/network.d.ts +48 -27
  964. package/out/tools/fetch/download/network.d.ts.map +1 -1
  965. package/out/tools/fetch/download/network.js +26 -16
  966. package/out/tools/fetch/download/network.js.map +1 -1
  967. package/out/tools/fetch/download/retry.d.ts +16 -15
  968. package/out/tools/fetch/download/retry.d.ts.map +1 -1
  969. package/out/tools/fetch/download/retry.js +24 -24
  970. package/out/tools/fetch/download/retry.js.map +1 -1
  971. package/out/tools/fetch/{download/index.d.ts → download.d.ts} +1 -1
  972. package/out/tools/fetch/download.d.ts.map +1 -0
  973. package/out/tools/fetch/{download/index.js → download.js} +1 -1
  974. package/out/tools/fetch/download.js.map +1 -0
  975. package/out/tools/fetch/geonames/dump.d.ts +50 -32
  976. package/out/tools/fetch/geonames/dump.d.ts.map +1 -1
  977. package/out/tools/fetch/geonames/dump.js +52 -42
  978. package/out/tools/fetch/geonames/dump.js.map +1 -1
  979. package/out/tools/fetch/geonames/postal.d.ts +14 -49
  980. package/out/tools/fetch/geonames/postal.d.ts.map +1 -1
  981. package/out/tools/fetch/geonames/postal.js +17 -56
  982. package/out/tools/fetch/geonames/postal.js.map +1 -1
  983. package/out/tools/fetch/gleif.d.ts +137 -0
  984. package/out/tools/fetch/gleif.d.ts.map +1 -0
  985. package/out/tools/fetch/gleif.js +220 -0
  986. package/out/tools/fetch/gleif.js.map +1 -0
  987. package/out/tools/fetch/header.d.ts +41 -0
  988. package/out/tools/fetch/header.d.ts.map +1 -0
  989. package/out/tools/fetch/header.js +59 -0
  990. package/out/tools/fetch/header.js.map +1 -0
  991. package/out/tools/fetch/inspire-addresses.d.ts +249 -0
  992. package/out/tools/fetch/inspire-addresses.d.ts.map +1 -0
  993. package/out/tools/fetch/inspire-addresses.js +276 -0
  994. package/out/tools/fetch/inspire-addresses.js.map +1 -0
  995. package/out/tools/fetch/openaddresses.d.ts +1 -4
  996. package/out/tools/fetch/openaddresses.d.ts.map +1 -1
  997. package/out/tools/fetch/openaddresses.js +19 -98
  998. package/out/tools/fetch/openaddresses.js.map +1 -1
  999. package/out/tools/fetch/ourairports.d.ts +6 -33
  1000. package/out/tools/fetch/ourairports.d.ts.map +1 -1
  1001. package/out/tools/fetch/ourairports.js +14 -47
  1002. package/out/tools/fetch/ourairports.js.map +1 -1
  1003. package/out/tools/fetch/ppd.d.ts +4 -3
  1004. package/out/tools/fetch/ppd.d.ts.map +1 -1
  1005. package/out/tools/fetch/ppd.js +10 -7
  1006. package/out/tools/fetch/ppd.js.map +1 -1
  1007. package/out/tools/fetch/vlaanderen-ad.d.ts +131 -0
  1008. package/out/tools/fetch/vlaanderen-ad.d.ts.map +1 -0
  1009. package/out/tools/fetch/vlaanderen-ad.js +293 -0
  1010. package/out/tools/fetch/vlaanderen-ad.js.map +1 -0
  1011. package/out/tools/fetch/wfs-harvest.d.ts +410 -0
  1012. package/out/tools/fetch/wfs-harvest.d.ts.map +1 -0
  1013. package/out/tools/fetch/wfs-harvest.js +522 -0
  1014. package/out/tools/fetch/wfs-harvest.js.map +1 -0
  1015. package/out/tools/fetch/wikidata-subvenue.d.ts +32 -100
  1016. package/out/tools/fetch/wikidata-subvenue.d.ts.map +1 -1
  1017. package/out/tools/fetch/wikidata-subvenue.js +27 -122
  1018. package/out/tools/fetch/wikidata-subvenue.js.map +1 -1
  1019. package/out/tools/fetch/zip-archive.d.ts +54 -0
  1020. package/out/tools/fetch/zip-archive.d.ts.map +1 -0
  1021. package/out/tools/fetch/zip-archive.js +58 -0
  1022. package/out/tools/fetch/zip-archive.js.map +1 -0
  1023. package/out/tools/fetch.d.ts +140 -0
  1024. package/out/tools/fetch.d.ts.map +1 -0
  1025. package/out/tools/fetch.js +136 -0
  1026. package/out/tools/fetch.js.map +1 -0
  1027. package/out/tools/golden/expand.d.ts +28 -13
  1028. package/out/tools/golden/expand.d.ts.map +1 -1
  1029. package/out/tools/golden/expand.js +50 -36
  1030. package/out/tools/golden/expand.js.map +1 -1
  1031. package/out/tools/golden/promote.d.ts +13 -8
  1032. package/out/tools/golden/promote.d.ts.map +1 -1
  1033. package/out/tools/golden/promote.js +33 -28
  1034. package/out/tools/golden/promote.js.map +1 -1
  1035. package/out/tools/golden/relabel-street/directory.d.ts +24 -9
  1036. package/out/tools/golden/relabel-street/directory.d.ts.map +1 -1
  1037. package/out/tools/golden/relabel-street/directory.js +41 -30
  1038. package/out/tools/golden/relabel-street/directory.js.map +1 -1
  1039. package/out/tools/golden/relabel-street/row.d.ts +17 -69
  1040. package/out/tools/golden/relabel-street/row.d.ts.map +1 -1
  1041. package/out/tools/golden/relabel-street/row.js +16 -74
  1042. package/out/tools/golden/relabel-street/row.js.map +1 -1
  1043. package/out/tools/golden/{relabel-street/index.d.ts → relabel-street.d.ts} +1 -1
  1044. package/out/tools/golden/relabel-street.d.ts.map +1 -0
  1045. package/out/tools/golden/{relabel-street/index.js → relabel-street.js} +1 -1
  1046. package/out/tools/golden/relabel-street.js.map +1 -0
  1047. package/out/tools/ingest-csv.d.ts +19 -15
  1048. package/out/tools/ingest-csv.d.ts.map +1 -1
  1049. package/out/tools/ingest-csv.js +39 -43
  1050. package/out/tools/ingest-csv.js.map +1 -1
  1051. package/out/tools/jsonl-to-parquet.d.ts +15 -28
  1052. package/out/tools/jsonl-to-parquet.d.ts.map +1 -1
  1053. package/out/tools/jsonl-to-parquet.js +49 -91
  1054. package/out/tools/jsonl-to-parquet.js.map +1 -1
  1055. package/out/tools/lint/recipe-output/vocab.d.ts +77 -0
  1056. package/out/tools/lint/recipe-output/vocab.d.ts.map +1 -0
  1057. package/out/tools/lint/{slice → recipe-output}/vocab.js +54 -69
  1058. package/out/tools/lint/recipe-output/vocab.js.map +1 -0
  1059. package/out/tools/lint/recipe-output.d.ts +73 -0
  1060. package/out/tools/lint/recipe-output.d.ts.map +1 -0
  1061. package/out/tools/lint/{slice/index.js → recipe-output.js} +76 -96
  1062. package/out/tools/lint/recipe-output.js.map +1 -0
  1063. package/out/tools/migrate/overlay-parquet.d.ts +30 -0
  1064. package/out/tools/migrate/overlay-parquet.d.ts.map +1 -0
  1065. package/out/tools/migrate/overlay-parquet.js +141 -0
  1066. package/out/tools/migrate/overlay-parquet.js.map +1 -0
  1067. package/out/tools/migrate/recipe-output.d.ts +35 -0
  1068. package/out/tools/migrate/recipe-output.d.ts.map +1 -0
  1069. package/out/tools/migrate/recipe-output.js +124 -0
  1070. package/out/tools/migrate/recipe-output.js.map +1 -0
  1071. package/out/tools/migrate/source-names.d.ts +52 -0
  1072. package/out/tools/migrate/source-names.d.ts.map +1 -0
  1073. package/out/tools/migrate/source-names.js +105 -0
  1074. package/out/tools/migrate/source-names.js.map +1 -0
  1075. package/out/tools/overlay/kryptonite.d.ts +33 -0
  1076. package/out/tools/overlay/kryptonite.d.ts.map +1 -0
  1077. package/out/tools/{slice → overlay}/kryptonite.js +37 -28
  1078. package/out/tools/overlay/kryptonite.js.map +1 -0
  1079. package/out/tools/overlay/manifest.d.ts +142 -0
  1080. package/out/tools/overlay/manifest.d.ts.map +1 -0
  1081. package/out/tools/overlay/manifest.js +260 -0
  1082. package/out/tools/overlay/manifest.js.map +1 -0
  1083. package/out/tools/overlay/merge-source.d.ts +73 -0
  1084. package/out/tools/overlay/merge-source.d.ts.map +1 -0
  1085. package/out/tools/overlay/merge-source.js +63 -0
  1086. package/out/tools/overlay/merge-source.js.map +1 -0
  1087. package/out/tools/overlay/split-slice.d.ts +66 -0
  1088. package/out/tools/overlay/split-slice.d.ts.map +1 -0
  1089. package/out/tools/overlay/split-slice.js +78 -0
  1090. package/out/tools/overlay/split-slice.js.map +1 -0
  1091. package/out/tools/overlay/translit.d.ts +54 -0
  1092. package/out/tools/overlay/translit.d.ts.map +1 -0
  1093. package/out/tools/{slice → overlay}/translit.js +59 -48
  1094. package/out/tools/overlay/translit.js.map +1 -0
  1095. package/out/tools/overture-subvenue.d.ts +16 -75
  1096. package/out/tools/overture-subvenue.d.ts.map +1 -1
  1097. package/out/tools/overture-subvenue.js +7 -74
  1098. package/out/tools/overture-subvenue.js.map +1 -1
  1099. package/out/tools/postcode-triples.d.ts +77 -126
  1100. package/out/tools/postcode-triples.d.ts.map +1 -1
  1101. package/out/tools/postcode-triples.js +198 -192
  1102. package/out/tools/postcode-triples.js.map +1 -1
  1103. package/out/tools/source-register/build.d.ts +145 -0
  1104. package/out/tools/source-register/build.d.ts.map +1 -0
  1105. package/out/tools/source-register/build.js +515 -0
  1106. package/out/tools/source-register/build.js.map +1 -0
  1107. package/out/tools/sub/venue/head-nouns.d.ts +9 -38
  1108. package/out/tools/sub/venue/head-nouns.d.ts.map +1 -1
  1109. package/out/tools/sub/venue/head-nouns.js +37 -74
  1110. package/out/tools/sub/venue/head-nouns.js.map +1 -1
  1111. package/out/tools/sub/venue/lexicon.d.ts +55 -82
  1112. package/out/tools/sub/venue/lexicon.d.ts.map +1 -1
  1113. package/out/tools/sub/venue/lexicon.js +43 -87
  1114. package/out/tools/sub/venue/lexicon.js.map +1 -1
  1115. package/out/tools/sub/venue/wikidata.d.ts +8 -6
  1116. package/out/tools/sub/venue/wikidata.d.ts.map +1 -1
  1117. package/out/tools/sub/venue/wikidata.js +12 -9
  1118. package/out/tools/sub/venue/wikidata.js.map +1 -1
  1119. package/out/tools.d.ts +31 -0
  1120. package/out/tools.d.ts.map +1 -0
  1121. package/out/tools.js +31 -0
  1122. package/out/tools.js.map +1 -0
  1123. package/out/tw/tools/fetch/gcis.d.ts +9 -3
  1124. package/out/tw/tools/fetch/gcis.d.ts.map +1 -1
  1125. package/out/tw/tools/fetch/gcis.js +16 -10
  1126. package/out/tw/tools/fetch/gcis.js.map +1 -1
  1127. package/out/types.d.ts +270 -101
  1128. package/out/types.d.ts.map +1 -1
  1129. package/out/types.js +133 -9
  1130. package/out/types.js.map +1 -1
  1131. package/out/us/adapters/fcc-bdc/adapter.d.ts +18 -36
  1132. package/out/us/adapters/fcc-bdc/adapter.d.ts.map +1 -1
  1133. package/out/us/adapters/fcc-bdc/adapter.js +25 -38
  1134. package/out/us/adapters/fcc-bdc/adapter.js.map +1 -1
  1135. package/out/us/adapters/state/hi-schools/adapter.d.ts +12 -11
  1136. package/out/us/adapters/state/hi-schools/adapter.d.ts.map +1 -1
  1137. package/out/us/adapters/state/hi-schools/adapter.js +26 -16
  1138. package/out/us/adapters/state/hi-schools/adapter.js.map +1 -1
  1139. package/out/us/adapters/state/hi-schools/workbook.d.ts +7 -2
  1140. package/out/us/adapters/state/hi-schools/workbook.d.ts.map +1 -1
  1141. package/out/us/adapters/state/hi-schools/workbook.js +3 -1
  1142. package/out/us/adapters/state/hi-schools/workbook.js.map +1 -1
  1143. package/out/us/adapters/state/ia-contractors/adapter.d.ts +13 -6
  1144. package/out/us/adapters/state/ia-contractors/adapter.d.ts.map +1 -1
  1145. package/out/us/adapters/state/ia-contractors/adapter.js +27 -14
  1146. package/out/us/adapters/state/ia-contractors/adapter.js.map +1 -1
  1147. package/out/us/adapters/state/ny-notaries/adapter.d.ts +7 -6
  1148. package/out/us/adapters/state/ny-notaries/adapter.d.ts.map +1 -1
  1149. package/out/us/adapters/state/ny-notaries/adapter.js +24 -22
  1150. package/out/us/adapters/state/ny-notaries/adapter.js.map +1 -1
  1151. package/out/us/adapters/state/tx-notaries/adapter.d.ts +8 -7
  1152. package/out/us/adapters/state/tx-notaries/adapter.d.ts.map +1 -1
  1153. package/out/us/adapters/state/tx-notaries/adapter.js +21 -14
  1154. package/out/us/adapters/state/tx-notaries/adapter.js.map +1 -1
  1155. package/out/us/adapters/tiger/adapter.d.ts +10 -34
  1156. package/out/us/adapters/tiger/adapter.d.ts.map +1 -1
  1157. package/out/us/adapters/tiger/adapter.js +18 -42
  1158. package/out/us/adapters/tiger/adapter.js.map +1 -1
  1159. package/out/us/adapters/tiger/street-decompose.d.ts +6 -13
  1160. package/out/us/adapters/tiger/street-decompose.d.ts.map +1 -1
  1161. package/out/us/adapters/tiger/street-decompose.js +7 -17
  1162. package/out/us/adapters/tiger/street-decompose.js.map +1 -1
  1163. package/out/us/adapters/usgov/hrsa-fqhc/adapter.d.ts +26 -20
  1164. package/out/us/adapters/usgov/hrsa-fqhc/adapter.d.ts.map +1 -1
  1165. package/out/us/adapters/usgov/hrsa-fqhc/adapter.js +41 -29
  1166. package/out/us/adapters/usgov/hrsa-fqhc/adapter.js.map +1 -1
  1167. package/out/us/adapters/usgov/imls-pls/adapter.d.ts +8 -7
  1168. package/out/us/adapters/usgov/imls-pls/adapter.d.ts.map +1 -1
  1169. package/out/us/adapters/usgov/imls-pls/adapter.js +25 -18
  1170. package/out/us/adapters/usgov/imls-pls/adapter.js.map +1 -1
  1171. package/out/us/adapters/usgov/irs-bmf/adapter.d.ts +11 -10
  1172. package/out/us/adapters/usgov/irs-bmf/adapter.d.ts.map +1 -1
  1173. package/out/us/adapters/usgov/irs-bmf/adapter.js +32 -22
  1174. package/out/us/adapters/usgov/irs-bmf/adapter.js.map +1 -1
  1175. package/out/us/adapters/usgov/nad/adapter.d.ts +11 -31
  1176. package/out/us/adapters/usgov/nad/adapter.d.ts.map +1 -1
  1177. package/out/us/adapters/usgov/nad/adapter.js +51 -105
  1178. package/out/us/adapters/usgov/nad/adapter.js.map +1 -1
  1179. package/out/us/adapters/usgov/nppes/adapter.d.ts +12 -22
  1180. package/out/us/adapters/usgov/nppes/adapter.d.ts.map +1 -1
  1181. package/out/us/adapters/usgov/nppes/adapter.js +62 -32
  1182. package/out/us/adapters/usgov/nppes/adapter.js.map +1 -1
  1183. package/out/us/adapters/usgov/samhsa-treatment-locator/adapter.d.ts +16 -15
  1184. package/out/us/adapters/usgov/samhsa-treatment-locator/adapter.d.ts.map +1 -1
  1185. package/out/us/adapters/usgov/samhsa-treatment-locator/adapter.js +36 -26
  1186. package/out/us/adapters/usgov/samhsa-treatment-locator/adapter.js.map +1 -1
  1187. package/out/us/fips-state.d.ts +17 -8
  1188. package/out/us/fips-state.d.ts.map +1 -1
  1189. package/out/us/fips-state.js +17 -8
  1190. package/out/us/fips-state.js.map +1 -1
  1191. package/out/us/tools/fetch/hrsa.d.ts +3 -3
  1192. package/out/us/tools/fetch/hrsa.d.ts.map +1 -1
  1193. package/out/us/tools/fetch/hrsa.js +6 -7
  1194. package/out/us/tools/fetch/hrsa.js.map +1 -1
  1195. package/out/us/tools/fetch/imls-pls.d.ts +5 -16
  1196. package/out/us/tools/fetch/imls-pls.d.ts.map +1 -1
  1197. package/out/us/tools/fetch/imls-pls.js +16 -33
  1198. package/out/us/tools/fetch/imls-pls.js.map +1 -1
  1199. package/out/us/tools/fetch/nad.d.ts +22 -10
  1200. package/out/us/tools/fetch/nad.d.ts.map +1 -1
  1201. package/out/us/tools/fetch/nad.js +29 -24
  1202. package/out/us/tools/fetch/nad.js.map +1 -1
  1203. package/out/us/tools/fetch/nppes.d.ts +6 -16
  1204. package/out/us/tools/fetch/nppes.d.ts.map +1 -1
  1205. package/out/us/tools/fetch/nppes.js +21 -33
  1206. package/out/us/tools/fetch/nppes.js.map +1 -1
  1207. package/out/us/tools/fetch/state/hi-schools.d.ts +8 -5
  1208. package/out/us/tools/fetch/state/hi-schools.d.ts.map +1 -1
  1209. package/out/us/tools/fetch/state/hi-schools.js +15 -13
  1210. package/out/us/tools/fetch/state/hi-schools.js.map +1 -1
  1211. package/out/us/tools/fetch/state/sources.d.ts +8 -7
  1212. package/out/us/tools/fetch/state/sources.d.ts.map +1 -1
  1213. package/out/us/tools/fetch/state/sources.js +8 -9
  1214. package/out/us/tools/fetch/state/sources.js.map +1 -1
  1215. package/out/us/tools/fetch/tiger-full.d.ts +1 -14
  1216. package/out/us/tools/fetch/tiger-full.d.ts.map +1 -1
  1217. package/out/us/tools/fetch/tiger-full.js +15 -54
  1218. package/out/us/tools/fetch/tiger-full.js.map +1 -1
  1219. package/out/utils/align.d.ts +24 -19
  1220. package/out/utils/align.d.ts.map +1 -1
  1221. package/out/utils/align.js +27 -42
  1222. package/out/utils/align.js.map +1 -1
  1223. package/out/utils/cooccurrence-stats.d.ts +58 -0
  1224. package/out/utils/cooccurrence-stats.d.ts.map +1 -0
  1225. package/out/utils/cooccurrence-stats.js +62 -0
  1226. package/out/utils/cooccurrence-stats.js.map +1 -0
  1227. package/out/utils/golden.d.ts +21 -31
  1228. package/out/utils/golden.d.ts.map +1 -1
  1229. package/out/utils/golden.js +28 -44
  1230. package/out/utils/golden.js.map +1 -1
  1231. package/out/utils/license.d.ts +158 -21
  1232. package/out/utils/license.d.ts.map +1 -1
  1233. package/out/utils/license.js +156 -26
  1234. package/out/utils/license.js.map +1 -1
  1235. package/out/utils/split.d.ts +66 -70
  1236. package/out/utils/split.d.ts.map +1 -1
  1237. package/out/utils/split.js +158 -69
  1238. package/out/utils/split.js.map +1 -1
  1239. package/out/utils/tokenize.d.ts +16 -28
  1240. package/out/utils/tokenize.d.ts.map +1 -1
  1241. package/out/utils/tokenize.js +18 -31
  1242. package/out/utils/tokenize.js.map +1 -1
  1243. package/out/utils/wof-json.d.ts +88 -62
  1244. package/out/utils/wof-json.d.ts.map +1 -1
  1245. package/out/utils/wof-json.js +76 -55
  1246. package/out/utils/wof-json.js.map +1 -1
  1247. package/out/{utils/index.js → utils.d.ts} +1 -2
  1248. package/out/utils.d.ts.map +1 -0
  1249. package/out/{utils/index.d.ts → utils.js} +1 -2
  1250. package/out/utils.js.map +1 -0
  1251. package/out/ve/recipes/reviewed-postcode-tail.d.ts +25 -7
  1252. package/out/ve/recipes/reviewed-postcode-tail.d.ts.map +1 -1
  1253. package/out/ve/recipes/reviewed-postcode-tail.js +33 -12
  1254. package/out/ve/recipes/reviewed-postcode-tail.js.map +1 -1
  1255. package/package.json +46 -480
  1256. package/lib/adapters/index.ts +0 -160
  1257. package/lib/adapters/synth-po-box/adapter.ts +0 -204
  1258. package/lib/adapters/utils/index.ts +0 -307
  1259. package/lib/recipes/bare/postcode/index.ts +0 -327
  1260. package/lib/recipes/sub/venue/index.ts +0 -997
  1261. package/lib/synthesizers/locale.ts +0 -261
  1262. package/lib/test-kit/index.ts +0 -100
  1263. package/lib/tools/align-slice.ts +0 -68
  1264. package/lib/tools/fetch/index.ts +0 -174
  1265. package/lib/tools/gb-title-case.ts +0 -69
  1266. package/lib/tools/index.ts +0 -28
  1267. package/lib/tools/lint/slice/vocab.ts +0 -376
  1268. package/lib/tools/overlay-manifest.ts +0 -215
  1269. package/lib/tools/sub/venue/harvest.ts +0 -234
  1270. package/lib/tools/sub/venue/surfaces.ts +0 -95
  1271. package/lib/tools/sub/venue/table.ts +0 -281
  1272. package/lib/utils/parquet.ts +0 -582
  1273. package/out/adapters/index.d.ts +0 -51
  1274. package/out/adapters/index.d.ts.map +0 -1
  1275. package/out/adapters/index.js +0 -97
  1276. package/out/adapters/index.js.map +0 -1
  1277. package/out/adapters/synth-po-box/adapter.d.ts +0 -67
  1278. package/out/adapters/synth-po-box/adapter.d.ts.map +0 -1
  1279. package/out/adapters/synth-po-box/adapter.js.map +0 -1
  1280. package/out/adapters/utils/index.d.ts +0 -191
  1281. package/out/adapters/utils/index.d.ts.map +0 -1
  1282. package/out/adapters/utils/index.js +0 -206
  1283. package/out/adapters/utils/index.js.map +0 -1
  1284. package/out/fr/adapters/ban/street-decompose.d.ts.map +0 -1
  1285. package/out/fr/adapters/ban/street-decompose.js.map +0 -1
  1286. package/out/no/recipes/street/index.d.ts +0 -18
  1287. package/out/no/recipes/street/index.d.ts.map +0 -1
  1288. package/out/no/recipes/street/index.js.map +0 -1
  1289. package/out/recipes/bare/postcode/index.d.ts +0 -62
  1290. package/out/recipes/bare/postcode/index.d.ts.map +0 -1
  1291. package/out/recipes/bare/postcode/index.js.map +0 -1
  1292. package/out/recipes/index.d.ts +0 -24
  1293. package/out/recipes/index.d.ts.map +0 -1
  1294. package/out/recipes/index.js.map +0 -1
  1295. package/out/recipes/po/box/index.d.ts +0 -17
  1296. package/out/recipes/po/box/index.d.ts.map +0 -1
  1297. package/out/recipes/po/box/index.js.map +0 -1
  1298. package/out/recipes/sub/venue/index.d.ts +0 -270
  1299. package/out/recipes/sub/venue/index.d.ts.map +0 -1
  1300. package/out/recipes/sub/venue/index.js +0 -728
  1301. package/out/recipes/sub/venue/index.js.map +0 -1
  1302. package/out/synthesizers/locale.d.ts +0 -116
  1303. package/out/synthesizers/locale.d.ts.map +0 -1
  1304. package/out/synthesizers/locale.js +0 -150
  1305. package/out/synthesizers/locale.js.map +0 -1
  1306. package/out/test-kit/index.d.ts +0 -48
  1307. package/out/test-kit/index.d.ts.map +0 -1
  1308. package/out/test-kit/index.js +0 -78
  1309. package/out/test-kit/index.js.map +0 -1
  1310. package/out/tools/align-slice.d.ts +0 -7
  1311. package/out/tools/align-slice.d.ts.map +0 -1
  1312. package/out/tools/align-slice.js +0 -55
  1313. package/out/tools/align-slice.js.map +0 -1
  1314. package/out/tools/fetch/download/index.d.ts.map +0 -1
  1315. package/out/tools/fetch/download/index.js.map +0 -1
  1316. package/out/tools/fetch/index.d.ts +0 -171
  1317. package/out/tools/fetch/index.d.ts.map +0 -1
  1318. package/out/tools/fetch/index.js +0 -170
  1319. package/out/tools/fetch/index.js.map +0 -1
  1320. package/out/tools/gb-title-case.d.ts +0 -2
  1321. package/out/tools/gb-title-case.d.ts.map +0 -1
  1322. package/out/tools/gb-title-case.js +0 -65
  1323. package/out/tools/gb-title-case.js.map +0 -1
  1324. package/out/tools/golden/relabel-street/index.d.ts.map +0 -1
  1325. package/out/tools/golden/relabel-street/index.js.map +0 -1
  1326. package/out/tools/index.d.ts +0 -28
  1327. package/out/tools/index.d.ts.map +0 -1
  1328. package/out/tools/index.js +0 -28
  1329. package/out/tools/index.js.map +0 -1
  1330. package/out/tools/lint/slice/index.d.ts +0 -93
  1331. package/out/tools/lint/slice/index.d.ts.map +0 -1
  1332. package/out/tools/lint/slice/index.js.map +0 -1
  1333. package/out/tools/lint/slice/vocab.d.ts +0 -90
  1334. package/out/tools/lint/slice/vocab.d.ts.map +0 -1
  1335. package/out/tools/lint/slice/vocab.js.map +0 -1
  1336. package/out/tools/overlay-manifest.d.ts +0 -89
  1337. package/out/tools/overlay-manifest.d.ts.map +0 -1
  1338. package/out/tools/overlay-manifest.js +0 -131
  1339. package/out/tools/overlay-manifest.js.map +0 -1
  1340. package/out/tools/slice/kryptonite.d.ts +0 -32
  1341. package/out/tools/slice/kryptonite.d.ts.map +0 -1
  1342. package/out/tools/slice/kryptonite.js.map +0 -1
  1343. package/out/tools/slice/translit.d.ts +0 -51
  1344. package/out/tools/slice/translit.d.ts.map +0 -1
  1345. package/out/tools/slice/translit.js.map +0 -1
  1346. package/out/tools/sub/venue/harvest.d.ts +0 -100
  1347. package/out/tools/sub/venue/harvest.d.ts.map +0 -1
  1348. package/out/tools/sub/venue/harvest.js +0 -168
  1349. package/out/tools/sub/venue/harvest.js.map +0 -1
  1350. package/out/tools/sub/venue/promotions.d.ts +0 -94
  1351. package/out/tools/sub/venue/promotions.d.ts.map +0 -1
  1352. package/out/tools/sub/venue/promotions.js.map +0 -1
  1353. package/out/tools/sub/venue/surfaces.d.ts +0 -45
  1354. package/out/tools/sub/venue/surfaces.d.ts.map +0 -1
  1355. package/out/tools/sub/venue/surfaces.js +0 -77
  1356. package/out/tools/sub/venue/surfaces.js.map +0 -1
  1357. package/out/tools/sub/venue/table.d.ts +0 -229
  1358. package/out/tools/sub/venue/table.d.ts.map +0 -1
  1359. package/out/tools/sub/venue/table.js +0 -108
  1360. package/out/tools/sub/venue/table.js.map +0 -1
  1361. package/out/utils/index.d.ts.map +0 -1
  1362. package/out/utils/index.js.map +0 -1
  1363. package/out/utils/parquet.d.ts +0 -178
  1364. package/out/utils/parquet.d.ts.map +0 -1
  1365. package/out/utils/parquet.js +0 -371
  1366. package/out/utils/parquet.js.map +0 -1
  1367. package/out/utils/slice-stats.d.ts +0 -52
  1368. package/out/utils/slice-stats.d.ts.map +0 -1
  1369. package/out/utils/slice-stats.js +0 -58
  1370. package/out/utils/slice-stats.js.map +0 -1
  1371. /package/lib/tools/fetch/{download/index.ts → download.ts} +0 -0
  1372. /package/lib/tools/golden/{relabel-street/index.ts → relabel-street.ts} +0 -0
@@ -0,0 +1,943 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ *
6
+ * The paging, manifest and resumption machinery a paged WFS harvest shares.
7
+ *
8
+ * `./inspire-addresses.ts` owns what an INSPIRE Addresses service exposes — its capabilities, its
9
+ * feature-type names and its GeoJSON pages. This module owns what a harvest of any paged WFS does
10
+ * with those pages: it appends each one to the single file an adapter's `inputPath` points at,
11
+ * records the page in a manifest beside it, and resumes from that manifest after an interrupted run.
12
+ *
13
+ * One file rather than one file per page, because the adapters read one. `#ee/adapters/ads/adapter`
14
+ * opens `opts.inputPath` as newline-delimited JSON and `#pl/adapters/emuia/adapter` opens it as one
15
+ * markup stream, so a directory of pages reaches neither. The manifest therefore records each page's
16
+ * byte range inside that file: `offset`, `bytes` and the sha256 of exactly those bytes. A range is
17
+ * what makes a page verifiable after it has been concatenated into its neighbors, and what lets an
18
+ * interrupted append be truncated back to a page boundary rather than discarding the harvest.
19
+ *
20
+ * Three properties of a WFS make this harder than reading pages until they run out, and each is
21
+ * handled here rather than by each country's module:
22
+ *
23
+ * 1. A service may ignore `startIndex` and answer every page with the first. `countWFSFeaturesByPaging`
24
+ * in `@mailwoman/core/api` refuses such a service by comparing two pages' leading feature. A
25
+ * harvest sees the same defect as two consecutive pages with equal bytes, which this refuses.
26
+ * 2. A service's own `numberMatched` may be a per-request cap rather than a count. The caller states
27
+ * what its count is and where it came from, and {@linkcode PagedWFSHarvestOptions.featureCount}
28
+ * carries both. No count is written into this module, and a harvest with no usable count ends on
29
+ * the first page that returns no features.
30
+ * 3. A page may return fewer features than `count` asks for. The next `startIndex` therefore advances
31
+ * by the features the service returned rather than by the page size, so a service that caps a page
32
+ * below the requested size is read whole instead of being read in strides that skip features.
33
+ */
34
+
35
+ import { APIClient, assertNoOGCServiceException, type CheckedWFSFeatureCount } from "@mailwoman/core/api"
36
+ import { ByteFormatter } from "@mailwoman/core/fs/formatters"
37
+ import { readFileRange, tryStat } from "@mailwoman/core/fs/readers"
38
+ import { appendLocalTextFile, makeDirectories, removePathIfPresent, truncateFile } from "@mailwoman/core/fs/writers"
39
+ import { sha256File, sha256Hex } from "@mailwoman/core/hash"
40
+ import { stringifyJSON } from "@mailwoman/core/json"
41
+ import { isoSecondsUTC } from "@mailwoman/core/utils"
42
+ import { PathBuilder, type PathBuilderLike } from "path-ts"
43
+
44
+ import { readManifest, writeManifest, type FetchSummary } from "#tools/fetch/download"
45
+
46
+ /**
47
+ * The WFS version this repository's harvesters speak.
48
+ *
49
+ * 2.0.0 defines `startIndex` paging and the `hits` result type, and it is what
50
+ * every service measured for these modules advertises.
51
+ */
52
+ export const WFS_VERSION = "2.0.0"
53
+
54
+ /**
55
+ * The file name a harvest writes its manifest under, beside the data file.
56
+ */
57
+ export const HARVEST_MANIFEST_FILE = "MANIFEST.json"
58
+
59
+ /**
60
+ * The first element of a response, as the service wrote it.
61
+ */
62
+ export interface MarkupRoot {
63
+ /**
64
+ * The opening tag verbatim, `<wfs:FeatureCollection …>`.
65
+ */
66
+ tag: string
67
+ /**
68
+ * The element's qualified name, prefix included.
69
+ */
70
+ name: string
71
+ /**
72
+ * The text between the name and the tag's terminator, which holds the attributes.
73
+ */
74
+ attributes: string
75
+ /**
76
+ * The offset just past the opening tag.
77
+ */
78
+ contentStart: number
79
+ }
80
+
81
+ /**
82
+ * The first element tag in a document.
83
+ *
84
+ * An index scan over the tag rather than a parse of the document: a harvest needs the
85
+ * opening tag verbatim to open the file it assembles, and parsing a 1.6 MB page per request
86
+ * to recover a tag that the first 400 bytes already hold costs a document parse per page.
87
+ *
88
+ * The leading `[A-Za-z_]` skips the XML declaration, which opens `<?xml`.
89
+ */
90
+ const ROOT_OPENING_TAG = /<([A-Za-z_][\w.:-]*)([^>]*)>/u
91
+
92
+ /**
93
+ * One attribute of an opening tag, by local name.
94
+ */
95
+ function tagAttribute(root: MarkupRoot, attribute: string): string | undefined {
96
+ const pattern = new RegExp(`(?:^|\\s)(?:[\\w.-]+:)?${attribute}\\s*=\\s*"([^"]*)"`, "iu")
97
+
98
+ return pattern.exec(root.attributes)?.[1]
99
+ }
100
+
101
+ /**
102
+ * The count an opening tag states, or `null` where it states none or declines to state one.
103
+ *
104
+ * WFS 2.0 permits `numberMatched="unknown"`, which declines to count rather than counting none.
105
+ */
106
+ export function rootCount(root: MarkupRoot, attribute: string): number | null {
107
+ const value = tagAttribute(root, attribute)
108
+
109
+ return value !== undefined && /^\d+$/u.test(value) ? Number(value) : null
110
+ }
111
+
112
+ /**
113
+ * The document's first element tag.
114
+ *
115
+ * @throws When the body holds no element tag, so a response that is not markup
116
+ * reads as unreadable rather than as a page of no features.
117
+ */
118
+ export function readMarkupRoot(body: string, context: string): MarkupRoot {
119
+ const match = ROOT_OPENING_TAG.exec(body)
120
+
121
+ if (!match) {
122
+ throw new TypeError(
123
+ `${context}: the response carried no element tag, so its root could not be read, beginning ${stringifyJSON(body.slice(0, 120))}`
124
+ )
125
+ }
126
+
127
+ return {
128
+ tag: match[0],
129
+ name: match[1] ?? "",
130
+ attributes: match[2] ?? "",
131
+ contentStart: match.index + match[0].length,
132
+ }
133
+ }
134
+
135
+ /**
136
+ * The content between a document's root tags, which for a `wfs:FeatureCollection` is its members.
137
+ *
138
+ * @throws When the root element is not closed, so a truncated transfer reads as
139
+ * unreadable rather than as a page of no features.
140
+ */
141
+ export function rootContent(body: string, root: MarkupRoot, context: string): string {
142
+ const closing = `</${root.name}>`
143
+ const end = body.lastIndexOf(closing)
144
+
145
+ if (end < root.contentStart) {
146
+ throw new TypeError(
147
+ `${context}: the response's ${root.name} element is not closed, so the members it holds could not be separated from the document that carries them`
148
+ )
149
+ }
150
+
151
+ return body.slice(root.contentStart, end)
152
+ }
153
+
154
+ /**
155
+ * The attributes a page states about itself rather than about the feature type.
156
+ *
157
+ * A harvest assembles many pages under one root element, so the first page's counts
158
+ * and timestamp would describe the assembled file wrongly.
159
+ * They are dropped and the manifest records them per page.
160
+ */
161
+ const PAGE_ATTRIBUTES = /\s(?:[\w.-]+:)?(?:numberMatched|numberReturned|timeStamp|next|previous)\s*=\s*"[^"]*"/giu
162
+
163
+ /**
164
+ * A page's root tag with its namespace declarations kept and its per-page attributes
165
+ * dropped, so it can open a file holding every page.
166
+ */
167
+ export function collectionOpeningTag(root: MarkupRoot): string {
168
+ return `<${root.name}${root.attributes.replace(PAGE_ATTRIBUTES, "")}>`
169
+ }
170
+
171
+ /**
172
+ * One `GetFeature` response in a markup format, with what its root states about itself.
173
+ */
174
+ export interface WFSMarkupPage {
175
+ body: string
176
+ root: MarkupRoot
177
+ /**
178
+ * The `numberReturned` the root states, or `null` where it states none.
179
+ */
180
+ numberReturned: number | null
181
+ /**
182
+ * The `numberMatched` the root states, or `null` where it answers `unknown`.
183
+ */
184
+ numberMatched: number | null
185
+ /**
186
+ * The `timeStamp` the root states, or `null` where it states none.
187
+ */
188
+ timeStamp: string | null
189
+ }
190
+
191
+ /**
192
+ * Issues one `GetFeature` and reads the counts off the root element.
193
+ *
194
+ * @throws When the service answers an OGC exception report, so an HTTP 400 carrying
195
+ * `ows:ExceptionCode` raises rather than being written into the harvest as a page.
196
+ */
197
+ export async function readWFSMarkupPage(
198
+ client: Pick<APIClient, "fetch">,
199
+ options: { wfsURL: string; context: string; params: Readonly<Record<string, string>> }
200
+ ): Promise<WFSMarkupPage> {
201
+ const { data } = await client.fetch<string>({
202
+ method: "GET",
203
+ url: options.wfsURL,
204
+ responseType: "text",
205
+ params: { service: "WFS", version: WFS_VERSION, request: "GetFeature", ...options.params },
206
+ })
207
+
208
+ assertNoOGCServiceException(data, options.context)
209
+
210
+ const root = readMarkupRoot(data, options.context)
211
+
212
+ return {
213
+ body: data,
214
+ root,
215
+ numberReturned: rootCount(root, "numberReturned"),
216
+ numberMatched: rootCount(root, "numberMatched"),
217
+ timeStamp: tagAttribute(root, "timeStamp") ?? null,
218
+ }
219
+ }
220
+
221
+ /**
222
+ * What a harvest asked the service for.
223
+ *
224
+ * Recorded in the manifest and compared against a resumed run's request: a harvest whose page
225
+ * size, ordering or format changed cannot be continued from pages taken under the old one.
226
+ */
227
+ export interface WFSHarvestRequest {
228
+ wfsURL: string
229
+ typeName: string
230
+ outputFormat: string
231
+ /**
232
+ * The property the service was asked to order by, or `null` where it grants no ordering.
233
+ *
234
+ * Without one, a resumed harvest rests on the service returning the same features
235
+ * in the same order as the earlier run, which no WFS guarantees.
236
+ */
237
+ sortBy: string | null
238
+ }
239
+
240
+ /**
241
+ * A feature count and how it was obtained.
242
+ *
243
+ * `count` is `null` where the service states no usable count.
244
+ * The harvest then ends on the first page that returns no features, and
245
+ * `because` records what the service said instead.
246
+ */
247
+ export interface FeatureCountStatement {
248
+ count: number | null
249
+ because: string
250
+ }
251
+
252
+ /**
253
+ * The count a service states, or no count and the reason there is none.
254
+ *
255
+ * `readCheckedWFSFeatureCount` proves a reported `numberMatched` against a page of the
256
+ * same type, which catches a service whose count is smaller than one of its own pages.
257
+ * It cannot catch a count that equals the service's page cap: no page can return more
258
+ * features than the cap, so the page it asks for agrees with the cap every time.
259
+ *
260
+ * Poland's service is that case.
261
+ * Measured 2026-10-02, `resultType=hits` at `startIndex=1` reports `numberMatched="1000"`, its
262
+ * capabilities document advertises `CountDefault` as 1000, and a page returns at most 1,000 features.
263
+ *
264
+ * The reported number is the cap, and a harvest that read it as a count would store 1,000
265
+ * of the 8.6 million features the service holds and record the type as read whole.
266
+ * A reported count equal to the cap is therefore carried as no count.
267
+ *
268
+ * @param pageCap The largest page the service will serve, from its advertised `CountDefault`.
269
+ */
270
+ export function statedFeatureCount(checked: CheckedWFSFeatureCount, pageCap: number | null): FeatureCountStatement {
271
+ if (!checked.usable || checked.reported === null) {
272
+ return { count: null, because: `the service stated no usable count: ${checked.because}` }
273
+ }
274
+
275
+ if (pageCap !== null && checked.reported === pageCap) {
276
+ return {
277
+ count: null,
278
+ because: `the service reported numberMatched=${checked.reported}, which is the ${pageCap}-feature cap it advertises as CountDefault, so the number describes the largest page it will serve rather than what the type holds`,
279
+ }
280
+ }
281
+
282
+ return {
283
+ count: checked.reported,
284
+ because: `the service reported numberMatched=${checked.reported} past index 0, and ${checked.because}`,
285
+ }
286
+ }
287
+
288
+ /**
289
+ * One page's contribution to the harvest file.
290
+ */
291
+ export interface HarvestedPayload {
292
+ /**
293
+ * The text appended to the harvest file for this page.
294
+ */
295
+ payload: string
296
+ /**
297
+ * Text written once, before the first page's payload — a document prolog
298
+ * and root tag, where the format needs one.
299
+ *
300
+ * Read from the first page a run writes and recorded in the manifest.
301
+ */
302
+ header?: string
303
+ /**
304
+ * Text written once the harvest reaches the end of the feature type, such as a closing root tag.
305
+ */
306
+ footer?: string
307
+ /**
308
+ * The features the service returned, which is what the next `startIndex` advances by.
309
+ *
310
+ * `null` where the service stated none.
311
+ * The harvest refuses that rather than reading it as zero.
312
+ */
313
+ numberReturned: number | null
314
+ numberMatched: number | null
315
+ retrievedAt: string | null
316
+ }
317
+
318
+ /**
319
+ * One page as the manifest records it.
320
+ *
321
+ * `offset` and `bytes` locate the page inside the harvest file and `sha256` is the digest of
322
+ * exactly those bytes, so a page stays verifiable after the pages around it were appended.
323
+ */
324
+ export interface WFSHarvestPageRecord {
325
+ start_index: number
326
+ /**
327
+ * The page size requested, which a service may answer with fewer features.
328
+ */
329
+ count: number
330
+ offset: number
331
+ bytes: number
332
+ sha256: string
333
+ number_returned: number
334
+ /**
335
+ * The `numberMatched` this page stated, where the service states a real one.
336
+ */
337
+ number_matched: number | null
338
+ retrieved_at: string | null
339
+ }
340
+
341
+ /**
342
+ * The manifest a paged harvest writes beside its data file.
343
+ *
344
+ * Written after every page, so an interrupted run resumes from the last page that reached disk.
345
+ */
346
+ export interface WFSHarvestManifest {
347
+ source: string
348
+ source_url: string
349
+ wfs_version: string
350
+ type_name: string
351
+ output_format: string
352
+ sort_by: string | null
353
+ license: string
354
+ attribution: string
355
+ downloaded_at: string
356
+ /**
357
+ * The file an adapter's `inputPath` points at, beside this manifest.
358
+ */
359
+ filename: string
360
+ page_size: number
361
+ /**
362
+ * The service's own count where it states a usable one, and `null` where it does not.
363
+ */
364
+ feature_count: number | null
365
+ feature_count_source: string
366
+ features_written: number
367
+ header_bytes: number
368
+ /**
369
+ * The text that closes the data file, appended once the harvest reaches the end of the type.
370
+ */
371
+ footer: string
372
+ /**
373
+ * The data file's byte length as this manifest describes it, footer included once complete.
374
+ */
375
+ bytes: number
376
+ /**
377
+ * The whole data file's digest, once the harvest is complete.
378
+ *
379
+ * `null` on a partial harvest, where the file is still being appended to
380
+ * and a digest of it would describe a prefix rather than the harvest.
381
+ */
382
+ sha256: string | null
383
+ complete: boolean
384
+ pages: WFSHarvestPageRecord[]
385
+ }
386
+
387
+ export interface PagedWFSHarvestOptions {
388
+ /**
389
+ * Names the service in every refusal.
390
+ */
391
+ context: string
392
+ /**
393
+ * The adapter slug this harvest feeds, stamped into the manifest.
394
+ */
395
+ source: string
396
+ /**
397
+ * Where the harvest is written.
398
+ *
399
+ * The adapter reads {@linkcode PagedWFSHarvestOptions.filename} inside this directory.
400
+ */
401
+ outputDir: PathBuilderLike
402
+ filename: string
403
+ request: WFSHarvestRequest
404
+ /**
405
+ * The license the address-source register elected for this publisher.
406
+ */
407
+ license: string
408
+ /**
409
+ * The attribution the elected terms require, or an empty string where they require none.
410
+ */
411
+ attribution: string
412
+ featureCount: FeatureCountStatement
413
+ pageSize: number
414
+ /**
415
+ * Stop once the manifest holds this many pages, for a probe rather than a full harvest.
416
+ *
417
+ * A cap on the manifest rather than on the run, so a second run under the same cap makes no request.
418
+ */
419
+ maxPages?: number
420
+ signal?: AbortSignal
421
+ /**
422
+ * Reads one page and states the bytes the harvest file receives for it.
423
+ */
424
+ readPage: (request: { startIndex: number; count: number }) => Promise<HarvestedPayload>
425
+ report?: (line: string) => void
426
+ }
427
+
428
+ /**
429
+ * Does a recorded manifest describe the request being made now?
430
+ *
431
+ * A harvest taken at another page size, ordering, format or type cannot be continued:
432
+ * its pages were cut at different boundaries, and appending to them would leave
433
+ * a file whose manifest describes neither half.
434
+ */
435
+ function describesSameRequest(manifest: WFSHarvestManifest, options: PagedWFSHarvestOptions): boolean {
436
+ return (
437
+ manifest.source_url === options.request.wfsURL &&
438
+ manifest.type_name === options.request.typeName &&
439
+ manifest.output_format === options.request.outputFormat &&
440
+ manifest.sort_by === options.request.sortBy &&
441
+ manifest.page_size === options.pageSize &&
442
+ manifest.filename === options.filename
443
+ )
444
+ }
445
+
446
+ function emptyManifest(options: PagedWFSHarvestOptions): WFSHarvestManifest {
447
+ return {
448
+ source: options.source,
449
+ source_url: options.request.wfsURL,
450
+ wfs_version: WFS_VERSION,
451
+ type_name: options.request.typeName,
452
+ output_format: options.request.outputFormat,
453
+ sort_by: options.request.sortBy,
454
+ license: options.license,
455
+ attribution: options.attribution,
456
+ downloaded_at: isoSecondsUTC(),
457
+ filename: options.filename,
458
+ page_size: options.pageSize,
459
+ feature_count: options.featureCount.count,
460
+ feature_count_source: options.featureCount.because,
461
+ features_written: 0,
462
+ header_bytes: 0,
463
+ footer: "",
464
+ bytes: 0,
465
+ sha256: null,
466
+ complete: false,
467
+ pages: [],
468
+ }
469
+ }
470
+
471
+ /**
472
+ * The offset the next page is appended at: the header plus every recorded page.
473
+ */
474
+ function dataEndOf(manifest: WFSHarvestManifest): number {
475
+ let end = manifest.header_bytes
476
+
477
+ for (const page of manifest.pages) {
478
+ end += page.bytes
479
+ }
480
+
481
+ return end
482
+ }
483
+
484
+ /**
485
+ * The features the recorded pages hold between them.
486
+ */
487
+ function featuresIn(pages: readonly WFSHarvestPageRecord[]): number {
488
+ let features = 0
489
+
490
+ for (const page of pages) {
491
+ features += page.number_returned
492
+ }
493
+
494
+ return features
495
+ }
496
+
497
+ /**
498
+ * The index the next page starts at: one past the last feature any recorded page reached.
499
+ */
500
+ function nextStartIndexOf(pages: readonly WFSHarvestPageRecord[]): number {
501
+ let next = 0
502
+
503
+ for (const page of pages) {
504
+ next = Math.max(next, page.start_index + page.number_returned)
505
+ }
506
+
507
+ return next
508
+ }
509
+
510
+ /**
511
+ * The recorded pages that are actually on disk, with the file truncated back to the last of them.
512
+ *
513
+ * An interrupted run can leave a partial page at the end of the file,
514
+ * or a footer the next page has to be appended past.
515
+ * Both are resolved by cutting the file at the last page boundary the file reaches,
516
+ * which is a page boundary rather than an arbitrary offset.
517
+ *
518
+ * @throws When the last surviving page's bytes no longer hash to what the manifest recorded,
519
+ * which is a file that was altered rather than one that was cut short.
520
+ */
521
+ async function reconcileHarvestFile(
522
+ manifest: WFSHarvestManifest,
523
+ dataPath: PathBuilderLike,
524
+ context: string,
525
+ report?: (line: string) => void
526
+ ): Promise<WFSHarvestManifest> {
527
+ const stat = await tryStat(dataPath)
528
+ const size = stat?.size ?? 0
529
+
530
+ const kept: WFSHarvestPageRecord[] = []
531
+
532
+ for (const page of manifest.pages) {
533
+ if (page.offset + page.bytes > size) break
534
+
535
+ kept.push(page)
536
+ }
537
+
538
+ if (kept.length < manifest.pages.length) {
539
+ report?.(
540
+ ` ${manifest.pages.length - kept.length} of ${manifest.pages.length} recorded pages are not on disk — resuming from page ${kept.length}`
541
+ )
542
+ }
543
+
544
+ const reconciled: WFSHarvestManifest = {
545
+ ...manifest,
546
+ pages: kept,
547
+ features_written: featuresIn(kept),
548
+ complete: manifest.complete && kept.length === manifest.pages.length,
549
+ }
550
+
551
+ if (!kept.length) {
552
+ // A header with no page behind it describes an empty document, so the file starts over.
553
+ await removePathIfPresent(dataPath)
554
+
555
+ return { ...reconciled, header_bytes: 0, footer: "", bytes: 0, sha256: null, complete: false }
556
+ }
557
+
558
+ const last = kept.at(-1)!
559
+ const recordedBytes = await readFileRange(dataPath, last.offset, last.bytes)
560
+ const digest = sha256Hex(recordedBytes)
561
+
562
+ if (digest !== last.sha256) {
563
+ throw new Error(
564
+ `${context}: the ${last.bytes} bytes the manifest records for the page at startIndex ${last.start_index} hash to ${digest} rather than ${last.sha256}, so ${dataPath} holds something other than the harvest it describes`
565
+ )
566
+ }
567
+
568
+ const dataEnd = dataEndOf(reconciled)
569
+
570
+ if (reconciled.complete) {
571
+ const expected = dataEnd + Buffer.byteLength(reconciled.footer)
572
+
573
+ if (size === expected) return { ...reconciled, bytes: expected }
574
+
575
+ report?.(` The complete harvest records ${expected} bytes and ${size} are on disk — closing it again`)
576
+ }
577
+
578
+ if (size !== dataEnd) {
579
+ await truncateFile(dataPath, dataEnd)
580
+ }
581
+
582
+ return { ...reconciled, bytes: dataEnd, sha256: null, complete: false }
583
+ }
584
+
585
+ /**
586
+ * What a caller knows about the request it is about to make before it has asked the service.
587
+ *
588
+ * The type name and the output format come from a capabilities document, so they are not here:
589
+ * the point of this check is to answer whether a harvest is already current without sending a request.
590
+ */
591
+ export interface HarvestCurrencyExpectation {
592
+ wfsURL: string
593
+ sortBy: string | null
594
+ pageSize: number
595
+ }
596
+
597
+ /**
598
+ * The manifest of a harvest that needs no further request, or `null` where one does.
599
+ *
600
+ * A caller reads this before it reads a capabilities document, so a current harvest costs no request at all.
601
+ * Two harvests need none:
602
+ *
603
+ * - A complete one whose data file still hashes to the digest the manifest records.
604
+ * - A partial one that already holds `maxPages` pages, which is what a bounded probe asks for.
605
+ *
606
+ * @throws When a page's recorded byte range no longer hashes to its recorded digest,
607
+ * so a file that was altered under its manifest is reported rather than used.
608
+ */
609
+ export async function readCurrentHarvest(options: {
610
+ outputDir: PathBuilderLike
611
+ filename: string
612
+ context: string
613
+ expect: HarvestCurrencyExpectation
614
+ maxPages?: number
615
+ }): Promise<WFSHarvestManifest | null> {
616
+ const root = PathBuilder.from(options.outputDir)
617
+ const manifest = await readManifest<WFSHarvestManifest>(root(HARVEST_MANIFEST_FILE))
618
+
619
+ if (!manifest || !Array.isArray(manifest.pages)) return null
620
+
621
+ const describesThisRequest =
622
+ manifest.filename === options.filename &&
623
+ manifest.source_url === options.expect.wfsURL &&
624
+ manifest.sort_by === options.expect.sortBy &&
625
+ manifest.page_size === options.expect.pageSize
626
+
627
+ if (!describesThisRequest) return null
628
+
629
+ const dataPath = root(options.filename)
630
+
631
+ if (manifest.complete) {
632
+ const stat = await tryStat(dataPath)
633
+
634
+ if (!stat || stat.size !== manifest.bytes) return null
635
+
636
+ return (await sha256File(dataPath)) === manifest.sha256 ? manifest : null
637
+ }
638
+
639
+ if (options.maxPages === undefined || manifest.pages.length < options.maxPages) return null
640
+
641
+ const last = manifest.pages.at(-1)
642
+
643
+ if (!last) return null
644
+
645
+ const stat = await tryStat(dataPath)
646
+
647
+ if (!stat || stat.size < last.offset + last.bytes) return null
648
+
649
+ const digest = sha256Hex(await readFileRange(dataPath, last.offset, last.bytes))
650
+
651
+ if (digest !== last.sha256) {
652
+ throw new Error(
653
+ `${options.context}: the ${last.bytes} bytes the manifest records for the page at startIndex ${last.start_index} hash to ${digest} rather than ${last.sha256}, so ${dataPath} holds something other than the harvest it describes`
654
+ )
655
+ }
656
+
657
+ return manifest
658
+ }
659
+
660
+ /**
661
+ * Harvests one WFS feature type into a single file, recording each page in a manifest beside it.
662
+ *
663
+ * Re-runnable in three ways, each of which makes no request:
664
+ *
665
+ * - A complete harvest whose file still hashes to the manifest's `sha256`.
666
+ * - A partial harvest that already holds {@linkcode PagedWFSHarvestOptions.maxPages} pages.
667
+ * - A partial harvest resumes at the page after the last one on disk,
668
+ * so the pages already taken are not taken again.
669
+ *
670
+ * @returns The manifest as written.
671
+ */
672
+ export async function harvestPagedWFS(options: PagedWFSHarvestOptions): Promise<WFSHarvestManifest> {
673
+ const root = PathBuilder.from(options.outputDir)
674
+
675
+ await makeDirectories(root)
676
+
677
+ const dataPath = root(options.filename)
678
+ const manifestPath = root(HARVEST_MANIFEST_FILE)
679
+ const recorded = await readManifest<WFSHarvestManifest>(manifestPath)
680
+ const resumable = recorded !== null && Array.isArray(recorded.pages) && describesSameRequest(recorded, options)
681
+
682
+ if (recorded !== null && !resumable) {
683
+ options.report?.(" The manifest describes a different request — starting the harvest over")
684
+
685
+ await removePathIfPresent(dataPath)
686
+ }
687
+
688
+ let manifest = resumable
689
+ ? await reconcileHarvestFile(recorded, dataPath, options.context, options.report)
690
+ : emptyManifest(options)
691
+
692
+ // The count may have become readable, or stopped being readable, since the recorded run.
693
+ manifest = {
694
+ ...manifest,
695
+ feature_count: options.featureCount.count,
696
+ feature_count_source: options.featureCount.because,
697
+ }
698
+
699
+ if (manifest.complete) {
700
+ const digest = await sha256File(dataPath)
701
+
702
+ if (digest === manifest.sha256) {
703
+ options.report?.(` ✓ Already harvested (sha256 matches ${HARVEST_MANIFEST_FILE}) — no request made.`)
704
+
705
+ return manifest
706
+ }
707
+
708
+ options.report?.(` ${dataPath} hashes to ${digest} rather than ${manifest.sha256} — harvesting it again`)
709
+
710
+ manifest = { ...manifest, complete: false, sha256: null }
711
+ }
712
+
713
+ const atPageCap = (): boolean => options.maxPages !== undefined && manifest.pages.length >= options.maxPages
714
+
715
+ if (atPageCap()) {
716
+ options.report?.(` ✓ The manifest already holds ${manifest.pages.length} pages — no request made.`)
717
+
718
+ return manifest
719
+ }
720
+
721
+ let startIndex = nextStartIndexOf(manifest.pages)
722
+ let complete = false
723
+
724
+ for (;;) {
725
+ if (options.signal?.aborted) break
726
+
727
+ if (atPageCap()) break
728
+
729
+ if (manifest.feature_count !== null && manifest.features_written >= manifest.feature_count) {
730
+ complete = true
731
+
732
+ break
733
+ }
734
+
735
+ const page = await options.readPage({ startIndex, count: options.pageSize })
736
+
737
+ if (page.numberReturned === null) {
738
+ throw new Error(
739
+ `${options.context}: the page at startIndex ${startIndex} stated no numberReturned, so what it holds is unknown rather than empty`
740
+ )
741
+ }
742
+
743
+ if (page.numberReturned === 0) {
744
+ complete = true
745
+
746
+ break
747
+ }
748
+
749
+ const payloadBytes = Buffer.byteLength(page.payload)
750
+ const digest = sha256Hex(page.payload)
751
+ const previous = manifest.pages.at(-1)
752
+
753
+ // A service that ignores `startIndex` answers every page with the first,
754
+ // and a harvest of one would hold the same features repeated.
755
+ // `countWFSFeaturesByPaging` refuses such a service by comparing two pages' leading feature.
756
+ // Identical bytes is the same defect seen here.
757
+ if (previous && previous.bytes === payloadBytes && previous.sha256 === digest) {
758
+ throw new Error(
759
+ `${options.context}: the page at startIndex ${startIndex} is byte-identical to the page at startIndex ${previous.start_index}, so the service is answering a new startIndex with the previous page rather than paging`
760
+ )
761
+ }
762
+
763
+ if (!manifest.pages.length && page.header) {
764
+ await appendLocalTextFile(page.header, dataPath)
765
+
766
+ manifest = { ...manifest, header_bytes: Buffer.byteLength(page.header) }
767
+ }
768
+
769
+ const offset = dataEndOf(manifest)
770
+
771
+ await appendLocalTextFile(page.payload, dataPath)
772
+
773
+ manifest = {
774
+ ...manifest,
775
+ downloaded_at: isoSecondsUTC(),
776
+ footer: page.footer ?? manifest.footer,
777
+ features_written: manifest.features_written + page.numberReturned,
778
+ bytes: offset + payloadBytes,
779
+ pages: [
780
+ ...manifest.pages,
781
+ {
782
+ start_index: startIndex,
783
+ count: options.pageSize,
784
+ offset,
785
+ bytes: payloadBytes,
786
+ sha256: digest,
787
+ number_returned: page.numberReturned,
788
+ number_matched: page.numberMatched,
789
+ retrieved_at: page.retrievedAt,
790
+ },
791
+ ],
792
+ }
793
+
794
+ await writeManifest(manifestPath, manifest)
795
+
796
+ options.report?.(
797
+ ` page ${manifest.pages.length} at startIndex ${startIndex}: ${page.numberReturned} features, ${ByteFormatter.formatIEC(payloadBytes)} (${manifest.features_written} written)`
798
+ )
799
+
800
+ // The service's own answer rather than the page size: a service that caps a page below the
801
+ // requested size would otherwise be read in strides that skip the features it did not return.
802
+ startIndex += page.numberReturned
803
+ }
804
+
805
+ if (complete) {
806
+ if (manifest.footer) {
807
+ await appendLocalTextFile(manifest.footer, dataPath)
808
+ }
809
+
810
+ // A feature type of no features still needs the file the adapter opens, and an empty append creates it.
811
+ if (!(await tryStat(dataPath))) {
812
+ await appendLocalTextFile("", dataPath)
813
+ }
814
+
815
+ const stat = await tryStat(dataPath)
816
+
817
+ manifest = {
818
+ ...manifest,
819
+ downloaded_at: isoSecondsUTC(),
820
+ bytes: stat?.size ?? manifest.bytes,
821
+ sha256: await sha256File(dataPath),
822
+ complete: true,
823
+ }
824
+ }
825
+
826
+ await writeManifest(manifestPath, manifest)
827
+
828
+ return manifest
829
+ }
830
+
831
+ /**
832
+ * What a registered `mailwoman corpus fetch` entry needs to run one service's harvest.
833
+ */
834
+ export interface RunWFSHarvestOptions {
835
+ /**
836
+ * The slug the harvest is written under and reported by, which matches the adapter's own id.
837
+ */
838
+ slug: string
839
+
840
+ /**
841
+ * Where the harvest directory sits, as the fetch registry hands it over.
842
+ */
843
+ outRoot: (segment: string) => PathBuilderLike
844
+
845
+ /**
846
+ * The data file inside the harvest directory, which is also the adapter's `inputPath`.
847
+ */
848
+ filename: string
849
+
850
+ /**
851
+ * What a stored manifest has to agree with before its harvest counts as current.
852
+ */
853
+ expect: HarvestCurrencyExpectation
854
+
855
+ /**
856
+ * The name the client reports itself under.
857
+ */
858
+ displayName: string
859
+
860
+ /**
861
+ * The floor between two requests to one government host.
862
+ */
863
+ minRequestIntervalMs: number
864
+
865
+ /**
866
+ * Runs the harvest against a client the caller does not own.
867
+ */
868
+ harvest: (client: Pick<APIClient, "fetch">) => Promise<WFSHarvestManifest>
869
+
870
+ /**
871
+ * A client to use rather than constructing one, which a test supplies.
872
+ */
873
+ client?: Pick<APIClient, "fetch">
874
+
875
+ /**
876
+ * A page cap, which makes an incomplete harvest a success.
877
+ */
878
+ maxPages?: number
879
+ }
880
+
881
+ /**
882
+ * Runs one service's harvest and reports it as a fetch registry entry does.
883
+ *
884
+ * Estonia and Poland wrote this sequence twice: ask whether the harvest on disk is
885
+ * already current, construct a paced client unless the caller supplied one, run,
886
+ * report, and decide whether an incomplete harvest is a failure.
887
+ * A third WFS source would have written it a third time.
888
+ *
889
+ * The currency check runs before any request, so a complete harvest or a bounded
890
+ * probe that already holds its pages makes no request at all.
891
+ *
892
+ * A bounded run stops short by instruction rather than by failure, so a page cap the caller
893
+ * asked for reads as a success while an incomplete harvest without one reads as a failure.
894
+ */
895
+ export async function runWFSHarvest(
896
+ options: RunWFSHarvestOptions,
897
+ report?: (line: string) => void
898
+ ): Promise<FetchSummary> {
899
+ report?.(`=== ${options.slug}`)
900
+
901
+ const destination = options.outRoot(options.slug)
902
+
903
+ const current = await readCurrentHarvest({
904
+ outputDir: destination,
905
+ filename: options.filename,
906
+ context: options.slug,
907
+ expect: options.expect,
908
+ maxPages: options.maxPages,
909
+ })
910
+
911
+ if (current) {
912
+ report?.(
913
+ ` ✓ Already harvested: ${current.features_written} features over ${current.pages.length} pages — no request made.`
914
+ )
915
+
916
+ return { fetched: 0, skipped: 1, failed: 0, failedCodes: [] }
917
+ }
918
+
919
+ let manifest: WFSHarvestManifest
920
+
921
+ if (options.client) {
922
+ manifest = await options.harvest(options.client)
923
+ } else {
924
+ // Bounded retry, because a harvest is many requests and one 5xx would otherwise end the run.
925
+ await using client = new APIClient({
926
+ displayName: options.displayName,
927
+ minRequestIntervalMs: options.minRequestIntervalMs,
928
+ retry: true,
929
+ })
930
+
931
+ manifest = await options.harvest(client)
932
+ }
933
+
934
+ report?.(
935
+ ` ${manifest.complete ? "✓" : "partial:"} ${manifest.features_written} features over ${manifest.pages.length} pages, ${manifest.bytes} bytes`
936
+ )
937
+
938
+ const bounded = options.maxPages !== undefined && manifest.pages.length >= options.maxPages
939
+
940
+ return manifest.complete || bounded
941
+ ? { fetched: 1, skipped: 0, failed: 0, failedCodes: [] }
942
+ : { fetched: 0, skipped: 0, failed: 1, failedCodes: [options.slug] }
943
+ }