@mailwoman/corpus 8.6.0 → 9.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 (497) hide show
  1. package/README.md +2 -2
  2. package/data/PROVENANCE.md +214 -0
  3. package/data/sub-venue-lexicon.json +18269 -0
  4. package/out/src/adapters/ban/adapter.d.ts +5 -4
  5. package/out/src/adapters/ban/adapter.d.ts.map +1 -1
  6. package/out/src/adapters/ban/adapter.js +62 -69
  7. package/out/src/adapters/ban/adapter.js.map +1 -1
  8. package/out/src/adapters/ban/street-decompose.d.ts.map +1 -1
  9. package/out/src/adapters/ban/street-decompose.js +18 -25
  10. package/out/src/adapters/ban/street-decompose.js.map +1 -1
  11. package/out/src/adapters/fcc-bdc/adapter.d.ts +1 -7
  12. package/out/src/adapters/fcc-bdc/adapter.d.ts.map +1 -1
  13. package/out/src/adapters/fcc-bdc/adapter.js +4 -26
  14. package/out/src/adapters/fcc-bdc/adapter.js.map +1 -1
  15. package/out/src/adapters/geonames/adapter.d.ts +1 -1
  16. package/out/src/adapters/geonames/adapter.d.ts.map +1 -1
  17. package/out/src/adapters/geonames/adapter.js +72 -78
  18. package/out/src/adapters/geonames/adapter.js.map +1 -1
  19. package/out/src/adapters/geonames-postal/adapter.d.ts +1 -1
  20. package/out/src/adapters/geonames-postal/adapter.d.ts.map +1 -1
  21. package/out/src/adapters/geonames-postal/adapter.js +46 -51
  22. package/out/src/adapters/geonames-postal/adapter.js.map +1 -1
  23. package/out/src/adapters/gnaf/adapter.d.ts +1 -1
  24. package/out/src/adapters/gnaf/adapter.d.ts.map +1 -1
  25. package/out/src/adapters/gnaf/adapter.js +6 -9
  26. package/out/src/adapters/gnaf/adapter.js.map +1 -1
  27. package/out/src/adapters/gnaf/assemble.d.ts.map +1 -1
  28. package/out/src/adapters/gnaf/assemble.js +7 -12
  29. package/out/src/adapters/gnaf/assemble.js.map +1 -1
  30. package/out/src/adapters/index.d.ts +1 -1
  31. package/out/src/adapters/index.d.ts.map +1 -1
  32. package/out/src/adapters/index.js +1 -1
  33. package/out/src/adapters/index.js.map +1 -1
  34. package/out/src/adapters/openaddresses/adapter.d.ts +1 -1
  35. package/out/src/adapters/openaddresses/adapter.d.ts.map +1 -1
  36. package/out/src/adapters/openaddresses/adapter.js +5 -10
  37. package/out/src/adapters/openaddresses/adapter.js.map +1 -1
  38. package/out/src/adapters/overture/adapter.d.ts +1 -1
  39. package/out/src/adapters/overture/adapter.d.ts.map +1 -1
  40. package/out/src/adapters/overture/adapter.js +5 -9
  41. package/out/src/adapters/overture/adapter.js.map +1 -1
  42. package/out/src/adapters/state-hi-schools/adapter.d.ts +1 -1
  43. package/out/src/adapters/state-hi-schools/adapter.d.ts.map +1 -1
  44. package/out/src/adapters/state-hi-schools/adapter.js +57 -75
  45. package/out/src/adapters/state-hi-schools/adapter.js.map +1 -1
  46. package/out/src/adapters/state-ia-contractors/adapter.d.ts +1 -1
  47. package/out/src/adapters/state-ia-contractors/adapter.d.ts.map +1 -1
  48. package/out/src/adapters/state-ia-contractors/adapter.js +60 -78
  49. package/out/src/adapters/state-ia-contractors/adapter.js.map +1 -1
  50. package/out/src/adapters/state-ny-notaries/adapter.d.ts +1 -1
  51. package/out/src/adapters/state-ny-notaries/adapter.d.ts.map +1 -1
  52. package/out/src/adapters/state-ny-notaries/adapter.js +69 -87
  53. package/out/src/adapters/state-ny-notaries/adapter.js.map +1 -1
  54. package/out/src/adapters/state-tx-notaries/adapter.d.ts +1 -1
  55. package/out/src/adapters/state-tx-notaries/adapter.d.ts.map +1 -1
  56. package/out/src/adapters/state-tx-notaries/adapter.js +71 -89
  57. package/out/src/adapters/state-tx-notaries/adapter.js.map +1 -1
  58. package/out/src/adapters/synth-po-box/adapter.d.ts +3 -3
  59. package/out/src/adapters/synth-po-box/adapter.d.ts.map +1 -1
  60. package/out/src/adapters/synth-po-box/adapter.js +10 -18
  61. package/out/src/adapters/synth-po-box/adapter.js.map +1 -1
  62. package/out/src/adapters/tiger/adapter.d.ts +1 -1
  63. package/out/src/adapters/tiger/adapter.d.ts.map +1 -1
  64. package/out/src/adapters/tiger/adapter.js +2 -2
  65. package/out/src/adapters/tiger/adapter.js.map +1 -1
  66. package/out/src/adapters/tiger/street-decompose.d.ts.map +1 -1
  67. package/out/src/adapters/tiger/street-decompose.js +18 -27
  68. package/out/src/adapters/tiger/street-decompose.js.map +1 -1
  69. package/out/src/adapters/usgov-hrsa-fqhc/adapter.d.ts +4 -4
  70. package/out/src/adapters/usgov-hrsa-fqhc/adapter.d.ts.map +1 -1
  71. package/out/src/adapters/usgov-hrsa-fqhc/adapter.js +64 -82
  72. package/out/src/adapters/usgov-hrsa-fqhc/adapter.js.map +1 -1
  73. package/out/src/adapters/usgov-imls-pls/adapter.d.ts +1 -1
  74. package/out/src/adapters/usgov-imls-pls/adapter.d.ts.map +1 -1
  75. package/out/src/adapters/usgov-imls-pls/adapter.js +62 -84
  76. package/out/src/adapters/usgov-imls-pls/adapter.js.map +1 -1
  77. package/out/src/adapters/usgov-irs-bmf/adapter.d.ts +1 -1
  78. package/out/src/adapters/usgov-irs-bmf/adapter.d.ts.map +1 -1
  79. package/out/src/adapters/usgov-irs-bmf/adapter.js +59 -66
  80. package/out/src/adapters/usgov-irs-bmf/adapter.js.map +1 -1
  81. package/out/src/adapters/usgov-nad/adapter.d.ts +1 -1
  82. package/out/src/adapters/usgov-nad/adapter.d.ts.map +1 -1
  83. package/out/src/adapters/usgov-nad/adapter.js +6 -9
  84. package/out/src/adapters/usgov-nad/adapter.js.map +1 -1
  85. package/out/src/adapters/usgov-nppes/adapter.d.ts +1 -1
  86. package/out/src/adapters/usgov-nppes/adapter.d.ts.map +1 -1
  87. package/out/src/adapters/usgov-nppes/adapter.js +60 -78
  88. package/out/src/adapters/usgov-nppes/adapter.js.map +1 -1
  89. package/out/src/adapters/usgov-samhsa-treatment-locator/adapter.d.ts +1 -1
  90. package/out/src/adapters/usgov-samhsa-treatment-locator/adapter.d.ts.map +1 -1
  91. package/out/src/adapters/usgov-samhsa-treatment-locator/adapter.js +53 -73
  92. package/out/src/adapters/usgov-samhsa-treatment-locator/adapter.js.map +1 -1
  93. package/out/src/{adapter.d.ts → adapters/utils/index.d.ts} +43 -2
  94. package/out/src/adapters/utils/index.d.ts.map +1 -0
  95. package/out/src/{adapter.js → adapters/utils/index.js} +47 -2
  96. package/out/src/adapters/utils/index.js.map +1 -0
  97. package/out/src/adapters/wof-admin-jp/adapter.d.ts +1 -1
  98. package/out/src/adapters/wof-admin-jp/adapter.d.ts.map +1 -1
  99. package/out/src/adapters/wof-admin-jp/adapter.js +24 -6
  100. package/out/src/adapters/wof-admin-jp/adapter.js.map +1 -1
  101. package/out/src/adapters/wof-admin-json/adapter.d.ts +2 -2
  102. package/out/src/adapters/wof-admin-json/adapter.d.ts.map +1 -1
  103. package/out/src/adapters/wof-admin-json/adapter.js +2 -2
  104. package/out/src/adapters/wof-admin-json/adapter.js.map +1 -1
  105. package/out/src/adapters/wof-postalcode-json/adapter.d.ts +2 -2
  106. package/out/src/adapters/wof-postalcode-json/adapter.d.ts.map +1 -1
  107. package/out/src/adapters/wof-postalcode-json/adapter.js +2 -2
  108. package/out/src/adapters/wof-postalcode-json/adapter.js.map +1 -1
  109. package/out/src/build.d.ts +3 -4
  110. package/out/src/build.d.ts.map +1 -1
  111. package/out/src/build.js +6 -8
  112. package/out/src/build.js.map +1 -1
  113. package/out/src/index.d.ts +3 -17
  114. package/out/src/index.d.ts.map +1 -1
  115. package/out/src/index.js +3 -17
  116. package/out/src/index.js.map +1 -1
  117. package/out/src/name-prone-us-suffixes.d.ts +12 -0
  118. package/out/src/name-prone-us-suffixes.d.ts.map +1 -0
  119. package/out/src/name-prone-us-suffixes.js +12 -0
  120. package/out/src/name-prone-us-suffixes.js.map +1 -0
  121. package/out/src/parquet-wrapper/reader.d.ts +8 -0
  122. package/out/src/parquet-wrapper/reader.d.ts.map +1 -1
  123. package/out/src/parquet-wrapper/reader.js +16 -0
  124. package/out/src/parquet-wrapper/reader.js.map +1 -1
  125. package/out/src/parquet-wrapper/schema.d.ts +4 -0
  126. package/out/src/parquet-wrapper/schema.d.ts.map +1 -1
  127. package/out/src/parquet-wrapper/schema.js.map +1 -1
  128. package/out/src/runner.d.ts +2 -2
  129. package/out/src/runner.d.ts.map +1 -1
  130. package/out/src/runner.js +1 -1
  131. package/out/src/runner.js.map +1 -1
  132. package/out/src/shard-recipes/anchor-absorption.d.ts.map +1 -1
  133. package/out/src/shard-recipes/anchor-absorption.js +5 -4
  134. package/out/src/shard-recipes/anchor-absorption.js.map +1 -1
  135. package/out/src/shard-recipes/boundary-stress.d.ts.map +1 -1
  136. package/out/src/shard-recipes/boundary-stress.js +2 -2
  137. package/out/src/shard-recipes/boundary-stress.js.map +1 -1
  138. package/out/src/shard-recipes/country-balanced.d.ts.map +1 -1
  139. package/out/src/shard-recipes/country-balanced.js +75 -75
  140. package/out/src/shard-recipes/country-balanced.js.map +1 -1
  141. package/out/src/shard-recipes/fr-admin-split.js +2 -2
  142. package/out/src/shard-recipes/fr-admin-split.js.map +1 -1
  143. package/out/src/shard-recipes/fr-fragment.d.ts.map +1 -1
  144. package/out/src/shard-recipes/fr-fragment.js +8 -5
  145. package/out/src/shard-recipes/fr-fragment.js.map +1 -1
  146. package/out/src/shard-recipes/fr-lieudit.js +2 -2
  147. package/out/src/shard-recipes/fr-lieudit.js.map +1 -1
  148. package/out/src/shard-recipes/fr-order.d.ts.map +1 -1
  149. package/out/src/shard-recipes/fr-order.js +18 -72
  150. package/out/src/shard-recipes/fr-order.js.map +1 -1
  151. package/out/src/shard-recipes/german.d.ts.map +1 -1
  152. package/out/src/shard-recipes/german.js +17 -70
  153. package/out/src/shard-recipes/german.js.map +1 -1
  154. package/out/src/shard-recipes/house-venue.d.ts.map +1 -1
  155. package/out/src/shard-recipes/house-venue.js +1 -1
  156. package/out/src/shard-recipes/house-venue.js.map +1 -1
  157. package/out/src/shard-recipes/index.d.ts.map +1 -1
  158. package/out/src/shard-recipes/index.js +4 -1
  159. package/out/src/shard-recipes/index.js.map +1 -1
  160. package/out/src/shard-recipes/intersection.d.ts +2 -2
  161. package/out/src/shard-recipes/intersection.d.ts.map +1 -1
  162. package/out/src/shard-recipes/intersection.js +28 -72
  163. package/out/src/shard-recipes/intersection.js.map +1 -1
  164. package/out/src/shard-recipes/locale.d.ts +5 -5
  165. package/out/src/shard-recipes/locale.d.ts.map +1 -1
  166. package/out/src/shard-recipes/locale.js +25 -35
  167. package/out/src/shard-recipes/locale.js.map +1 -1
  168. package/out/src/shard-recipes/no-fragment.d.ts.map +1 -1
  169. package/out/src/shard-recipes/no-fragment.js +8 -5
  170. package/out/src/shard-recipes/no-fragment.js.map +1 -1
  171. package/out/src/shard-recipes/no-street-led.d.ts.map +1 -1
  172. package/out/src/shard-recipes/no-street-led.js +8 -5
  173. package/out/src/shard-recipes/no-street-led.js.map +1 -1
  174. package/out/src/shard-recipes/no-street.d.ts.map +1 -1
  175. package/out/src/shard-recipes/no-street.js +1 -1
  176. package/out/src/shard-recipes/no-street.js.map +1 -1
  177. package/out/src/shard-recipes/po-box-cedex.d.ts +3 -3
  178. package/out/src/shard-recipes/po-box-cedex.d.ts.map +1 -1
  179. package/out/src/shard-recipes/po-box-cedex.js +101 -127
  180. package/out/src/shard-recipes/po-box-cedex.js.map +1 -1
  181. package/out/src/shard-recipes/po-box.d.ts.map +1 -1
  182. package/out/src/shard-recipes/po-box.js +1 -1
  183. package/out/src/shard-recipes/po-box.js.map +1 -1
  184. package/out/src/shard-recipes/scaffold.d.ts +58 -9
  185. package/out/src/shard-recipes/scaffold.d.ts.map +1 -1
  186. package/out/src/shard-recipes/scaffold.js +87 -29
  187. package/out/src/shard-recipes/scaffold.js.map +1 -1
  188. package/out/src/shard-recipes/street-affix.d.ts +54 -0
  189. package/out/src/shard-recipes/street-affix.d.ts.map +1 -1
  190. package/out/src/shard-recipes/street-affix.js +253 -111
  191. package/out/src/shard-recipes/street-affix.js.map +1 -1
  192. package/out/src/shard-recipes/street-bare.d.ts.map +1 -1
  193. package/out/src/shard-recipes/street-bare.js +3 -3
  194. package/out/src/shard-recipes/street-bare.js.map +1 -1
  195. package/out/src/shard-recipes/street.d.ts.map +1 -1
  196. package/out/src/shard-recipes/street.js +2 -2
  197. package/out/src/shard-recipes/street.js.map +1 -1
  198. package/out/src/shard-recipes/sub-venue-sources.d.ts +228 -0
  199. package/out/src/shard-recipes/sub-venue-sources.d.ts.map +1 -0
  200. package/out/src/shard-recipes/sub-venue-sources.js +664 -0
  201. package/out/src/shard-recipes/sub-venue-sources.js.map +1 -0
  202. package/out/src/shard-recipes/sub-venue.d.ts +269 -0
  203. package/out/src/shard-recipes/sub-venue.d.ts.map +1 -0
  204. package/out/src/shard-recipes/sub-venue.js +709 -0
  205. package/out/src/shard-recipes/sub-venue.js.map +1 -0
  206. package/out/src/shard-recipes/unit.d.ts +1 -1
  207. package/out/src/shard-recipes/unit.d.ts.map +1 -1
  208. package/out/src/shard-recipes/unit.js +26 -74
  209. package/out/src/shard-recipes/unit.js.map +1 -1
  210. package/out/src/{synthesize-anchor-absorption.d.ts → synthesizers/anchor-absorption.d.ts} +1 -1
  211. package/out/src/synthesizers/anchor-absorption.d.ts.map +1 -0
  212. package/out/src/{synthesize-anchor-absorption.js → synthesizers/anchor-absorption.js} +1 -1
  213. package/out/src/synthesizers/anchor-absorption.js.map +1 -0
  214. package/out/src/{synthesize-boundary-stress.d.ts → synthesizers/boundary-stress.d.ts} +3 -3
  215. package/out/src/synthesizers/boundary-stress.d.ts.map +1 -0
  216. package/out/src/{synthesize-boundary-stress.js → synthesizers/boundary-stress.js} +2 -2
  217. package/out/src/synthesizers/boundary-stress.js.map +1 -0
  218. package/out/src/{synthesize-german.d.ts → synthesizers/german.d.ts} +2 -2
  219. package/out/src/synthesizers/german.d.ts.map +1 -0
  220. package/out/src/{synthesize-german.js → synthesizers/german.js} +2 -2
  221. package/out/src/synthesizers/german.js.map +1 -0
  222. package/out/src/{synthesize-house-venue.d.ts → synthesizers/house-venue.d.ts} +4 -4
  223. package/out/src/synthesizers/house-venue.d.ts.map +1 -0
  224. package/out/src/{synthesize-house-venue.js → synthesizers/house-venue.js} +4 -4
  225. package/out/src/synthesizers/house-venue.js.map +1 -0
  226. package/out/src/{synthesize-intersection.d.ts → synthesizers/intersection.d.ts} +2 -2
  227. package/out/src/synthesizers/intersection.d.ts.map +1 -0
  228. package/out/src/{synthesize-intersection.js → synthesizers/intersection.js} +1 -1
  229. package/out/src/synthesizers/intersection.js.map +1 -0
  230. package/out/src/{synthesize-no-street.d.ts → synthesizers/no-street.d.ts} +3 -3
  231. package/out/src/synthesizers/no-street.d.ts.map +1 -0
  232. package/out/src/{synthesize-no-street.js → synthesizers/no-street.js} +2 -2
  233. package/out/src/synthesizers/no-street.js.map +1 -0
  234. package/out/src/{synthesize-po-box.d.ts → synthesizers/po-box.d.ts} +2 -2
  235. package/out/src/synthesizers/po-box.d.ts.map +1 -0
  236. package/out/src/{synthesize-po-box.js → synthesizers/po-box.js} +1 -1
  237. package/out/src/synthesizers/po-box.js.map +1 -0
  238. package/out/src/{synthesize-street.d.ts → synthesizers/street.d.ts} +2 -2
  239. package/out/src/synthesizers/street.d.ts.map +1 -0
  240. package/out/src/{synthesize-street.js → synthesizers/street.js} +2 -2
  241. package/out/src/synthesizers/street.js.map +1 -0
  242. package/out/src/{synthesize.d.ts → synthesizers/utils.d.ts} +3 -3
  243. package/out/src/synthesizers/utils.d.ts.map +1 -0
  244. package/out/src/{synthesize.js → synthesizers/utils.js} +4 -15
  245. package/out/src/synthesizers/utils.js.map +1 -0
  246. package/out/src/tools/align-shard.d.ts.map +1 -1
  247. package/out/src/tools/align-shard.js +4 -8
  248. package/out/src/tools/align-shard.js.map +1 -1
  249. package/out/src/tools/audit.d.ts.map +1 -1
  250. package/out/src/tools/audit.js +4 -4
  251. package/out/src/tools/audit.js.map +1 -1
  252. package/out/src/tools/corpus-stats.d.ts +2 -2
  253. package/out/src/tools/corpus-stats.d.ts.map +1 -1
  254. package/out/src/tools/corpus-stats.js +18 -31
  255. package/out/src/tools/corpus-stats.js.map +1 -1
  256. package/out/src/tools/fetch/download.d.ts.map +1 -1
  257. package/out/src/tools/fetch/download.js +5 -6
  258. package/out/src/tools/fetch/download.js.map +1 -1
  259. package/out/src/tools/fetch/imls-pls.d.ts.map +1 -1
  260. package/out/src/tools/fetch/imls-pls.js +3 -15
  261. package/out/src/tools/fetch/imls-pls.js.map +1 -1
  262. package/out/src/tools/fetch/index.d.ts +14 -1
  263. package/out/src/tools/fetch/index.d.ts.map +1 -1
  264. package/out/src/tools/fetch/index.js +14 -1
  265. package/out/src/tools/fetch/index.js.map +1 -1
  266. package/out/src/tools/fetch/nad.d.ts +1 -1
  267. package/out/src/tools/fetch/nad.js +1 -1
  268. package/out/src/tools/fetch/nppes.d.ts.map +1 -1
  269. package/out/src/tools/fetch/nppes.js +8 -14
  270. package/out/src/tools/fetch/nppes.js.map +1 -1
  271. package/out/src/tools/fetch/openaddresses.d.ts +1 -1
  272. package/out/src/tools/fetch/openaddresses.js +1 -1
  273. package/out/src/tools/fetch/ourairports.d.ts +45 -0
  274. package/out/src/tools/fetch/ourairports.d.ts.map +1 -0
  275. package/out/src/tools/fetch/ourairports.js +123 -0
  276. package/out/src/tools/fetch/ourairports.js.map +1 -0
  277. package/out/src/tools/fetch/wikidata-subvenue.d.ts +171 -0
  278. package/out/src/tools/fetch/wikidata-subvenue.d.ts.map +1 -0
  279. package/out/src/tools/fetch/wikidata-subvenue.js +275 -0
  280. package/out/src/tools/fetch/wikidata-subvenue.js.map +1 -0
  281. package/out/src/tools/golden-expand.d.ts.map +1 -1
  282. package/out/src/tools/golden-expand.js +18 -16
  283. package/out/src/tools/golden-expand.js.map +1 -1
  284. package/out/src/tools/golden-promote.d.ts.map +1 -1
  285. package/out/src/tools/golden-promote.js +12 -6
  286. package/out/src/tools/golden-promote.js.map +1 -1
  287. package/out/src/tools/golden-relabel-street.d.ts +196 -0
  288. package/out/src/tools/golden-relabel-street.d.ts.map +1 -0
  289. package/out/src/tools/golden-relabel-street.js +440 -0
  290. package/out/src/tools/golden-relabel-street.js.map +1 -0
  291. package/out/src/tools/index.d.ts +4 -0
  292. package/out/src/tools/index.d.ts.map +1 -1
  293. package/out/src/tools/index.js +4 -0
  294. package/out/src/tools/index.js.map +1 -1
  295. package/out/src/tools/jsonl-to-parquet.d.ts.map +1 -1
  296. package/out/src/tools/jsonl-to-parquet.js +3 -2
  297. package/out/src/tools/jsonl-to-parquet.js.map +1 -1
  298. package/out/src/tools/lint-shard-vocab.d.ts.map +1 -1
  299. package/out/src/tools/lint-shard-vocab.js +3 -2
  300. package/out/src/tools/lint-shard-vocab.js.map +1 -1
  301. package/out/src/tools/lint-shard.d.ts +3 -3
  302. package/out/src/tools/lint-shard.d.ts.map +1 -1
  303. package/out/src/tools/lint-shard.js +23 -32
  304. package/out/src/tools/lint-shard.js.map +1 -1
  305. package/out/src/tools/overlay-manifest.d.ts.map +1 -1
  306. package/out/src/tools/overlay-manifest.js +2 -1
  307. package/out/src/tools/overlay-manifest.js.map +1 -1
  308. package/out/src/tools/overture-subvenue.d.ts +112 -0
  309. package/out/src/tools/overture-subvenue.d.ts.map +1 -0
  310. package/out/src/tools/overture-subvenue.js +144 -0
  311. package/out/src/tools/overture-subvenue.js.map +1 -0
  312. package/out/src/tools/shard-kryptonite.d.ts +1 -1
  313. package/out/src/tools/shard-kryptonite.d.ts.map +1 -1
  314. package/out/src/tools/shard-kryptonite.js +6 -6
  315. package/out/src/tools/shard-kryptonite.js.map +1 -1
  316. package/out/src/tools/shard-translit.d.ts +6 -3
  317. package/out/src/tools/shard-translit.d.ts.map +1 -1
  318. package/out/src/tools/shard-translit.js +9 -8
  319. package/out/src/tools/shard-translit.js.map +1 -1
  320. package/out/src/tools/sub-venue-lexicon.d.ts +507 -0
  321. package/out/src/tools/sub-venue-lexicon.d.ts.map +1 -0
  322. package/out/src/tools/sub-venue-lexicon.js +817 -0
  323. package/out/src/tools/sub-venue-lexicon.js.map +1 -0
  324. package/out/src/tools/sub-venue-promotions.d.ts +94 -0
  325. package/out/src/tools/sub-venue-promotions.d.ts.map +1 -0
  326. package/out/src/tools/sub-venue-promotions.js +266 -0
  327. package/out/src/tools/sub-venue-promotions.js.map +1 -0
  328. package/out/src/{align.d.ts → utils/align.d.ts} +1 -1
  329. package/out/src/utils/align.d.ts.map +1 -0
  330. package/out/src/utils/align.js.map +1 -0
  331. package/out/src/{golden.d.ts → utils/golden.d.ts} +5 -0
  332. package/out/src/utils/golden.d.ts.map +1 -0
  333. package/out/src/{golden.js → utils/golden.js} +24 -10
  334. package/out/src/utils/golden.js.map +1 -0
  335. package/out/src/utils/index.d.ts +14 -0
  336. package/out/src/utils/index.d.ts.map +1 -0
  337. package/out/src/utils/index.js +14 -0
  338. package/out/src/utils/index.js.map +1 -0
  339. package/out/src/utils/license.d.ts.map +1 -0
  340. package/out/src/utils/license.js.map +1 -0
  341. package/out/src/{parquet.d.ts → utils/parquet.d.ts} +2 -2
  342. package/out/src/utils/parquet.d.ts.map +1 -0
  343. package/out/src/{parquet.js → utils/parquet.js} +3 -15
  344. package/out/src/utils/parquet.js.map +1 -0
  345. package/out/src/{split.d.ts → utils/split.d.ts} +8 -1
  346. package/out/src/utils/split.d.ts.map +1 -0
  347. package/out/src/{split.js → utils/split.js} +7 -0
  348. package/out/src/utils/split.js.map +1 -0
  349. package/out/src/utils/tokenize.d.ts.map +1 -0
  350. package/out/src/utils/tokenize.js.map +1 -0
  351. package/out/src/{wof-json.d.ts → utils/wof-json.d.ts} +2 -2
  352. package/out/src/utils/wof-json.d.ts.map +1 -0
  353. package/out/src/{wof-json.js → utils/wof-json.js} +5 -8
  354. package/out/src/utils/wof-json.js.map +1 -0
  355. package/package.json +66 -20
  356. package/src/adapters/ban/adapter.ts +58 -68
  357. package/src/adapters/ban/street-decompose.ts +17 -25
  358. package/src/adapters/fcc-bdc/adapter.ts +5 -36
  359. package/src/adapters/geonames/adapter.ts +67 -76
  360. package/src/adapters/geonames-postal/adapter.ts +45 -54
  361. package/src/adapters/gnaf/adapter.ts +7 -11
  362. package/src/adapters/gnaf/assemble.ts +7 -11
  363. package/src/adapters/index.ts +3 -2
  364. package/src/adapters/openaddresses/adapter.ts +6 -12
  365. package/src/adapters/overture/adapter.ts +6 -10
  366. package/src/adapters/state-hi-schools/adapter.ts +53 -77
  367. package/src/adapters/state-ia-contractors/adapter.ts +55 -80
  368. package/src/adapters/state-ny-notaries/adapter.ts +64 -89
  369. package/src/adapters/state-tx-notaries/adapter.ts +63 -88
  370. package/src/adapters/synth-po-box/adapter.ts +12 -23
  371. package/src/adapters/tiger/adapter.ts +4 -3
  372. package/src/adapters/tiger/street-decompose.ts +21 -31
  373. package/src/adapters/usgov-hrsa-fqhc/adapter.ts +64 -88
  374. package/src/adapters/usgov-imls-pls/adapter.ts +57 -86
  375. package/src/adapters/usgov-irs-bmf/adapter.ts +55 -66
  376. package/src/adapters/usgov-nad/adapter.ts +7 -11
  377. package/src/adapters/usgov-nppes/adapter.ts +54 -79
  378. package/src/adapters/usgov-samhsa-treatment-locator/adapter.ts +48 -75
  379. package/src/{adapter.ts → adapters/utils/index.ts} +59 -3
  380. package/src/adapters/wof-admin-jp/adapter.ts +35 -9
  381. package/src/adapters/wof-admin-json/adapter.ts +3 -4
  382. package/src/adapters/wof-postalcode-json/adapter.ts +3 -4
  383. package/src/build.ts +12 -11
  384. package/src/index.ts +3 -17
  385. package/src/name-prone-us-suffixes.ts +12 -0
  386. package/src/parquet-wrapper/reader.ts +19 -0
  387. package/src/parquet-wrapper/schema.ts +4 -0
  388. package/src/runner.ts +7 -2
  389. package/src/shard-recipes/anchor-absorption.ts +5 -4
  390. package/src/shard-recipes/boundary-stress.ts +6 -2
  391. package/src/shard-recipes/country-balanced.ts +77 -91
  392. package/src/shard-recipes/fr-admin-split.ts +3 -3
  393. package/src/shard-recipes/fr-fragment.ts +10 -7
  394. package/src/shard-recipes/fr-lieudit.ts +3 -3
  395. package/src/shard-recipes/fr-order.ts +18 -83
  396. package/src/shard-recipes/german.ts +17 -80
  397. package/src/shard-recipes/house-venue.ts +2 -1
  398. package/src/shard-recipes/index.ts +4 -1
  399. package/src/shard-recipes/intersection.ts +37 -74
  400. package/src/shard-recipes/locale.ts +31 -39
  401. package/src/shard-recipes/no-fragment.ts +10 -7
  402. package/src/shard-recipes/no-street-led.ts +10 -7
  403. package/src/shard-recipes/no-street.ts +2 -1
  404. package/src/shard-recipes/po-box-cedex.ts +127 -161
  405. package/src/shard-recipes/po-box.ts +6 -1
  406. package/src/shard-recipes/scaffold.ts +125 -27
  407. package/src/shard-recipes/street-affix.ts +335 -134
  408. package/src/shard-recipes/street-bare.ts +4 -3
  409. package/src/shard-recipes/street.ts +3 -2
  410. package/src/shard-recipes/sub-venue-sources.ts +895 -0
  411. package/src/shard-recipes/sub-venue.ts +982 -0
  412. package/src/shard-recipes/unit.ts +27 -85
  413. package/src/{synthesize-boundary-stress.ts → synthesizers/boundary-stress.ts} +2 -2
  414. package/src/{synthesize-german.ts → synthesizers/german.ts} +2 -2
  415. package/src/{synthesize-house-venue.ts → synthesizers/house-venue.ts} +4 -4
  416. package/src/{synthesize-intersection.ts → synthesizers/intersection.ts} +1 -1
  417. package/src/{synthesize-no-street.ts → synthesizers/no-street.ts} +2 -2
  418. package/src/{synthesize-po-box.ts → synthesizers/po-box.ts} +1 -1
  419. package/src/{synthesize-street.ts → synthesizers/street.ts} +2 -2
  420. package/src/{synthesize.ts → synthesizers/utils.ts} +4 -18
  421. package/src/tools/align-shard.ts +4 -7
  422. package/src/tools/audit.ts +6 -5
  423. package/src/tools/corpus-stats.ts +25 -33
  424. package/src/tools/fetch/download.ts +7 -5
  425. package/src/tools/fetch/imls-pls.ts +4 -18
  426. package/src/tools/fetch/index.ts +14 -1
  427. package/src/tools/fetch/nad.ts +1 -1
  428. package/src/tools/fetch/nppes.ts +9 -16
  429. package/src/tools/fetch/openaddresses.ts +1 -1
  430. package/src/tools/fetch/ourairports.ts +166 -0
  431. package/src/tools/fetch/wikidata-subvenue.ts +386 -0
  432. package/src/tools/golden-expand.ts +18 -13
  433. package/src/tools/golden-promote.ts +15 -6
  434. package/src/tools/golden-relabel-street.ts +685 -0
  435. package/src/tools/index.ts +4 -0
  436. package/src/tools/jsonl-to-parquet.ts +3 -2
  437. package/src/tools/lint-shard-vocab.ts +3 -2
  438. package/src/tools/lint-shard.ts +33 -36
  439. package/src/tools/overlay-manifest.ts +2 -1
  440. package/src/tools/overture-subvenue.ts +215 -0
  441. package/src/tools/shard-kryptonite.ts +8 -9
  442. package/src/tools/shard-translit.ts +22 -11
  443. package/src/tools/sub-venue-lexicon.ts +1250 -0
  444. package/src/tools/sub-venue-promotions.ts +330 -0
  445. package/src/{align.ts → utils/align.ts} +1 -1
  446. package/src/{golden.ts → utils/golden.ts} +25 -11
  447. package/src/utils/index.ts +14 -0
  448. package/src/{parquet.ts → utils/parquet.ts} +5 -19
  449. package/src/{split.ts → utils/split.ts} +8 -2
  450. package/src/{wof-json.ts → utils/wof-json.ts} +5 -8
  451. package/out/src/adapter.d.ts.map +0 -1
  452. package/out/src/adapter.js.map +0 -1
  453. package/out/src/align.d.ts.map +0 -1
  454. package/out/src/align.js.map +0 -1
  455. package/out/src/format.d.ts +0 -14
  456. package/out/src/format.d.ts.map +0 -1
  457. package/out/src/format.js +0 -14
  458. package/out/src/format.js.map +0 -1
  459. package/out/src/golden.d.ts.map +0 -1
  460. package/out/src/golden.js.map +0 -1
  461. package/out/src/license.d.ts.map +0 -1
  462. package/out/src/license.js.map +0 -1
  463. package/out/src/parquet.d.ts.map +0 -1
  464. package/out/src/parquet.js.map +0 -1
  465. package/out/src/split.d.ts.map +0 -1
  466. package/out/src/split.js.map +0 -1
  467. package/out/src/synthesize-anchor-absorption.d.ts.map +0 -1
  468. package/out/src/synthesize-anchor-absorption.js.map +0 -1
  469. package/out/src/synthesize-boundary-stress.d.ts.map +0 -1
  470. package/out/src/synthesize-boundary-stress.js.map +0 -1
  471. package/out/src/synthesize-german.d.ts.map +0 -1
  472. package/out/src/synthesize-german.js.map +0 -1
  473. package/out/src/synthesize-house-venue.d.ts.map +0 -1
  474. package/out/src/synthesize-house-venue.js.map +0 -1
  475. package/out/src/synthesize-intersection.d.ts.map +0 -1
  476. package/out/src/synthesize-intersection.js.map +0 -1
  477. package/out/src/synthesize-no-street.d.ts.map +0 -1
  478. package/out/src/synthesize-no-street.js.map +0 -1
  479. package/out/src/synthesize-po-box.d.ts.map +0 -1
  480. package/out/src/synthesize-po-box.js.map +0 -1
  481. package/out/src/synthesize-street.d.ts.map +0 -1
  482. package/out/src/synthesize-street.js.map +0 -1
  483. package/out/src/synthesize.d.ts.map +0 -1
  484. package/out/src/synthesize.js.map +0 -1
  485. package/out/src/tokenize.d.ts.map +0 -1
  486. package/out/src/tokenize.js.map +0 -1
  487. package/out/src/wof-json.d.ts.map +0 -1
  488. package/out/src/wof-json.js.map +0 -1
  489. package/src/format.ts +0 -14
  490. /package/out/src/{align.js → utils/align.js} +0 -0
  491. /package/out/src/{license.d.ts → utils/license.d.ts} +0 -0
  492. /package/out/src/{license.js → utils/license.js} +0 -0
  493. /package/out/src/{tokenize.d.ts → utils/tokenize.d.ts} +0 -0
  494. /package/out/src/{tokenize.js → utils/tokenize.js} +0 -0
  495. /package/src/{synthesize-anchor-absorption.ts → synthesizers/anchor-absorption.ts} +0 -0
  496. /package/src/{license.ts → utils/license.ts} +0 -0
  497. /package/src/{tokenize.ts → utils/tokenize.ts} +0 -0
@@ -18,14 +18,11 @@
18
18
  * License: stamped `"Public Domain"` per IMLS federal government distribution terms.
19
19
  */
20
20
 
21
- import { createReadStream } from "node:fs"
22
-
23
- import { parse as csvParse } from "csv-parse"
24
-
25
- import { stableSourceID } from "../../adapter.ts"
26
- import { lookupStateAbbreviation } from "../../codex/us-fips-state.ts"
27
- import { reconcileComponents } from "../../format.ts"
28
- import type { AdapterOptions, CanonicalRow, CorpusAdapter } from "../../types.ts"
21
+ import { splitStreetLine, stableSourceID } from "@mailwoman/corpus/adapters/utils"
22
+ import { lookupStateAbbreviation } from "@mailwoman/corpus/codex/us-fips-state"
23
+ import type { AdapterOptions, CanonicalRow, CorpusAdapter } from "@mailwoman/corpus/types"
24
+ import { reconcileComponents } from "@mailwoman/formatter"
25
+ import { CSVSpliterator } from "spliterator"
29
26
 
30
27
  /**
31
28
  * Registry id for this adapter. Stamped into every row it emits, so a corpus record can be traced back to the dataset
@@ -38,8 +35,6 @@ export const USGOV_IMLS_PLS_ADAPTER_ID = "usgov-imls-pls"
38
35
  */
39
36
  export const USGOV_IMLS_PLS_DEFAULT_LICENSE = "Public Domain"
40
37
 
41
- const HOUSE_NUMBER_PREFIX = /^(\d+(?:-\d+)?[A-Za-z]?)\s+(.+)$/
42
-
43
38
  interface ImlsOutletRow {
44
39
  LIBNAME: string
45
40
  ADDRESS: string
@@ -50,17 +45,6 @@ interface ImlsOutletRow {
50
45
  FSCSKEY: string
51
46
  }
52
47
 
53
- function splitAddress(address: string): { house_number?: string; street: string } | null {
54
- const trimmed = address.trim()
55
-
56
- if (!trimmed) return null
57
- const m = HOUSE_NUMBER_PREFIX.exec(trimmed)
58
-
59
- if (m) return { house_number: m[1], street: m[2]!.trim() }
60
-
61
- return { street: trimmed }
62
- }
63
-
64
48
  export function createUsgovImlsPlsAdapter(): CorpusAdapter {
65
49
  return {
66
50
  id: USGOV_IMLS_PLS_ADAPTER_ID,
@@ -72,90 +56,77 @@ export function createUsgovImlsPlsAdapter(): CorpusAdapter {
72
56
  throw new Error(`usgov-imls-pls adapter: only US supported, got country=${opts.country}`)
73
57
  }
74
58
 
75
- const stream = createReadStream(opts.inputPath, { encoding: "utf8" })
76
-
77
- const parser = stream.pipe(
78
- csvParse({
79
- columns: true,
80
- skip_empty_lines: true,
81
- relax_quotes: true,
82
- relax_column_count: true,
83
- })
84
- )
59
+ const rows = CSVSpliterator.fromAsync(opts.inputPath, {
60
+ mode: "object",
61
+ normalizeKeys: false,
62
+ enableQuoteHandling: true,
63
+ })
85
64
 
86
65
  let emitted = 0
87
66
 
88
- try {
89
- for await (const record of parser as AsyncIterable<ImlsOutletRow>) {
90
- if (opts.signal?.aborted) break
67
+ for await (const record of rows as AsyncIterable<ImlsOutletRow>) {
68
+ if (opts.signal?.aborted) break
91
69
 
92
- if (opts.limit !== undefined && emitted >= opts.limit) break
70
+ if (opts.limit !== undefined && emitted >= opts.limit) break
93
71
 
94
- const libName = (record.LIBNAME ?? "").trim()
95
- const address = (record.ADDRESS ?? "").trim()
96
- const city = (record.CITY ?? "").trim()
97
- const zip = (record.ZIP ?? "").trim()
98
- const stateAbbr = (record.STABR ?? "").trim()
99
- const county = (record.CNTY ?? "").trim()
72
+ const libName = (record.LIBNAME ?? "").trim()
73
+ const address = (record.ADDRESS ?? "").trim()
74
+ const city = (record.CITY ?? "").trim()
75
+ const zip = (record.ZIP ?? "").trim()
76
+ const stateAbbr = (record.STABR ?? "").trim()
77
+ const county = (record.CNTY ?? "").trim()
100
78
 
101
- if (!libName || !city || !zip) continue
79
+ if (!libName || !city || !zip) continue
102
80
 
103
- const state = lookupStateAbbreviation(stateAbbr)
81
+ const state = lookupStateAbbreviation(stateAbbr)
104
82
 
105
- if (!state) continue
83
+ if (!state) continue
106
84
 
107
- const split = splitAddress(address)
85
+ const split = splitStreetLine(address)
108
86
 
109
- if (!split) continue
87
+ if (!split) continue
110
88
 
111
- const components: CanonicalRow["components"] = {
112
- venue: libName,
113
- ...(split.house_number ? { house_number: split.house_number } : {}),
114
- street: split.street,
115
- locality: city,
116
- region: state.abbreviation,
117
- postcode: zip,
118
- // #552: no subregion — US postal addresses don't surface the county, so emitting
119
- // subregion creates a phantom component with no raw-span to align to, quarantining
120
- // ~21% of rows. The county is still available in the source CSV; it just isn't
121
- // a postal-surface component here.
122
- }
123
-
124
- const streetPart = [split.house_number, split.street].filter(Boolean).join(" ").trim()
89
+ const components: CanonicalRow["components"] = {
90
+ venue: libName,
91
+ ...(split.house_number ? { house_number: split.house_number } : {}),
92
+ street: split.street,
93
+ locality: city,
94
+ region: state.abbreviation,
95
+ postcode: zip,
96
+ // #552: no subregion — US postal addresses don't surface the county, so emitting
97
+ // subregion creates a phantom component with no raw-span to align to, quarantining
98
+ // ~21% of rows. The county is still available in the source CSV; it just isn't
99
+ // a postal-surface component here.
100
+ }
125
101
 
126
- const raw = [
127
- libName,
128
- streetPart,
129
- [city, [stateAbbr, zip].filter(Boolean).join(" ")].filter(Boolean).join(", "),
130
- ]
131
- .filter(Boolean)
132
- .join(", ")
102
+ const streetPart = [split.house_number, split.street].filter(Boolean).join(" ").trim()
133
103
 
134
- const aligned = reconcileComponents(components, raw)
104
+ const raw = [libName, streetPart, [city, [stateAbbr, zip].filter(Boolean).join(" ")].filter(Boolean).join(", ")]
105
+ .filter(Boolean)
106
+ .join(", ")
135
107
 
136
- if (Object.keys(aligned).length <= 2) continue
108
+ const aligned = reconcileComponents(components, raw)
137
109
 
138
- const fscsKey = (record.FSCSKEY ?? "").trim()
110
+ if (Object.keys(aligned).length <= 2) continue
139
111
 
140
- const sourceID = fscsKey
141
- ? `${USGOV_IMLS_PLS_ADAPTER_ID}-${fscsKey}`
142
- : stableSourceID(USGOV_IMLS_PLS_ADAPTER_ID, aligned)
112
+ const fscsKey = (record.FSCSKEY ?? "").trim()
143
113
 
144
- yield {
145
- raw,
146
- components: aligned,
147
- country: "US",
148
- locale: "en-US",
149
- source: USGOV_IMLS_PLS_ADAPTER_ID,
150
- source_id: sourceID,
151
- corpus_version: "",
152
- license: USGOV_IMLS_PLS_DEFAULT_LICENSE,
153
- }
114
+ const sourceID = fscsKey
115
+ ? `${USGOV_IMLS_PLS_ADAPTER_ID}-${fscsKey}`
116
+ : stableSourceID(USGOV_IMLS_PLS_ADAPTER_ID, aligned)
154
117
 
155
- emitted++
118
+ yield {
119
+ raw,
120
+ components: aligned,
121
+ country: "US",
122
+ locale: "en-US",
123
+ source: USGOV_IMLS_PLS_ADAPTER_ID,
124
+ source_id: sourceID,
125
+ corpus_version: "",
126
+ license: USGOV_IMLS_PLS_DEFAULT_LICENSE,
156
127
  }
157
- } finally {
158
- stream.destroy()
128
+
129
+ emitted++
159
130
  }
160
131
  },
161
132
  }
@@ -19,13 +19,10 @@
19
19
  * federal).
20
20
  */
21
21
 
22
- import { createReadStream } from "node:fs"
23
-
24
- import { parse as csvParse } from "csv-parse"
25
-
26
- import { stableSourceID } from "../../adapter.ts"
27
- import { reconcileComponents } from "../../format.ts"
28
- import type { AdapterOptions, CanonicalRow, CorpusAdapter } from "../../types.ts"
22
+ import { splitStreetLine, stableSourceID } from "@mailwoman/corpus/adapters/utils"
23
+ import type { AdapterOptions, CanonicalRow, CorpusAdapter } from "@mailwoman/corpus/types"
24
+ import { reconcileComponents } from "@mailwoman/formatter"
25
+ import { CSVSpliterator } from "spliterator"
29
26
 
30
27
  /**
31
28
  * Registry id for this adapter. Stamped into every row it emits, so a corpus record can be traced back to the dataset
@@ -38,7 +35,6 @@ export const USGOV_IRS_BMF_ADAPTER_ID = "usgov-irs-bmf"
38
35
  */
39
36
  export const USGOV_IRS_BMF_DEFAULT_LICENSE = "Public Domain"
40
37
 
41
- const HOUSE_NUMBER_PREFIX = /^(\d+(?:-\d+)?[A-Za-z]?)\s+(.+)$/
42
38
  /**
43
39
  * PO box in its many written forms: "PO BOX 12", "P.O. BOX 12", "P O BOX 12", "POB 12", "BOX 12".
44
40
  */
@@ -55,18 +51,17 @@ interface IrsBmfRow {
55
51
 
56
52
  /**
57
53
  * Classify the street line into a `po_box` or a `{house_number?, street}` split.
54
+ *
55
+ * BMF mixes street addresses and PO boxes in one `STREET` column, so the PO-box shapes have to be claimed BEFORE the
56
+ * shared house-number split runs — otherwise `splitStreetLine` would hand back `"PO Box 1234"` as a plain street, which
57
+ * is correct for every other US adapter and wrong here.
58
58
  */
59
- function splitStreetLine(street: string): { po_box: string } | { house_number?: string; street: string } | null {
59
+ function splitStreetLineOrPOBox(street: string): { po_box: string } | { house_number?: string; street: string } | null {
60
60
  const trimmed = street.trim()
61
61
 
62
- if (!trimmed) return null
63
-
64
62
  if (PO_BOX.test(trimmed)) return { po_box: trimmed }
65
- const m = HOUSE_NUMBER_PREFIX.exec(trimmed)
66
-
67
- if (m) return { house_number: m[1], street: m[2]!.trim() }
68
63
 
69
- return { street: trimmed }
64
+ return splitStreetLine(trimmed)
70
65
  }
71
66
 
72
67
  function composeRaw(
@@ -93,74 +88,68 @@ export function createUsgovIrsBmfAdapter(): CorpusAdapter {
93
88
  throw new Error(`usgov-irs-bmf adapter: only US supported, got country=${opts.country}`)
94
89
  }
95
90
 
96
- const stream = createReadStream(opts.inputPath, { encoding: "utf8" })
97
-
98
- const parser = stream.pipe(
99
- csvParse({ columns: true, skip_empty_lines: true, relax_quotes: true, relax_column_count: true, trim: true })
100
- )
91
+ const rows = CSVSpliterator.fromAsync(opts.inputPath, {
92
+ mode: "object",
93
+ normalizeKeys: false,
94
+ enableQuoteHandling: true,
95
+ })
101
96
 
102
97
  let emitted = 0
103
98
 
104
- try {
105
- for await (const record of parser as AsyncIterable<IrsBmfRow>) {
106
- if (opts.signal?.aborted) break
107
-
108
- if (opts.limit !== undefined && emitted >= opts.limit) break
99
+ for await (const record of rows as AsyncIterable<IrsBmfRow>) {
100
+ if (opts.signal?.aborted) break
109
101
 
110
- const ein = (record.EIN ?? "").trim()
111
- const venue = (record.NAME ?? "").trim() || undefined
112
- const street = (record.STREET ?? "").trim()
113
- const city = (record.CITY ?? "").trim()
114
- const state = (record.STATE ?? "").trim()
115
- const zipRaw = (record.ZIP ?? "").trim()
102
+ if (opts.limit !== undefined && emitted >= opts.limit) break
116
103
 
117
- if (!city || !zipRaw) continue
118
- const postcode = zipRaw.split("-")[0]!.trim() // 5-digit; drop the optional +4
104
+ const ein = (record.EIN ?? "").trim()
105
+ const venue = (record.NAME ?? "").trim() || undefined
106
+ const street = (record.STREET ?? "").trim()
107
+ const city = (record.CITY ?? "").trim()
108
+ const state = (record.STATE ?? "").trim()
109
+ const zipRaw = (record.ZIP ?? "").trim()
119
110
 
120
- const split = splitStreetLine(street)
111
+ if (!city || !zipRaw) continue
112
+ const postcode = zipRaw.split("-")[0]!.trim() // 5-digit; drop the optional +4
121
113
 
122
- if (!split) continue
114
+ const split = splitStreetLineOrPOBox(street)
123
115
 
124
- const streetPart =
125
- "po_box" in split ? split.po_box : [split.house_number, split.street].filter(Boolean).join(" ")
116
+ if (!split) continue
126
117
 
127
- const components: CanonicalRow["components"] = {
128
- ...(venue ? { venue } : {}),
129
- ...("po_box" in split
130
- ? { po_box: split.po_box }
131
- : { ...(split.house_number ? { house_number: split.house_number } : {}), street: split.street }),
132
- locality: city,
133
- ...(state ? { region: state } : {}),
134
- postcode,
135
- }
118
+ const streetPart =
119
+ "po_box" in split ? split.po_box : [split.house_number, split.street].filter(Boolean).join(" ")
136
120
 
137
- const raw = composeRaw(venue, streetPart, city, state, postcode)
121
+ const components: CanonicalRow["components"] = {
122
+ ...(venue ? { venue } : {}),
123
+ ...("po_box" in split
124
+ ? { po_box: split.po_box }
125
+ : { ...(split.house_number ? { house_number: split.house_number } : {}), street: split.street }),
126
+ locality: city,
127
+ ...(state ? { region: state } : {}),
128
+ postcode,
129
+ }
138
130
 
139
- if (!raw) continue
131
+ const raw = composeRaw(venue, streetPart, city, state, postcode)
140
132
 
141
- const aligned = reconcileComponents(components, raw)
133
+ if (!raw) continue
142
134
 
143
- if (Object.keys(aligned).length <= 2) continue
135
+ const aligned = reconcileComponents(components, raw)
144
136
 
145
- const sourceID = ein
146
- ? `${USGOV_IRS_BMF_ADAPTER_ID}-${ein}`
147
- : stableSourceID(USGOV_IRS_BMF_ADAPTER_ID, aligned)
137
+ if (Object.keys(aligned).length <= 2) continue
148
138
 
149
- yield {
150
- raw,
151
- components: aligned,
152
- country: "US",
153
- locale: "en-US",
154
- source: USGOV_IRS_BMF_ADAPTER_ID,
155
- source_id: sourceID,
156
- corpus_version: "",
157
- license: USGOV_IRS_BMF_DEFAULT_LICENSE,
158
- }
139
+ const sourceID = ein ? `${USGOV_IRS_BMF_ADAPTER_ID}-${ein}` : stableSourceID(USGOV_IRS_BMF_ADAPTER_ID, aligned)
159
140
 
160
- emitted++
141
+ yield {
142
+ raw,
143
+ components: aligned,
144
+ country: "US",
145
+ locale: "en-US",
146
+ source: USGOV_IRS_BMF_ADAPTER_ID,
147
+ source_id: sourceID,
148
+ corpus_version: "",
149
+ license: USGOV_IRS_BMF_DEFAULT_LICENSE,
161
150
  }
162
- } finally {
163
- stream.destroy()
151
+
152
+ emitted++
164
153
  }
165
154
  },
166
155
  }
@@ -33,11 +33,11 @@
33
33
  import { readdir } from "node:fs/promises"
34
34
  import { join } from "node:path"
35
35
 
36
+ import { tryParsingJSON } from "@mailwoman/core/objects"
37
+ import type { AdapterOptions, CanonicalRow, CorpusAdapter } from "@mailwoman/corpus/types"
38
+ import { reconcileComponents } from "@mailwoman/formatter"
36
39
  import { TextSpliterator } from "spliterator"
37
40
 
38
- import { reconcileComponents } from "../../format.ts"
39
- import type { AdapterOptions, CanonicalRow, CorpusAdapter } from "../../types.ts"
40
-
41
41
  /**
42
42
  * Registry id for this adapter. Stamped into every row it emits, so a corpus record can be traced back to the dataset
43
43
  * it came from.
@@ -257,8 +257,8 @@ export function createUsgovNADAdapter(): CorpusAdapter {
257
257
  let emitted = 0
258
258
  outer: for (const shard of shards) {
259
259
  if (opts.signal?.aborted) break
260
- // TextSpliterator streams string lines; the per-line try/catch below keeps the reader
261
- // tolerant of malformed rows (skip silently), so TextSpliterator + explicit JSON.parse —
260
+ // TextSpliterator streams string lines; the per-line tryParsingJSON below keeps the reader
261
+ // tolerant of malformed rows (skip silently), so TextSpliterator + a non-throwing parse —
262
262
  // not JSONSpliterator, which would throw. The path string lets the lib own + dispose each
263
263
  // shard's file handle, including on the `break outer` early exit.
264
264
  const lines = TextSpliterator.fromAsync(join(opts.inputPath, shard))
@@ -270,13 +270,9 @@ export function createUsgovNADAdapter(): CorpusAdapter {
270
270
 
271
271
  if (!line) continue
272
272
 
273
- let record: NADRecord
273
+ const record = tryParsingJSON<NADRecord>(line)
274
274
 
275
- try {
276
- record = JSON.parse(line) as NADRecord
277
- } catch {
278
- continue // malformed line — skip silently
279
- }
275
+ if (record === null) continue // malformed line — skip silently
280
276
 
281
277
  const state = (record.State ?? "").toString().trim().toUpperCase()
282
278
 
@@ -21,14 +21,11 @@
21
21
  * License: stamped `"Public Domain"` per CMS's federal government distribution terms.
22
22
  */
23
23
 
24
- import { createReadStream } from "node:fs"
25
-
26
- import { parse as csvParse } from "csv-parse"
27
-
28
- import { stableSourceID } from "../../adapter.ts"
29
- import { lookupStateAbbreviation } from "../../codex/us-fips-state.ts"
30
- import { reconcileComponents } from "../../format.ts"
31
- import type { AdapterOptions, CanonicalRow, CorpusAdapter } from "../../types.ts"
24
+ import { splitStreetLine, stableSourceID } from "@mailwoman/corpus/adapters/utils"
25
+ import { lookupStateAbbreviation } from "@mailwoman/corpus/codex/us-fips-state"
26
+ import type { AdapterOptions, CanonicalRow, CorpusAdapter } from "@mailwoman/corpus/types"
27
+ import { reconcileComponents } from "@mailwoman/formatter"
28
+ import { CSVSpliterator } from "spliterator"
32
29
 
33
30
  /**
34
31
  * Registry id for this adapter. Stamped into every row it emits, so a corpus record can be traced back to the dataset
@@ -41,8 +38,6 @@ export const USGOV_NPPES_ADAPTER_ID = "usgov-nppes"
41
38
  */
42
39
  export const USGOV_NPPES_DEFAULT_LICENSE = "Public Domain"
43
40
 
44
- const HOUSE_NUMBER_PREFIX = /^(\d+(?:-\d+)?[A-Za-z]?)\s+(.+)$/
45
-
46
41
  interface NPPESRow {
47
42
  NPI: string
48
43
  "Entity Type Code": string
@@ -56,17 +51,6 @@ interface NPPESRow {
56
51
  "Provider Business Practice Location Address Postal Code": string
57
52
  }
58
53
 
59
- function splitAddress(address: string): { house_number?: string; street: string } | null {
60
- const trimmed = address.trim()
61
-
62
- if (!trimmed) return null
63
- const m = HOUSE_NUMBER_PREFIX.exec(trimmed)
64
-
65
- if (m) return { house_number: m[1], street: m[2]!.trim() }
66
-
67
- return { street: trimmed }
68
- }
69
-
70
54
  function composeRaw(
71
55
  venue: string | undefined,
72
56
  house: string | undefined,
@@ -93,84 +77,75 @@ export function createUsgovNPPESAdapter(): CorpusAdapter {
93
77
  throw new Error(`usgov-nppes adapter: only US supported, got country=${opts.country}`)
94
78
  }
95
79
 
96
- const stream = createReadStream(opts.inputPath, { encoding: "utf8" })
97
-
98
- const parser = stream.pipe(
99
- csvParse({
100
- columns: true,
101
- skip_empty_lines: true,
102
- relax_quotes: true,
103
- relax_column_count: true,
104
- })
105
- )
80
+ const rows = CSVSpliterator.fromAsync(opts.inputPath, {
81
+ mode: "object",
82
+ normalizeKeys: false,
83
+ enableQuoteHandling: true,
84
+ })
106
85
 
107
86
  let emitted = 0
108
87
 
109
- try {
110
- for await (const record of parser as AsyncIterable<NPPESRow>) {
111
- if (opts.signal?.aborted) break
88
+ for await (const record of rows as AsyncIterable<NPPESRow>) {
89
+ if (opts.signal?.aborted) break
112
90
 
113
- if (opts.limit !== undefined && emitted >= opts.limit) break
91
+ if (opts.limit !== undefined && emitted >= opts.limit) break
114
92
 
115
- const npi = (record.NPI ?? "").trim()
116
- const entityType = (record["Entity Type Code"] ?? "").trim()
117
- const orgName = (record["Provider Organization Name (Legal Business Name)"] ?? "").trim()
118
- const lastName = (record["Provider Last Name (Legal Name)"] ?? "").trim()
119
- const firstName = (record["Provider First Name"] ?? "").trim()
93
+ const npi = (record.NPI ?? "").trim()
94
+ const entityType = (record["Entity Type Code"] ?? "").trim()
95
+ const orgName = (record["Provider Organization Name (Legal Business Name)"] ?? "").trim()
96
+ const lastName = (record["Provider Last Name (Legal Name)"] ?? "").trim()
97
+ const firstName = (record["Provider First Name"] ?? "").trim()
120
98
 
121
- const address1 = (record["Provider First Line Business Practice Location Address"] ?? "").trim()
122
- const address2 = (record["Provider Second Line Business Practice Location Address"] ?? "").trim()
123
- const city = (record["Provider Business Practice Location Address City Name"] ?? "").trim()
124
- const stateRaw = (record["Provider Business Practice Location Address State Name"] ?? "").trim()
125
- const postcode = (record["Provider Business Practice Location Address Postal Code"] ?? "").trim()
99
+ const address1 = (record["Provider First Line Business Practice Location Address"] ?? "").trim()
100
+ const address2 = (record["Provider Second Line Business Practice Location Address"] ?? "").trim()
101
+ const city = (record["Provider Business Practice Location Address City Name"] ?? "").trim()
102
+ const stateRaw = (record["Provider Business Practice Location Address State Name"] ?? "").trim()
103
+ const postcode = (record["Provider Business Practice Location Address Postal Code"] ?? "").trim()
126
104
 
127
- if (!city || !postcode) continue
105
+ if (!city || !postcode) continue
128
106
 
129
- const state = lookupStateAbbreviation(stateRaw)
107
+ const state = lookupStateAbbreviation(stateRaw)
130
108
 
131
- if (!state) continue
109
+ if (!state) continue
132
110
 
133
- const fullStreet = [address1, address2].filter(Boolean).join(" ")
134
- const split = splitAddress(fullStreet)
111
+ const fullStreet = [address1, address2].filter(Boolean).join(" ")
112
+ const split = splitStreetLine(fullStreet)
135
113
 
136
- if (!split) continue
114
+ if (!split) continue
137
115
 
138
- const venue = orgName || [firstName, lastName].filter(Boolean).join(" ") || undefined
116
+ const venue = orgName || [firstName, lastName].filter(Boolean).join(" ") || undefined
139
117
 
140
- const components: CanonicalRow["components"] = {
141
- ...(venue ? { venue } : {}),
142
- ...(split.house_number ? { house_number: split.house_number } : {}),
143
- street: split.street,
144
- locality: city,
145
- region: state.abbreviation,
146
- postcode,
147
- }
148
-
149
- const raw = composeRaw(venue, split.house_number, split.street, city, state.abbreviation, postcode)
118
+ const components: CanonicalRow["components"] = {
119
+ ...(venue ? { venue } : {}),
120
+ ...(split.house_number ? { house_number: split.house_number } : {}),
121
+ street: split.street,
122
+ locality: city,
123
+ region: state.abbreviation,
124
+ postcode,
125
+ }
150
126
 
151
- if (!raw) continue
127
+ const raw = composeRaw(venue, split.house_number, split.street, city, state.abbreviation, postcode)
152
128
 
153
- const aligned = reconcileComponents(components, raw)
129
+ if (!raw) continue
154
130
 
155
- if (Object.keys(aligned).length <= 2) continue
131
+ const aligned = reconcileComponents(components, raw)
156
132
 
157
- const sourceID = npi ? `${USGOV_NPPES_ADAPTER_ID}-${npi}` : stableSourceID(USGOV_NPPES_ADAPTER_ID, aligned)
133
+ if (Object.keys(aligned).length <= 2) continue
158
134
 
159
- yield {
160
- raw,
161
- components: aligned,
162
- country: "US",
163
- locale: "en-US",
164
- source: USGOV_NPPES_ADAPTER_ID,
165
- source_id: sourceID,
166
- corpus_version: "",
167
- license: USGOV_NPPES_DEFAULT_LICENSE,
168
- }
135
+ const sourceID = npi ? `${USGOV_NPPES_ADAPTER_ID}-${npi}` : stableSourceID(USGOV_NPPES_ADAPTER_ID, aligned)
169
136
 
170
- emitted++
137
+ yield {
138
+ raw,
139
+ components: aligned,
140
+ country: "US",
141
+ locale: "en-US",
142
+ source: USGOV_NPPES_ADAPTER_ID,
143
+ source_id: sourceID,
144
+ corpus_version: "",
145
+ license: USGOV_NPPES_DEFAULT_LICENSE,
171
146
  }
172
- } finally {
173
- stream.destroy()
147
+
148
+ emitted++
174
149
  }
175
150
  },
176
151
  }