@mailwoman/corpus 9.0.0 → 9.2.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.
- package/README.md +3 -3
- package/data/PROVENANCE.md +227 -0
- package/data/reviewed-ve-postcode-tuples.json +74 -0
- package/data/sub-venue-lexicon.json +18269 -0
- package/out/src/adapters/ban/adapter.d.ts +1 -1
- package/out/src/adapters/ban/adapter.d.ts.map +1 -1
- package/out/src/adapters/ban/adapter.js +5 -4
- package/out/src/adapters/ban/adapter.js.map +1 -1
- package/out/src/adapters/fcc-bdc/adapter.d.ts +1 -1
- package/out/src/adapters/fcc-bdc/adapter.d.ts.map +1 -1
- package/out/src/adapters/fcc-bdc/adapter.js +3 -3
- package/out/src/adapters/fcc-bdc/adapter.js.map +1 -1
- package/out/src/adapters/geonames/adapter.d.ts +1 -1
- package/out/src/adapters/geonames/adapter.d.ts.map +1 -1
- package/out/src/adapters/geonames/adapter.js +2 -2
- package/out/src/adapters/geonames/adapter.js.map +1 -1
- package/out/src/adapters/geonames-postal/adapter.d.ts +1 -1
- package/out/src/adapters/geonames-postal/adapter.d.ts.map +1 -1
- package/out/src/adapters/geonames-postal/adapter.js +3 -3
- package/out/src/adapters/geonames-postal/adapter.js.map +1 -1
- package/out/src/adapters/gnaf/adapter.d.ts +1 -1
- package/out/src/adapters/gnaf/adapter.d.ts.map +1 -1
- package/out/src/adapters/gnaf/adapter.js +2 -2
- package/out/src/adapters/gnaf/adapter.js.map +1 -1
- package/out/src/adapters/gnaf/assemble.js +1 -1
- package/out/src/adapters/gnaf/assemble.js.map +1 -1
- package/out/src/adapters/index.d.ts +1 -1
- package/out/src/adapters/index.d.ts.map +1 -1
- package/out/src/adapters/index.js +1 -1
- package/out/src/adapters/index.js.map +1 -1
- package/out/src/adapters/openaddresses/adapter.d.ts +1 -1
- package/out/src/adapters/openaddresses/adapter.d.ts.map +1 -1
- package/out/src/adapters/openaddresses/adapter.js +3 -3
- package/out/src/adapters/openaddresses/adapter.js.map +1 -1
- package/out/src/adapters/overture/adapter.d.ts +1 -1
- package/out/src/adapters/overture/adapter.d.ts.map +1 -1
- package/out/src/adapters/overture/adapter.js +2 -2
- package/out/src/adapters/overture/adapter.js.map +1 -1
- package/out/src/adapters/state-hi-schools/adapter.d.ts +1 -1
- package/out/src/adapters/state-hi-schools/adapter.d.ts.map +1 -1
- package/out/src/adapters/state-hi-schools/adapter.js +7 -6
- package/out/src/adapters/state-hi-schools/adapter.js.map +1 -1
- package/out/src/adapters/state-ia-contractors/adapter.d.ts +1 -1
- package/out/src/adapters/state-ia-contractors/adapter.d.ts.map +1 -1
- package/out/src/adapters/state-ia-contractors/adapter.js +12 -7
- package/out/src/adapters/state-ia-contractors/adapter.js.map +1 -1
- package/out/src/adapters/state-ny-notaries/adapter.d.ts +1 -1
- package/out/src/adapters/state-ny-notaries/adapter.d.ts.map +1 -1
- package/out/src/adapters/state-ny-notaries/adapter.js +12 -18
- package/out/src/adapters/state-ny-notaries/adapter.js.map +1 -1
- package/out/src/adapters/state-tx-notaries/adapter.d.ts +1 -1
- package/out/src/adapters/state-tx-notaries/adapter.d.ts.map +1 -1
- package/out/src/adapters/state-tx-notaries/adapter.js +12 -7
- package/out/src/adapters/state-tx-notaries/adapter.js.map +1 -1
- package/out/src/adapters/synth-po-box/adapter.d.ts +3 -3
- package/out/src/adapters/synth-po-box/adapter.d.ts.map +1 -1
- package/out/src/adapters/synth-po-box/adapter.js +3 -3
- package/out/src/adapters/synth-po-box/adapter.js.map +1 -1
- package/out/src/adapters/tiger/adapter.d.ts +1 -1
- package/out/src/adapters/tiger/adapter.d.ts.map +1 -1
- package/out/src/adapters/tiger/adapter.js +2 -2
- package/out/src/adapters/tiger/adapter.js.map +1 -1
- package/out/src/adapters/usgov-hrsa-fqhc/adapter.d.ts +1 -1
- package/out/src/adapters/usgov-hrsa-fqhc/adapter.d.ts.map +1 -1
- package/out/src/adapters/usgov-hrsa-fqhc/adapter.js +7 -6
- package/out/src/adapters/usgov-hrsa-fqhc/adapter.js.map +1 -1
- package/out/src/adapters/usgov-imls-pls/adapter.d.ts +1 -1
- package/out/src/adapters/usgov-imls-pls/adapter.d.ts.map +1 -1
- package/out/src/adapters/usgov-imls-pls/adapter.js +11 -7
- package/out/src/adapters/usgov-imls-pls/adapter.js.map +1 -1
- package/out/src/adapters/usgov-irs-bmf/adapter.d.ts +1 -1
- package/out/src/adapters/usgov-irs-bmf/adapter.d.ts.map +1 -1
- package/out/src/adapters/usgov-irs-bmf/adapter.js +6 -5
- package/out/src/adapters/usgov-irs-bmf/adapter.js.map +1 -1
- package/out/src/adapters/usgov-nad/adapter.d.ts +1 -1
- package/out/src/adapters/usgov-nad/adapter.d.ts.map +1 -1
- package/out/src/adapters/usgov-nad/adapter.js +8 -8
- package/out/src/adapters/usgov-nad/adapter.js.map +1 -1
- package/out/src/adapters/usgov-nppes/adapter.d.ts +1 -1
- package/out/src/adapters/usgov-nppes/adapter.d.ts.map +1 -1
- package/out/src/adapters/usgov-nppes/adapter.js +10 -10
- package/out/src/adapters/usgov-nppes/adapter.js.map +1 -1
- package/out/src/adapters/usgov-samhsa-treatment-locator/adapter.d.ts +1 -1
- package/out/src/adapters/usgov-samhsa-treatment-locator/adapter.d.ts.map +1 -1
- package/out/src/adapters/usgov-samhsa-treatment-locator/adapter.js +7 -6
- package/out/src/adapters/usgov-samhsa-treatment-locator/adapter.js.map +1 -1
- package/out/src/{adapter.d.ts → adapters/utils/index.d.ts} +8 -2
- package/out/src/adapters/utils/index.d.ts.map +1 -0
- package/out/src/{adapter.js → adapters/utils/index.js} +11 -3
- package/out/src/adapters/utils/index.js.map +1 -0
- package/out/src/adapters/wof-admin-jp/adapter.d.ts +1 -1
- package/out/src/adapters/wof-admin-jp/adapter.d.ts.map +1 -1
- package/out/src/adapters/wof-admin-jp/adapter.js +5 -5
- package/out/src/adapters/wof-admin-jp/adapter.js.map +1 -1
- package/out/src/adapters/wof-admin-json/adapter.d.ts +4 -15
- package/out/src/adapters/wof-admin-json/adapter.d.ts.map +1 -1
- package/out/src/adapters/wof-admin-json/adapter.js +11 -35
- package/out/src/adapters/wof-admin-json/adapter.js.map +1 -1
- package/out/src/adapters/wof-json-rows.d.ts +32 -0
- package/out/src/adapters/wof-json-rows.d.ts.map +1 -0
- package/out/src/adapters/wof-json-rows.js +45 -0
- package/out/src/adapters/wof-json-rows.js.map +1 -0
- package/out/src/adapters/wof-postalcode-json/adapter.d.ts +4 -9
- package/out/src/adapters/wof-postalcode-json/adapter.d.ts.map +1 -1
- package/out/src/adapters/wof-postalcode-json/adapter.js +12 -37
- package/out/src/adapters/wof-postalcode-json/adapter.js.map +1 -1
- package/out/src/build.d.ts +4 -4
- package/out/src/build.d.ts.map +1 -1
- package/out/src/build.js +7 -7
- package/out/src/build.js.map +1 -1
- package/out/src/index.d.ts +3 -17
- package/out/src/index.d.ts.map +1 -1
- package/out/src/index.js +3 -17
- package/out/src/index.js.map +1 -1
- package/out/src/name-prone-us-suffixes.d.ts +12 -0
- package/out/src/name-prone-us-suffixes.d.ts.map +1 -0
- package/out/src/name-prone-us-suffixes.js +12 -0
- package/out/src/name-prone-us-suffixes.js.map +1 -0
- package/out/src/parquet-wrapper/reader.d.ts.map +1 -1
- package/out/src/parquet-wrapper/reader.js +5 -0
- package/out/src/parquet-wrapper/reader.js.map +1 -1
- package/out/src/runner.d.ts +2 -2
- package/out/src/runner.d.ts.map +1 -1
- package/out/src/runner.js +1 -1
- package/out/src/runner.js.map +1 -1
- package/out/src/shard-recipes/anchor-absorption.d.ts.map +1 -1
- package/out/src/shard-recipes/anchor-absorption.js +4 -5
- package/out/src/shard-recipes/anchor-absorption.js.map +1 -1
- package/out/src/shard-recipes/bare-country.d.ts +25 -0
- package/out/src/shard-recipes/bare-country.d.ts.map +1 -0
- package/out/src/shard-recipes/bare-country.js +87 -0
- package/out/src/shard-recipes/bare-country.js.map +1 -0
- package/out/src/shard-recipes/boundary-stress.d.ts.map +1 -1
- package/out/src/shard-recipes/boundary-stress.js +2 -2
- package/out/src/shard-recipes/boundary-stress.js.map +1 -1
- package/out/src/shard-recipes/country-balanced.d.ts.map +1 -1
- package/out/src/shard-recipes/country-balanced.js +14 -21
- package/out/src/shard-recipes/country-balanced.js.map +1 -1
- package/out/src/shard-recipes/cz-pcfirst-preposition.d.ts.map +1 -1
- package/out/src/shard-recipes/cz-pcfirst-preposition.js +28 -10
- package/out/src/shard-recipes/cz-pcfirst-preposition.js.map +1 -1
- package/out/src/shard-recipes/fr-admin-split.d.ts.map +1 -1
- package/out/src/shard-recipes/fr-admin-split.js +4 -3
- package/out/src/shard-recipes/fr-admin-split.js.map +1 -1
- package/out/src/shard-recipes/fr-bare-street.d.ts.map +1 -1
- package/out/src/shard-recipes/fr-bare-street.js +72 -11
- package/out/src/shard-recipes/fr-bare-street.js.map +1 -1
- package/out/src/shard-recipes/fr-lieudit.d.ts.map +1 -1
- package/out/src/shard-recipes/fr-lieudit.js +4 -3
- package/out/src/shard-recipes/fr-lieudit.js.map +1 -1
- package/out/src/shard-recipes/fr-order.d.ts.map +1 -1
- package/out/src/shard-recipes/fr-order.js +11 -20
- package/out/src/shard-recipes/fr-order.js.map +1 -1
- package/out/src/shard-recipes/german.d.ts.map +1 -1
- package/out/src/shard-recipes/german.js +8 -14
- package/out/src/shard-recipes/german.js.map +1 -1
- package/out/src/shard-recipes/house-venue.d.ts.map +1 -1
- package/out/src/shard-recipes/house-venue.js +1 -1
- package/out/src/shard-recipes/house-venue.js.map +1 -1
- package/out/src/shard-recipes/index.d.ts.map +1 -1
- package/out/src/shard-recipes/index.js +8 -1
- package/out/src/shard-recipes/index.js.map +1 -1
- package/out/src/shard-recipes/intersection.d.ts.map +1 -1
- package/out/src/shard-recipes/intersection.js +7 -13
- package/out/src/shard-recipes/intersection.js.map +1 -1
- package/out/src/shard-recipes/locale.d.ts +5 -5
- package/out/src/shard-recipes/locale.d.ts.map +1 -1
- package/out/src/shard-recipes/locale.js +13 -20
- package/out/src/shard-recipes/locale.js.map +1 -1
- package/out/src/shard-recipes/no-street.d.ts.map +1 -1
- package/out/src/shard-recipes/no-street.js +1 -1
- package/out/src/shard-recipes/no-street.js.map +1 -1
- package/out/src/shard-recipes/po-box-cedex.d.ts.map +1 -1
- package/out/src/shard-recipes/po-box-cedex.js +60 -43
- package/out/src/shard-recipes/po-box-cedex.js.map +1 -1
- package/out/src/shard-recipes/po-box.d.ts.map +1 -1
- package/out/src/shard-recipes/po-box.js +1 -1
- package/out/src/shard-recipes/po-box.js.map +1 -1
- package/out/src/shard-recipes/reviewed-postcode-tail.d.ts +47 -0
- package/out/src/shard-recipes/reviewed-postcode-tail.d.ts.map +1 -0
- package/out/src/shard-recipes/reviewed-postcode-tail.js +125 -0
- package/out/src/shard-recipes/reviewed-postcode-tail.js.map +1 -0
- package/out/src/shard-recipes/scaffold.d.ts +51 -23
- package/out/src/shard-recipes/scaffold.d.ts.map +1 -1
- package/out/src/shard-recipes/scaffold.js +59 -23
- package/out/src/shard-recipes/scaffold.js.map +1 -1
- package/out/src/shard-recipes/street-affix.d.ts +54 -0
- package/out/src/shard-recipes/street-affix.d.ts.map +1 -1
- package/out/src/shard-recipes/street-affix.js +203 -35
- package/out/src/shard-recipes/street-affix.js.map +1 -1
- package/out/src/shard-recipes/street-bare.d.ts.map +1 -1
- package/out/src/shard-recipes/street-bare.js +3 -3
- package/out/src/shard-recipes/street-bare.js.map +1 -1
- package/out/src/shard-recipes/street.d.ts.map +1 -1
- package/out/src/shard-recipes/street.js +2 -2
- package/out/src/shard-recipes/street.js.map +1 -1
- package/out/src/shard-recipes/sub-venue-sources.d.ts +3 -6
- package/out/src/shard-recipes/sub-venue-sources.d.ts.map +1 -1
- package/out/src/shard-recipes/sub-venue-sources.js +4 -9
- package/out/src/shard-recipes/sub-venue-sources.js.map +1 -1
- package/out/src/shard-recipes/sub-venue.d.ts +2 -2
- package/out/src/shard-recipes/sub-venue.d.ts.map +1 -1
- package/out/src/shard-recipes/sub-venue.js +7 -6
- package/out/src/shard-recipes/sub-venue.js.map +1 -1
- package/out/src/shard-recipes/trailing-region.d.ts +74 -0
- package/out/src/shard-recipes/trailing-region.d.ts.map +1 -0
- package/out/src/shard-recipes/trailing-region.js +157 -0
- package/out/src/shard-recipes/trailing-region.js.map +1 -0
- package/out/src/shard-recipes/unit.d.ts.map +1 -1
- package/out/src/shard-recipes/unit.js +6 -12
- package/out/src/shard-recipes/unit.js.map +1 -1
- package/out/src/{synthesize-anchor-absorption.d.ts → synthesizers/anchor-absorption.d.ts} +1 -1
- package/out/src/synthesizers/anchor-absorption.d.ts.map +1 -0
- package/out/src/{synthesize-anchor-absorption.js → synthesizers/anchor-absorption.js} +1 -1
- package/out/src/synthesizers/anchor-absorption.js.map +1 -0
- package/out/src/{synthesize-boundary-stress.d.ts → synthesizers/boundary-stress.d.ts} +3 -3
- package/out/src/synthesizers/boundary-stress.d.ts.map +1 -0
- package/out/src/{synthesize-boundary-stress.js → synthesizers/boundary-stress.js} +2 -2
- package/out/src/synthesizers/boundary-stress.js.map +1 -0
- package/out/src/{synthesize-german.d.ts → synthesizers/german.d.ts} +2 -2
- package/out/src/synthesizers/german.d.ts.map +1 -0
- package/out/src/{synthesize-german.js → synthesizers/german.js} +2 -2
- package/out/src/synthesizers/german.js.map +1 -0
- package/out/src/{synthesize-house-venue.d.ts → synthesizers/house-venue.d.ts} +4 -4
- package/out/src/synthesizers/house-venue.d.ts.map +1 -0
- package/out/src/{synthesize-house-venue.js → synthesizers/house-venue.js} +20 -6
- package/out/src/synthesizers/house-venue.js.map +1 -0
- package/out/src/{synthesize-intersection.d.ts → synthesizers/intersection.d.ts} +2 -2
- package/out/src/synthesizers/intersection.d.ts.map +1 -0
- package/out/src/{synthesize-intersection.js → synthesizers/intersection.js} +1 -1
- package/out/src/synthesizers/intersection.js.map +1 -0
- package/out/src/{synthesize-no-street.d.ts → synthesizers/no-street.d.ts} +3 -3
- package/out/src/synthesizers/no-street.d.ts.map +1 -0
- package/out/src/{synthesize-no-street.js → synthesizers/no-street.js} +2 -2
- package/out/src/synthesizers/no-street.js.map +1 -0
- package/out/src/{synthesize-po-box.d.ts → synthesizers/po-box.d.ts} +2 -2
- package/out/src/synthesizers/po-box.d.ts.map +1 -0
- package/out/src/{synthesize-po-box.js → synthesizers/po-box.js} +1 -1
- package/out/src/synthesizers/po-box.js.map +1 -0
- package/out/src/{synthesize-street.d.ts → synthesizers/street.d.ts} +2 -2
- package/out/src/synthesizers/street.d.ts.map +1 -0
- package/out/src/{synthesize-street.js → synthesizers/street.js} +4 -3
- package/out/src/synthesizers/street.js.map +1 -0
- package/out/src/{synthesize.d.ts → synthesizers/utils.d.ts} +3 -3
- package/out/src/synthesizers/utils.d.ts.map +1 -0
- package/out/src/{synthesize.js → synthesizers/utils.js} +5 -4
- package/out/src/synthesizers/utils.js.map +1 -0
- package/out/src/tools/align-shard.d.ts.map +1 -1
- package/out/src/tools/align-shard.js +2 -2
- package/out/src/tools/align-shard.js.map +1 -1
- package/out/src/tools/fetch/ban.d.ts.map +1 -1
- package/out/src/tools/fetch/ban.js +2 -18
- package/out/src/tools/fetch/ban.js.map +1 -1
- package/out/src/tools/fetch/download.d.ts +12 -3
- package/out/src/tools/fetch/download.d.ts.map +1 -1
- package/out/src/tools/fetch/download.js +20 -4
- package/out/src/tools/fetch/download.js.map +1 -1
- package/out/src/tools/fetch/geonames-dump.d.ts +87 -0
- package/out/src/tools/fetch/geonames-dump.d.ts.map +1 -0
- package/out/src/tools/fetch/geonames-dump.js +178 -0
- package/out/src/tools/fetch/geonames-dump.js.map +1 -0
- package/out/src/tools/fetch/geonames-postal.d.ts +76 -0
- package/out/src/tools/fetch/geonames-postal.d.ts.map +1 -0
- package/out/src/tools/fetch/geonames-postal.js +125 -0
- package/out/src/tools/fetch/geonames-postal.js.map +1 -0
- package/out/src/tools/fetch/imls-pls.d.ts.map +1 -1
- package/out/src/tools/fetch/imls-pls.js +5 -17
- package/out/src/tools/fetch/imls-pls.js.map +1 -1
- package/out/src/tools/fetch/index.d.ts +11 -0
- package/out/src/tools/fetch/index.d.ts.map +1 -1
- package/out/src/tools/fetch/index.js +11 -0
- package/out/src/tools/fetch/index.js.map +1 -1
- package/out/src/tools/fetch/nad.d.ts.map +1 -1
- package/out/src/tools/fetch/nad.js +20 -11
- package/out/src/tools/fetch/nad.js.map +1 -1
- package/out/src/tools/fetch/nppes.d.ts.map +1 -1
- package/out/src/tools/fetch/nppes.js +17 -22
- package/out/src/tools/fetch/nppes.js.map +1 -1
- package/out/src/tools/fetch/openaddresses.d.ts.map +1 -1
- package/out/src/tools/fetch/openaddresses.js +18 -17
- package/out/src/tools/fetch/openaddresses.js.map +1 -1
- package/out/src/tools/fetch/ourairports.d.ts.map +1 -1
- package/out/src/tools/fetch/ourairports.js +7 -2
- package/out/src/tools/fetch/ourairports.js.map +1 -1
- package/out/src/tools/fetch/ppd.d.ts +0 -4
- package/out/src/tools/fetch/ppd.d.ts.map +1 -1
- package/out/src/tools/fetch/ppd.js +1 -1
- package/out/src/tools/fetch/ppd.js.map +1 -1
- package/out/src/tools/fetch/state-hi-schools.d.ts.map +1 -1
- package/out/src/tools/fetch/state-hi-schools.js +3 -19
- package/out/src/tools/fetch/state-hi-schools.js.map +1 -1
- package/out/src/tools/fetch/state-sources.d.ts +4 -0
- package/out/src/tools/fetch/state-sources.d.ts.map +1 -1
- package/out/src/tools/fetch/state-sources.js +1 -5
- package/out/src/tools/fetch/state-sources.js.map +1 -1
- package/out/src/tools/fetch/tiger-full.d.ts.map +1 -1
- package/out/src/tools/fetch/tiger-full.js +15 -21
- package/out/src/tools/fetch/tiger-full.js.map +1 -1
- package/out/src/tools/golden-expand.d.ts.map +1 -1
- package/out/src/tools/golden-expand.js +34 -25
- package/out/src/tools/golden-expand.js.map +1 -1
- package/out/src/tools/golden-relabel-street.d.ts.map +1 -1
- package/out/src/tools/golden-relabel-street.js +4 -77
- package/out/src/tools/golden-relabel-street.js.map +1 -1
- package/out/src/tools/index.d.ts +2 -2
- package/out/src/tools/index.d.ts.map +1 -1
- package/out/src/tools/index.js +2 -2
- package/out/src/tools/index.js.map +1 -1
- package/out/src/tools/ingest-csv.d.ts.map +1 -1
- package/out/src/tools/ingest-csv.js +0 -11
- package/out/src/tools/ingest-csv.js.map +1 -1
- package/out/src/tools/overlay-manifest.d.ts +4 -0
- package/out/src/tools/overlay-manifest.d.ts.map +1 -1
- package/out/src/tools/overlay-manifest.js +16 -6
- package/out/src/tools/overlay-manifest.js.map +1 -1
- package/out/src/tools/postcode-triples.d.ts +175 -0
- package/out/src/tools/postcode-triples.d.ts.map +1 -0
- package/out/src/tools/postcode-triples.js +304 -0
- package/out/src/tools/postcode-triples.js.map +1 -0
- package/out/src/tools/shard-kryptonite.d.ts.map +1 -1
- package/out/src/tools/shard-kryptonite.js +1 -3
- package/out/src/tools/shard-kryptonite.js.map +1 -1
- package/out/src/tools/shard-translit.d.ts.map +1 -1
- package/out/src/tools/shard-translit.js +4 -27
- package/out/src/tools/shard-translit.js.map +1 -1
- package/out/src/tools/sub-venue/harvest.d.ts +100 -0
- package/out/src/tools/sub-venue/harvest.d.ts.map +1 -0
- package/out/src/tools/sub-venue/harvest.js +168 -0
- package/out/src/tools/sub-venue/harvest.js.map +1 -0
- package/out/src/tools/sub-venue/head-nouns.d.ts +50 -0
- package/out/src/tools/sub-venue/head-nouns.d.ts.map +1 -0
- package/out/src/tools/sub-venue/head-nouns.js +210 -0
- package/out/src/tools/sub-venue/head-nouns.js.map +1 -0
- package/out/src/tools/sub-venue/surfaces.d.ts +45 -0
- package/out/src/tools/sub-venue/surfaces.d.ts.map +1 -0
- package/out/src/tools/sub-venue/surfaces.js +77 -0
- package/out/src/tools/sub-venue/surfaces.js.map +1 -0
- package/out/src/tools/sub-venue/table.d.ts +229 -0
- package/out/src/tools/sub-venue/table.d.ts.map +1 -0
- package/out/src/tools/sub-venue/table.js +108 -0
- package/out/src/tools/sub-venue/table.js.map +1 -0
- package/out/src/tools/sub-venue/wikidata.d.ts +26 -0
- package/out/src/tools/sub-venue/wikidata.d.ts.map +1 -0
- package/out/src/tools/sub-venue/wikidata.js +62 -0
- package/out/src/tools/sub-venue/wikidata.js.map +1 -0
- package/out/src/tools/sub-venue-lexicon.d.ts +27 -378
- package/out/src/tools/sub-venue-lexicon.d.ts.map +1 -1
- package/out/src/tools/sub-venue-lexicon.js +30 -565
- package/out/src/tools/sub-venue-lexicon.js.map +1 -1
- package/out/src/{align.d.ts → utils/align.d.ts} +1 -1
- package/out/src/utils/align.d.ts.map +1 -0
- package/out/src/utils/align.js.map +1 -0
- package/out/src/utils/golden.d.ts.map +1 -0
- package/out/src/{golden.js → utils/golden.js} +2 -2
- package/out/src/utils/golden.js.map +1 -0
- package/out/src/utils/index.d.ts +14 -0
- package/out/src/utils/index.d.ts.map +1 -0
- package/out/src/utils/index.js +14 -0
- package/out/src/utils/index.js.map +1 -0
- package/out/src/utils/license.d.ts.map +1 -0
- package/out/src/{license.js → utils/license.js} +1 -1
- package/out/src/utils/license.js.map +1 -0
- package/out/src/{parquet.d.ts → utils/parquet.d.ts} +24 -5
- package/out/src/utils/parquet.d.ts.map +1 -0
- package/out/src/{parquet.js → utils/parquet.js} +6 -3
- package/out/src/utils/parquet.js.map +1 -0
- package/out/src/{split.d.ts → utils/split.d.ts} +1 -1
- package/out/src/utils/split.d.ts.map +1 -0
- package/out/src/{split.js → utils/split.js} +2 -2
- package/out/src/utils/split.js.map +1 -0
- package/out/src/utils/tokenize.d.ts.map +1 -0
- package/out/src/utils/tokenize.js.map +1 -0
- package/out/src/utils/wof-json.d.ts.map +1 -0
- package/out/src/utils/wof-json.js.map +1 -0
- package/package.json +287 -21
- package/src/adapters/ban/adapter.ts +7 -5
- package/src/adapters/fcc-bdc/adapter.ts +5 -4
- package/src/adapters/geonames/adapter.ts +3 -3
- package/src/adapters/geonames-postal/adapter.ts +4 -4
- package/src/adapters/gnaf/adapter.ts +3 -3
- package/src/adapters/gnaf/assemble.ts +1 -1
- package/src/adapters/index.ts +3 -2
- package/src/adapters/openaddresses/adapter.ts +4 -4
- package/src/adapters/overture/adapter.ts +3 -3
- package/src/adapters/state-hi-schools/adapter.ts +8 -7
- package/src/adapters/state-ia-contractors/adapter.ts +13 -8
- package/src/adapters/state-ny-notaries/adapter.ts +13 -32
- package/src/adapters/state-tx-notaries/adapter.ts +13 -8
- package/src/adapters/synth-po-box/adapter.ts +4 -4
- package/src/adapters/tiger/adapter.ts +5 -3
- package/src/adapters/usgov-hrsa-fqhc/adapter.ts +8 -7
- package/src/adapters/usgov-imls-pls/adapter.ts +12 -8
- package/src/adapters/usgov-irs-bmf/adapter.ts +7 -6
- package/src/adapters/usgov-nad/adapter.ts +9 -9
- package/src/adapters/usgov-nppes/adapter.ts +13 -12
- package/src/adapters/usgov-samhsa-treatment-locator/adapter.ts +8 -7
- package/src/{adapter.ts → adapters/utils/index.ts} +15 -3
- package/src/adapters/wof-admin-jp/adapter.ts +9 -12
- package/src/adapters/wof-admin-json/adapter.ts +15 -54
- package/src/adapters/wof-json-rows.ts +79 -0
- package/src/adapters/wof-postalcode-json/adapter.ts +16 -50
- package/src/build.ts +8 -8
- package/src/index.ts +3 -17
- package/src/name-prone-us-suffixes.ts +12 -0
- package/src/parquet-wrapper/reader.ts +9 -0
- package/src/runner.ts +2 -2
- package/src/shard-recipes/anchor-absorption.ts +5 -5
- package/src/shard-recipes/bare-country.ts +95 -0
- package/src/shard-recipes/boundary-stress.ts +3 -2
- package/src/shard-recipes/country-balanced.ts +16 -27
- package/src/shard-recipes/cz-pcfirst-preposition.ts +29 -10
- package/src/shard-recipes/fr-admin-split.ts +6 -4
- package/src/shard-recipes/fr-bare-street.ts +85 -10
- package/src/shard-recipes/fr-lieudit.ts +6 -4
- package/src/shard-recipes/fr-order.ts +13 -26
- package/src/shard-recipes/german.ts +9 -18
- package/src/shard-recipes/house-venue.ts +2 -1
- package/src/shard-recipes/index.ts +8 -1
- package/src/shard-recipes/intersection.ts +9 -17
- package/src/shard-recipes/locale.ts +16 -24
- package/src/shard-recipes/no-street.ts +2 -1
- package/src/shard-recipes/po-box-cedex.ts +76 -58
- package/src/shard-recipes/po-box.ts +2 -1
- package/src/shard-recipes/reviewed-postcode-tail.ts +189 -0
- package/src/shard-recipes/scaffold.ts +99 -24
- package/src/shard-recipes/street-affix.ts +284 -45
- package/src/shard-recipes/street-bare.ts +4 -3
- package/src/shard-recipes/street.ts +3 -2
- package/src/shard-recipes/sub-venue-sources.ts +13 -23
- package/src/shard-recipes/sub-venue.ts +11 -9
- package/src/shard-recipes/trailing-region.ts +183 -0
- package/src/shard-recipes/unit.ts +8 -17
- package/src/{synthesize-boundary-stress.ts → synthesizers/boundary-stress.ts} +2 -2
- package/src/{synthesize-german.ts → synthesizers/german.ts} +3 -2
- package/src/{synthesize-house-venue.ts → synthesizers/house-venue.ts} +20 -6
- package/src/{synthesize-intersection.ts → synthesizers/intersection.ts} +1 -1
- package/src/{synthesize-no-street.ts → synthesizers/no-street.ts} +2 -2
- package/src/{synthesize-po-box.ts → synthesizers/po-box.ts} +1 -1
- package/src/{synthesize-street.ts → synthesizers/street.ts} +5 -3
- package/src/{synthesize.ts → synthesizers/utils.ts} +6 -4
- package/src/tools/align-shard.ts +3 -2
- package/src/tools/fetch/ban.ts +2 -22
- package/src/tools/fetch/download.ts +22 -4
- package/src/tools/fetch/geonames-dump.ts +267 -0
- package/src/tools/fetch/geonames-postal.ts +180 -0
- package/src/tools/fetch/imls-pls.ts +6 -20
- package/src/tools/fetch/index.ts +11 -0
- package/src/tools/fetch/nad.ts +21 -10
- package/src/tools/fetch/nppes.ts +17 -23
- package/src/tools/fetch/openaddresses.ts +18 -22
- package/src/tools/fetch/ourairports.ts +7 -2
- package/src/tools/fetch/ppd.ts +1 -1
- package/src/tools/fetch/state-hi-schools.ts +3 -23
- package/src/tools/fetch/state-sources.ts +1 -1
- package/src/tools/fetch/tiger-full.ts +17 -24
- package/src/tools/golden-expand.ts +44 -33
- package/src/tools/golden-relabel-street.ts +5 -68
- package/src/tools/index.ts +2 -2
- package/src/tools/ingest-csv.ts +0 -13
- package/src/tools/overlay-manifest.ts +20 -8
- package/src/tools/postcode-triples.ts +375 -0
- package/src/tools/shard-kryptonite.ts +4 -5
- package/src/tools/shard-translit.ts +16 -35
- package/src/tools/sub-venue/harvest.ts +235 -0
- package/src/tools/sub-venue/head-nouns.ts +242 -0
- package/src/tools/sub-venue/surfaces.ts +95 -0
- package/src/tools/sub-venue/table.ts +281 -0
- package/src/tools/sub-venue/wikidata.ts +85 -0
- package/src/tools/sub-venue-lexicon.ts +67 -886
- package/src/{align.ts → utils/align.ts} +2 -1
- package/src/{golden.ts → utils/golden.ts} +2 -3
- package/src/utils/index.ts +14 -0
- package/src/{license.ts → utils/license.ts} +1 -1
- package/src/{parquet.ts → utils/parquet.ts} +22 -9
- package/src/{split.ts → utils/split.ts} +3 -3
- package/out/src/adapter.d.ts.map +0 -1
- package/out/src/adapter.js.map +0 -1
- package/out/src/align.d.ts.map +0 -1
- package/out/src/align.js.map +0 -1
- package/out/src/format.d.ts +0 -14
- package/out/src/format.d.ts.map +0 -1
- package/out/src/format.js +0 -14
- package/out/src/format.js.map +0 -1
- package/out/src/golden.d.ts.map +0 -1
- package/out/src/golden.js.map +0 -1
- package/out/src/license.d.ts.map +0 -1
- package/out/src/license.js.map +0 -1
- package/out/src/parquet.d.ts.map +0 -1
- package/out/src/parquet.js.map +0 -1
- package/out/src/split.d.ts.map +0 -1
- package/out/src/split.js.map +0 -1
- package/out/src/synthesize-anchor-absorption.d.ts.map +0 -1
- package/out/src/synthesize-anchor-absorption.js.map +0 -1
- package/out/src/synthesize-boundary-stress.d.ts.map +0 -1
- package/out/src/synthesize-boundary-stress.js.map +0 -1
- package/out/src/synthesize-german.d.ts.map +0 -1
- package/out/src/synthesize-german.js.map +0 -1
- package/out/src/synthesize-house-venue.d.ts.map +0 -1
- package/out/src/synthesize-house-venue.js.map +0 -1
- package/out/src/synthesize-intersection.d.ts.map +0 -1
- package/out/src/synthesize-intersection.js.map +0 -1
- package/out/src/synthesize-no-street.d.ts.map +0 -1
- package/out/src/synthesize-no-street.js.map +0 -1
- package/out/src/synthesize-po-box.d.ts.map +0 -1
- package/out/src/synthesize-po-box.js.map +0 -1
- package/out/src/synthesize-street.d.ts.map +0 -1
- package/out/src/synthesize-street.js.map +0 -1
- package/out/src/synthesize.d.ts.map +0 -1
- package/out/src/synthesize.js.map +0 -1
- package/out/src/tokenize.d.ts.map +0 -1
- package/out/src/tokenize.js.map +0 -1
- package/out/src/wof-json.d.ts.map +0 -1
- package/out/src/wof-json.js.map +0 -1
- package/src/format.ts +0 -14
- /package/out/src/{align.js → utils/align.js} +0 -0
- /package/out/src/{golden.d.ts → utils/golden.d.ts} +0 -0
- /package/out/src/{license.d.ts → utils/license.d.ts} +0 -0
- /package/out/src/{tokenize.d.ts → utils/tokenize.d.ts} +0 -0
- /package/out/src/{tokenize.js → utils/tokenize.js} +0 -0
- /package/out/src/{wof-json.d.ts → utils/wof-json.d.ts} +0 -0
- /package/out/src/{wof-json.js → utils/wof-json.js} +0 -0
- /package/src/{synthesize-anchor-absorption.ts → synthesizers/anchor-absorption.ts} +0 -0
- /package/src/{tokenize.ts → utils/tokenize.ts} +0 -0
- /package/src/{wof-json.ts → utils/wof-json.ts} +0 -0
package/src/tools/fetch/nppes.ts
CHANGED
|
@@ -24,20 +24,17 @@
|
|
|
24
24
|
/* oxlint-disable sister-software/prefer-region-over-marks -- these markers label steps inside one
|
|
25
25
|
procedure, not sections of declarations. A region there folds nothing a reader wants folded. */
|
|
26
26
|
|
|
27
|
-
import { execFile } from "node:child_process"
|
|
28
27
|
import { existsSync, mkdirSync, statSync } from "node:fs"
|
|
29
28
|
import { rm } from "node:fs/promises"
|
|
30
|
-
import { join } from "node:path"
|
|
31
|
-
import { promisify } from "node:util"
|
|
29
|
+
import { basename, join } from "node:path"
|
|
32
30
|
|
|
31
|
+
import { APIClient, pluckResponseData } from "@mailwoman/core/api"
|
|
32
|
+
import { extractZipEntry, listZipEntries } from "@mailwoman/core/fs/zip"
|
|
33
33
|
import { sha256File } from "@mailwoman/core/utils"
|
|
34
|
-
import { TextSpliterator } from "spliterator"
|
|
35
34
|
|
|
36
35
|
import type { BaseFetchOptions, FetchSummary } from "./download.ts"
|
|
37
36
|
import { downloadToFile, readManifest, writeManifest } from "./download.ts"
|
|
38
37
|
|
|
39
|
-
const execFileAsync = promisify(execFile)
|
|
40
|
-
|
|
41
38
|
const INDEX_URL = "https://download.cms.gov/nppes/NPI_Files.html"
|
|
42
39
|
const BASE_URL = "https://download.cms.gov/nppes"
|
|
43
40
|
const SLUG = "usgov-nppes"
|
|
@@ -57,13 +54,14 @@ interface SourceManifest {
|
|
|
57
54
|
* `NPPES_Data_Dissemination_<Month>_<Year>*.zip`; weekly files carry a `MMDDYY_MMDDYY` date range, which we exclude.
|
|
58
55
|
*/
|
|
59
56
|
async function discoverLatestZip(): Promise<string | undefined> {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
57
|
+
// `responseType: "text"` — the index is HTML, scraped by regex below.
|
|
58
|
+
const html = await new APIClient({
|
|
59
|
+
displayName: "nppes-index",
|
|
60
|
+
retry: true,
|
|
61
|
+
axios: { headers: { "Accept-Encoding": "gzip, br" } },
|
|
63
62
|
})
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
const html = await res.text()
|
|
63
|
+
.fetch<string>({ url: INDEX_URL, responseType: "text", timeout: 60_000 })
|
|
64
|
+
.then(pluckResponseData)
|
|
67
65
|
|
|
68
66
|
for (const match of html.matchAll(/NPPES_Data_Dissemination_[A-Za-z]+_\d{4}[^"]*\.zip/g)) {
|
|
69
67
|
const name = match[0]
|
|
@@ -75,18 +73,13 @@ async function discoverLatestZip(): Promise<string | undefined> {
|
|
|
75
73
|
}
|
|
76
74
|
|
|
77
75
|
/**
|
|
78
|
-
*
|
|
76
|
+
* The main registry CSV (npidata_pfile_*.csv), which the archive also carries alongside a header file and a per-month
|
|
77
|
+
* change file.
|
|
79
78
|
*/
|
|
80
79
|
async function findNpidataCSV(zipPath: string): Promise<string | undefined> {
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
for (const line of TextSpliterator.from(listing.stdout)) {
|
|
84
|
-
const match = /npidata_pfile\S+\.csv/i.exec(line)
|
|
80
|
+
const entries = await listZipEntries(zipPath)
|
|
85
81
|
|
|
86
|
-
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
return undefined
|
|
82
|
+
return entries.find((entry) => /npidata_pfile\S+\.csv/i.test(entry.name))?.name
|
|
90
83
|
}
|
|
91
84
|
|
|
92
85
|
export async function fetchNPPES(options: FetchNPPESOptions, report?: (line: string) => void): Promise<FetchSummary> {
|
|
@@ -149,9 +142,10 @@ export async function fetchNPPES(options: FetchNPPESOptions, report?: (line: str
|
|
|
149
142
|
}
|
|
150
143
|
|
|
151
144
|
report?.(` Extracting: ${csvName}`)
|
|
152
|
-
await execFileAsync("unzip", ["-o", "-j", zipDest, csvName, "-d", destDir])
|
|
153
145
|
|
|
154
|
-
const csvDest = join(destDir, csvName)
|
|
146
|
+
const csvDest = join(destDir, basename(csvName))
|
|
147
|
+
|
|
148
|
+
await extractZipEntry(zipDest, csvName, csvDest)
|
|
155
149
|
const csvSize = statSync(csvDest).size
|
|
156
150
|
const csvSha = await sha256File(csvDest)
|
|
157
151
|
report?.(` CSV size: ${(csvSize / 1024 / 1024).toFixed(1)} MB`)
|
|
@@ -62,7 +62,9 @@ import { pipeline } from "node:stream/promises"
|
|
|
62
62
|
import { setTimeout as sleep } from "node:timers/promises"
|
|
63
63
|
import { promisify } from "node:util"
|
|
64
64
|
|
|
65
|
+
import { APIClient, isSuccessStatus } from "@mailwoman/core/api"
|
|
65
66
|
import { $private } from "@mailwoman/core/env"
|
|
67
|
+
import { ByteFormatter } from "@mailwoman/core/fs/utils"
|
|
66
68
|
import { sha256File } from "@mailwoman/core/utils"
|
|
67
69
|
|
|
68
70
|
import type { BaseFetchOptions, FetchSummary } from "./download.ts"
|
|
@@ -82,8 +84,6 @@ const HTTP_OK = 200
|
|
|
82
84
|
*/
|
|
83
85
|
const MIN_PLAUSIBLE_SHARD_BYTES = 10_240
|
|
84
86
|
|
|
85
|
-
const BYTES_PER_KIB = 1024
|
|
86
|
-
|
|
87
87
|
const execFileAsync = promisify(execFile)
|
|
88
88
|
|
|
89
89
|
const OA_BASE = "https://batch.openaddresses.io"
|
|
@@ -132,20 +132,6 @@ async function countLines(path: string): Promise<number> {
|
|
|
132
132
|
return count
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
-
function humanBytes(bytes: number): string {
|
|
136
|
-
const units = ["B", "KiB", "MiB", "GiB", "TiB"]
|
|
137
|
-
let value = bytes
|
|
138
|
-
let unit = 0
|
|
139
|
-
|
|
140
|
-
while (value >= BYTES_PER_KIB && unit < units.length - 1) {
|
|
141
|
-
value /= 1024
|
|
142
|
-
|
|
143
|
-
unit++
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
return `${value.toFixed(unit === 0 ? 0 : 1)}${units[unit]}`
|
|
147
|
-
}
|
|
148
|
-
|
|
149
135
|
interface StreamDownloadOpts {
|
|
150
136
|
headers?: Record<string, string>
|
|
151
137
|
timeoutMs: number
|
|
@@ -263,18 +249,28 @@ The Canada collection (ca) is ~2 GiB compressed / ~7 GiB uncompressed
|
|
|
263
249
|
if (collectionID === undefined) {
|
|
264
250
|
report?.(`Unknown country code '${country}'. Fetching collection list to find ID...`)
|
|
265
251
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
252
|
+
// The collections API only. The COLLECTION ARCHIVES stay on raw `fetch` — they stream multi-gigabyte
|
|
253
|
+
// bodies straight to disk, where response caching is nonsense and axios would buffer them in memory.
|
|
254
|
+
const res = await new APIClient({
|
|
255
|
+
displayName: "openaddresses-api",
|
|
256
|
+
retry: true,
|
|
257
|
+
axios: { headers: { Authorization: `Bearer ${token}`, "Accept-Encoding": "gzip, br" } },
|
|
269
258
|
})
|
|
259
|
+
// `validateStatus` keeps a non-2xx as a RESPONSE rather than a throw: the caller reports the status and
|
|
260
|
+
// returns `fail(country)`, a graceful path this must not turn into an exception.
|
|
261
|
+
.fetch<OaCollection[]>({
|
|
262
|
+
url: `${OA_BASE}/api/collections`,
|
|
263
|
+
timeout: 30_000,
|
|
264
|
+
validateStatus: () => true,
|
|
265
|
+
})
|
|
270
266
|
|
|
271
|
-
if (!res.
|
|
267
|
+
if (!isSuccessStatus(res.status)) {
|
|
272
268
|
report?.(`ERROR: GET /api/collections returned HTTP ${res.status}.`)
|
|
273
269
|
|
|
274
270
|
return fail(country)
|
|
275
271
|
}
|
|
276
272
|
|
|
277
|
-
const collections =
|
|
273
|
+
const collections = res.data
|
|
278
274
|
const match = collections.find((item) => item.name === country)
|
|
279
275
|
|
|
280
276
|
if (match?.id === undefined) {
|
|
@@ -395,7 +391,7 @@ URL tried: ${OA_BASE}/api/collections/${collectionID}/download
|
|
|
395
391
|
|
|
396
392
|
await writeManifest(manifestPath, manifest)
|
|
397
393
|
|
|
398
|
-
report?.(` ✓ ${
|
|
394
|
+
report?.(` ✓ ${ByteFormatter.formatIEC(size)} rows=${rowCount} sha256=${sha}`)
|
|
399
395
|
report?.(` MANIFEST written to ${manifestPath}`)
|
|
400
396
|
report?.(`=== done`)
|
|
401
397
|
report?.(`Feed to the adapter:`)
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
import { mkdirSync } from "node:fs"
|
|
40
40
|
import { join } from "node:path"
|
|
41
41
|
|
|
42
|
+
import { APIClient } from "@mailwoman/core/api"
|
|
42
43
|
import { sha256File } from "@mailwoman/core/utils"
|
|
43
44
|
|
|
44
45
|
import type { BaseFetchOptions, FetchSummary } from "./download.ts"
|
|
@@ -92,9 +93,13 @@ interface OurAirportsManifest {
|
|
|
92
93
|
*/
|
|
93
94
|
async function readLastModified(url: string): Promise<string | null> {
|
|
94
95
|
try {
|
|
95
|
-
const res = await
|
|
96
|
+
const res = await new APIClient({ displayName: "ourairports", retry: true }).fetch({
|
|
97
|
+
url,
|
|
98
|
+
method: "head",
|
|
99
|
+
timeout: 30_000,
|
|
100
|
+
})
|
|
96
101
|
|
|
97
|
-
return res.
|
|
102
|
+
return (res.headers["last-modified"] as string | undefined) ?? null
|
|
98
103
|
} catch {
|
|
99
104
|
return null
|
|
100
105
|
}
|
package/src/tools/fetch/ppd.ts
CHANGED
|
@@ -104,7 +104,7 @@ export async function extractPPDTuples(
|
|
|
104
104
|
/**
|
|
105
105
|
* Stream `inputPath` (PPD CSV) → `outputPath` (OA-shaped tuples CSV), returning the row-count stats.
|
|
106
106
|
*/
|
|
107
|
-
|
|
107
|
+
async function runPPDExtract(inputPath: string, outputPath: string): Promise<PPDExtractStats> {
|
|
108
108
|
// No `encoding` — CSVSpliterator delimits raw bytes and decodes utf-8 itself (see readTuples in
|
|
109
109
|
// shard-recipes/locale.ts). `header: false` yields every row as data — PPD ships no header row.
|
|
110
110
|
const rows = CSVSpliterator.fromAsync<string[]>(createReadStream(inputPath), {
|
|
@@ -25,6 +25,7 @@ import { existsSync, mkdirSync, statSync } from "node:fs"
|
|
|
25
25
|
import { unlink } from "node:fs/promises"
|
|
26
26
|
import { join } from "node:path"
|
|
27
27
|
|
|
28
|
+
import { BYTES_PER_KIB, ByteFormatter } from "@mailwoman/core/fs/utils"
|
|
28
29
|
import { sha256File } from "@mailwoman/core/utils"
|
|
29
30
|
|
|
30
31
|
import type { BaseFetchOptions, FetchSummary } from "./download.ts"
|
|
@@ -34,7 +35,6 @@ import { downloadToFile, readManifest, writeManifest } from "./download.ts"
|
|
|
34
35
|
* Bytes per KiB — the divisor for human-readable sizes, and the floor below which a "download" is an error page rather
|
|
35
36
|
* than data.
|
|
36
37
|
*/
|
|
37
|
-
const BYTES_PER_KIB = 1024
|
|
38
38
|
|
|
39
39
|
const SOURCE_URL = "https://www.hawaiipublicschools.org/DOE%20Forms/SchoolList.xlsx"
|
|
40
40
|
const SLUG = "state-hi-schools"
|
|
@@ -96,26 +96,6 @@ interface Manifest {
|
|
|
96
96
|
notes: string
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
-
/**
|
|
100
|
-
* Mimic `numfmt --to=iec` for a friendly byte-size log line.
|
|
101
|
-
*/
|
|
102
|
-
function iec(bytes: number): string {
|
|
103
|
-
if (bytes < BYTES_PER_KIB) return String(bytes)
|
|
104
|
-
const units = ["K", "M", "G", "T", "P"]
|
|
105
|
-
let value = bytes / 1024
|
|
106
|
-
let i = 0
|
|
107
|
-
|
|
108
|
-
while (value >= BYTES_PER_KIB && i < units.length - 1) {
|
|
109
|
-
value /= 1024
|
|
110
|
-
|
|
111
|
-
i++
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
const rounded = value < 10 ? value.toFixed(1) : Math.round(value).toString()
|
|
115
|
-
|
|
116
|
-
return `${rounded}${units[i] ?? ""}`
|
|
117
|
-
}
|
|
118
|
-
|
|
119
99
|
/**
|
|
120
100
|
* Run the openpyxl converter. Its stderr narration streams straight through to the process stderr (matching the old
|
|
121
101
|
* `stdio: inherit` behavior) rather than routing through `report` — the python child owns those lines.
|
|
@@ -190,7 +170,7 @@ export async function fetchStateHISchools(
|
|
|
190
170
|
}
|
|
191
171
|
|
|
192
172
|
const xlsxSize = statSync(xlsxDest).size
|
|
193
|
-
report?.(` Downloaded XLSX: ${
|
|
173
|
+
report?.(` Downloaded XLSX: ${ByteFormatter.formatIEC(xlsxSize)}`)
|
|
194
174
|
|
|
195
175
|
if (xlsxSize < BYTES_PER_KIB) {
|
|
196
176
|
report?.(` ✗ Response too small (${xlsxSize} bytes) — probable error page`)
|
|
@@ -221,7 +201,7 @@ export async function fetchStateHISchools(
|
|
|
221
201
|
|
|
222
202
|
await writeManifest(manifestPath, manifest)
|
|
223
203
|
|
|
224
|
-
report?.(` ✓ ${
|
|
204
|
+
report?.(` ✓ ${ByteFormatter.formatIEC(csvSize)} sha256=${csvSha}`)
|
|
225
205
|
report?.(` MANIFEST written to ${manifestPath}`)
|
|
226
206
|
|
|
227
207
|
return { fetched: 1, skipped: 0, failed: 0, failedCodes: [] }
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
import { mkdirSync } from "node:fs"
|
|
21
21
|
import { join } from "node:path"
|
|
22
22
|
|
|
23
|
+
import { BYTES_PER_KIB } from "@mailwoman/core/fs/utils"
|
|
23
24
|
import { sha256File } from "@mailwoman/core/utils"
|
|
24
25
|
|
|
25
26
|
import type { BaseFetchOptions, FetchSummary } from "./download.ts"
|
|
@@ -29,7 +30,6 @@ import { downloadToFile, writeManifest } from "./download.ts"
|
|
|
29
30
|
* Bytes per KiB — the divisor for human-readable sizes, and the floor below which a "download" is an error page rather
|
|
30
31
|
* than data.
|
|
31
32
|
*/
|
|
32
|
-
const BYTES_PER_KIB = 1024
|
|
33
33
|
|
|
34
34
|
export type FetchStateSourcesOptions = BaseFetchOptions
|
|
35
35
|
|
|
@@ -28,6 +28,8 @@ import { Readable } from "node:stream"
|
|
|
28
28
|
import { pipeline } from "node:stream/promises"
|
|
29
29
|
import { setTimeout as sleep } from "node:timers/promises"
|
|
30
30
|
|
|
31
|
+
import { APIClient, pluckResponseData } from "@mailwoman/core/api"
|
|
32
|
+
import { BYTES_PER_KIB, ByteFormatter } from "@mailwoman/core/fs/utils"
|
|
31
33
|
import { sha256File } from "@mailwoman/core/utils"
|
|
32
34
|
|
|
33
35
|
import type { BaseFetchOptions, FetchSummary } from "./download.ts"
|
|
@@ -47,8 +49,6 @@ const HTTP_OK = 200
|
|
|
47
49
|
*/
|
|
48
50
|
const HTTP_REDIRECT = 300
|
|
49
51
|
|
|
50
|
-
const BYTES_PER_KIB = 1024
|
|
51
|
-
|
|
52
52
|
const TIGER_BASE_URL = "https://www2.census.gov/geo/tiger/TIGER2024/ADDRFEAT"
|
|
53
53
|
|
|
54
54
|
export interface FetchTigerFullOptions extends BaseFetchOptions {
|
|
@@ -77,20 +77,6 @@ interface CountyEntry {
|
|
|
77
77
|
bytes: number
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
function humanBytes(bytes: number): string {
|
|
81
|
-
const units = ["B", "KiB", "MiB", "GiB", "TiB"]
|
|
82
|
-
let value = bytes
|
|
83
|
-
let unit = 0
|
|
84
|
-
|
|
85
|
-
while (value >= BYTES_PER_KIB && unit < units.length - 1) {
|
|
86
|
-
value /= 1024
|
|
87
|
-
|
|
88
|
-
unit++
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
return `${value.toFixed(unit === 0 ? 0 : 1)}${units[unit]}`
|
|
92
|
-
}
|
|
93
|
-
|
|
94
80
|
/**
|
|
95
81
|
* Stream an HTTP download to disk, returning the final HTTP status (0 on network error after retries).
|
|
96
82
|
*
|
|
@@ -193,7 +179,7 @@ export async function fetchTigerFull(
|
|
|
193
179
|
options: FetchTigerFullOptions,
|
|
194
180
|
report?: (line: string) => void
|
|
195
181
|
): Promise<FetchSummary> {
|
|
196
|
-
const skipStateFips = (options.skipStateFips ?? "50").split(/\s+/).filter(
|
|
182
|
+
const skipStateFips = (options.skipStateFips ?? "50").split(/\s+/).filter((value) => value.length > 0)
|
|
197
183
|
const rateSleepMs = Math.round((options.rateSleep ?? 0.2) * 1000)
|
|
198
184
|
const maxParallel = options.maxParallel ?? 4
|
|
199
185
|
const dryRun = options.dryRun ?? false
|
|
@@ -205,13 +191,17 @@ export async function fetchTigerFull(
|
|
|
205
191
|
|
|
206
192
|
report?.(`=== Fetching TIGER 2024 ADDRFEAT directory listing...`)
|
|
207
193
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
194
|
+
// `responseType: "text"` — an Apache directory index, scraped below. The per-county ARCHIVE downloads
|
|
195
|
+
// stay on raw `fetch` (they stream to disk; see `downloadOne`).
|
|
196
|
+
const listingRes = await new APIClient({
|
|
197
|
+
displayName: "tiger-listing",
|
|
198
|
+
retry: true,
|
|
199
|
+
axios: { headers: { "Accept-Encoding": "gzip, br" } },
|
|
211
200
|
})
|
|
201
|
+
.fetch<string>({ url: `${TIGER_BASE_URL}/`, responseType: "text", timeout: 60_000 })
|
|
202
|
+
.then(pluckResponseData)
|
|
212
203
|
|
|
213
|
-
|
|
214
|
-
const html = await listingRes.text()
|
|
204
|
+
const html = listingRes
|
|
215
205
|
const allZips = [...new Set(html.match(/tl_2024_[0-9]{5}_addrfeat\.zip/g))].toSorted()
|
|
216
206
|
const totalCounties = allZips.length
|
|
217
207
|
report?.(` Found ${totalCounties} county ZIPs in the TIGER 2024 ADDRFEAT index.`)
|
|
@@ -314,7 +304,10 @@ export async function fetchTigerFull(
|
|
|
314
304
|
// Collect results from this state.
|
|
315
305
|
for (const result of results) {
|
|
316
306
|
if (result.ok) {
|
|
317
|
-
report?.(
|
|
307
|
+
report?.(
|
|
308
|
+
` ok ${result.filename} ${ByteFormatter.formatIEC(result.bytes)} sha256=${result.sha256.slice(0, 12)}...`
|
|
309
|
+
)
|
|
310
|
+
|
|
318
311
|
manifest.set(result.filename, { filename: result.filename, sha256: result.sha256, bytes: result.bytes })
|
|
319
312
|
|
|
320
313
|
totalFetched++
|
|
@@ -350,7 +343,7 @@ export async function fetchTigerFull(
|
|
|
350
343
|
report?.(` Counties failed : ${totalFailed}`)
|
|
351
344
|
|
|
352
345
|
if (totalBytesFetched > 0) {
|
|
353
|
-
report?.(` Bytes fetched this run : ${
|
|
346
|
+
report?.(` Bytes fetched this run : ${ByteFormatter.formatIEC(totalBytesFetched)} (${totalBytesFetched})`)
|
|
354
347
|
}
|
|
355
348
|
|
|
356
349
|
if (totalFailed > 0) {
|
|
@@ -50,8 +50,9 @@ import { mkdir } from "node:fs/promises"
|
|
|
50
50
|
import { dirname } from "node:path"
|
|
51
51
|
|
|
52
52
|
import { ParquetReader } from "@dsnp/parquetjs"
|
|
53
|
+
import { APIClient, pluckResponseData } from "@mailwoman/core/api"
|
|
53
54
|
import { $private } from "@mailwoman/core/env"
|
|
54
|
-
import { tryParsingJSON } from "@mailwoman/core/objects"
|
|
55
|
+
import { isPresent, tryParsingJSON } from "@mailwoman/core/objects"
|
|
55
56
|
import { dataRootPath } from "@mailwoman/core/utils"
|
|
56
57
|
import { createNewlineWriter } from "spliterator"
|
|
57
58
|
|
|
@@ -195,7 +196,7 @@ async function loadSeeds(
|
|
|
195
196
|
const paths = corpusPath
|
|
196
197
|
.split(",")
|
|
197
198
|
.map((p) => p.trim())
|
|
198
|
-
.filter(
|
|
199
|
+
.filter(isPresent)
|
|
199
200
|
|
|
200
201
|
report?.(`reading seeds from ${paths.length} shard(s) (target: ${count}, stratified)`)
|
|
201
202
|
|
|
@@ -345,24 +346,28 @@ function makeDeepseekProvider(model: string): LlmProvider {
|
|
|
345
346
|
name: "deepseek",
|
|
346
347
|
model,
|
|
347
348
|
async generateVariants(seed, n) {
|
|
348
|
-
const
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
model,
|
|
353
|
-
messages: [
|
|
354
|
-
{ role: "system", content: SYSTEM_PROMPT },
|
|
355
|
-
{ role: "user", content: buildUserPrompt(seed, n) },
|
|
356
|
-
],
|
|
357
|
-
response_format: { type: "json_object" },
|
|
358
|
-
max_tokens: 800,
|
|
359
|
-
temperature: 0.7,
|
|
360
|
-
}),
|
|
361
|
-
signal: AbortSignal.timeout(60_000),
|
|
349
|
+
const data = await new APIClient({
|
|
350
|
+
displayName: "deepseek",
|
|
351
|
+
retry: true,
|
|
352
|
+
axios: { headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json" } },
|
|
362
353
|
})
|
|
354
|
+
.fetch<{ choices?: Array<{ message: { content: string } }> }>({
|
|
355
|
+
url: "https://api.deepseek.com/chat/completions",
|
|
356
|
+
method: "post",
|
|
357
|
+
timeout: 60_000,
|
|
358
|
+
data: {
|
|
359
|
+
model,
|
|
360
|
+
messages: [
|
|
361
|
+
{ role: "system", content: SYSTEM_PROMPT },
|
|
362
|
+
{ role: "user", content: buildUserPrompt(seed, n) },
|
|
363
|
+
],
|
|
364
|
+
response_format: { type: "json_object" },
|
|
365
|
+
max_tokens: 800,
|
|
366
|
+
temperature: 0.7,
|
|
367
|
+
},
|
|
368
|
+
})
|
|
369
|
+
.then(pluckResponseData)
|
|
363
370
|
|
|
364
|
-
if (!res.ok) throw new Error(`DeepSeek HTTP ${res.status}: ${await res.text()}`)
|
|
365
|
-
const data = (await res.json()) as { choices?: Array<{ message: { content: string } }> }
|
|
366
371
|
const content = data.choices?.[0]?.message.content ?? "{}"
|
|
367
372
|
|
|
368
373
|
return parseCandidates(content)
|
|
@@ -379,24 +384,30 @@ function makeAnthropicProvider(model: string): LlmProvider {
|
|
|
379
384
|
name: "anthropic",
|
|
380
385
|
model,
|
|
381
386
|
async generateVariants(seed, n) {
|
|
382
|
-
const
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
387
|
+
const data = await new APIClient({
|
|
388
|
+
displayName: "anthropic",
|
|
389
|
+
retry: true,
|
|
390
|
+
axios: {
|
|
391
|
+
headers: {
|
|
392
|
+
"x-api-key": apiKey,
|
|
393
|
+
"anthropic-version": "2023-06-01",
|
|
394
|
+
"Content-Type": "application/json",
|
|
395
|
+
},
|
|
388
396
|
},
|
|
389
|
-
body: JSON.stringify({
|
|
390
|
-
model,
|
|
391
|
-
max_tokens: 800,
|
|
392
|
-
system: SYSTEM_PROMPT,
|
|
393
|
-
messages: [{ role: "user", content: buildUserPrompt(seed, n) }],
|
|
394
|
-
}),
|
|
395
|
-
signal: AbortSignal.timeout(60_000),
|
|
396
397
|
})
|
|
398
|
+
.fetch<{ content?: Array<{ type: string; text: string }> }>({
|
|
399
|
+
url: "https://api.anthropic.com/v1/messages",
|
|
400
|
+
method: "post",
|
|
401
|
+
timeout: 60_000,
|
|
402
|
+
data: {
|
|
403
|
+
model,
|
|
404
|
+
max_tokens: 800,
|
|
405
|
+
system: SYSTEM_PROMPT,
|
|
406
|
+
messages: [{ role: "user", content: buildUserPrompt(seed, n) }],
|
|
407
|
+
},
|
|
408
|
+
})
|
|
409
|
+
.then(pluckResponseData)
|
|
397
410
|
|
|
398
|
-
if (!res.ok) throw new Error(`Anthropic HTTP ${res.status}: ${await res.text()}`)
|
|
399
|
-
const data = (await res.json()) as { content?: Array<{ type: string; text: string }> }
|
|
400
411
|
const text = data.content?.find((c) => c.type === "text")?.text ?? "[]"
|
|
401
412
|
|
|
402
413
|
return parseCandidates(text)
|
|
@@ -60,10 +60,12 @@ import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from
|
|
|
60
60
|
import { basename, join } from "node:path"
|
|
61
61
|
|
|
62
62
|
import { isStreetDirectionalToken, matchTrailingSuffix, type USStreetSuffix } from "@mailwoman/codex/us"
|
|
63
|
-
import { parseJSONStrict, tryParsingJSON } from "@mailwoman/core/objects"
|
|
63
|
+
import { isPresent, parseJSONStrict, tryParsingJSON } from "@mailwoman/core/objects"
|
|
64
64
|
import { sha256File } from "@mailwoman/core/utils"
|
|
65
65
|
import { TextSpliterator } from "spliterator"
|
|
66
66
|
|
|
67
|
+
import { NAME_PRONE_US_SUFFIXES } from "../name-prone-us-suffixes.ts"
|
|
68
|
+
|
|
67
69
|
// ── Types ──────────────────────────────────────────────────────────────────
|
|
68
70
|
|
|
69
71
|
/**
|
|
@@ -136,71 +138,6 @@ export interface GoldenRelabelResult {
|
|
|
136
138
|
* pass 3 — the whole flagged class is 60 rows of 1,906), not from the whole 200-entry table: flagging every possible
|
|
137
139
|
* name-head would mark a third of the corrections and stop being a review artifact.
|
|
138
140
|
*/
|
|
139
|
-
const NAME_PRONE_SUFFIXES: ReadonlySet<USStreetSuffix> = new Set<USStreetSuffix>([
|
|
140
|
-
"BEACH",
|
|
141
|
-
"BROOK",
|
|
142
|
-
"BROOKS",
|
|
143
|
-
"CAMP",
|
|
144
|
-
"CENTER",
|
|
145
|
-
"CENTERS",
|
|
146
|
-
"CLUB",
|
|
147
|
-
"COMMON",
|
|
148
|
-
"COMMONS",
|
|
149
|
-
"CREEK",
|
|
150
|
-
"CROSSING",
|
|
151
|
-
"ESTATE",
|
|
152
|
-
"ESTATES",
|
|
153
|
-
"FIELD",
|
|
154
|
-
"FIELDS",
|
|
155
|
-
"FOREST",
|
|
156
|
-
"GARDEN",
|
|
157
|
-
"GARDENS",
|
|
158
|
-
"GLEN",
|
|
159
|
-
"GREEN",
|
|
160
|
-
"GREENS",
|
|
161
|
-
"GROVE",
|
|
162
|
-
"GROVES",
|
|
163
|
-
"HARBOR",
|
|
164
|
-
"HEIGHTS",
|
|
165
|
-
"HILL",
|
|
166
|
-
"HILLS",
|
|
167
|
-
"HOLLOW",
|
|
168
|
-
"ISLAND",
|
|
169
|
-
"ISLANDS",
|
|
170
|
-
"ISLE",
|
|
171
|
-
"JUNCTION",
|
|
172
|
-
"LAKE",
|
|
173
|
-
"LAKES",
|
|
174
|
-
"LANDING",
|
|
175
|
-
"MALL",
|
|
176
|
-
"MANOR",
|
|
177
|
-
"MEADOW",
|
|
178
|
-
"MEADOWS",
|
|
179
|
-
"MILL",
|
|
180
|
-
"MILLS",
|
|
181
|
-
"MISSION",
|
|
182
|
-
"ORCHARD",
|
|
183
|
-
"PARK",
|
|
184
|
-
"PASS",
|
|
185
|
-
"PLAZA",
|
|
186
|
-
"POINT",
|
|
187
|
-
"POINTS",
|
|
188
|
-
"RANCH",
|
|
189
|
-
"RIDGE",
|
|
190
|
-
"SHORE",
|
|
191
|
-
"SHORES",
|
|
192
|
-
"SPRING",
|
|
193
|
-
"SPRINGS",
|
|
194
|
-
"SQUARE",
|
|
195
|
-
"STATION",
|
|
196
|
-
"SUMMIT",
|
|
197
|
-
"VALLEY",
|
|
198
|
-
"VIEW",
|
|
199
|
-
"VIEWS",
|
|
200
|
-
"VILLAGE",
|
|
201
|
-
"VISTA",
|
|
202
|
-
])
|
|
203
|
-
|
|
204
141
|
// ── Byte-exact tail split ──────────────────────────────────────────────────
|
|
205
142
|
|
|
206
143
|
interface TailSplit {
|
|
@@ -381,7 +318,7 @@ export function relabelGoldenStreetRow(
|
|
|
381
318
|
throw new Error(`golden-relabel: span reconstruction failed for ${JSON.stringify(street)}`)
|
|
382
319
|
}
|
|
383
320
|
|
|
384
|
-
if (canonical &&
|
|
321
|
+
if (canonical && NAME_PRONE_US_SUFFIXES.has(canonical)) {
|
|
385
322
|
flags.push({
|
|
386
323
|
kind: "name-prone-suffix",
|
|
387
324
|
detail: `${canonical} heads proper names as often as street types`,
|
|
@@ -679,7 +616,7 @@ export async function relabelGoldenDirectory(
|
|
|
679
616
|
function renderDeckMarkdown(deck: GoldenRelabelDeckEntry[], parent: string, version: string): string {
|
|
680
617
|
const span = (components: Record<string, string>): string =>
|
|
681
618
|
[components.street_prefix, components.street, components.street_suffix]
|
|
682
|
-
.filter(
|
|
619
|
+
.filter(isPresent)
|
|
683
620
|
.map((s) => JSON.stringify(s))
|
|
684
621
|
.join(" + ")
|
|
685
622
|
|
package/src/tools/index.ts
CHANGED
|
@@ -4,8 +4,7 @@
|
|
|
4
4
|
* @author Teffen Ellis, et al.
|
|
5
5
|
*
|
|
6
6
|
* Corpus operator tools — the `run()`-style modules behind `mailwoman corpus …` commands. No argv,
|
|
7
|
-
* no `process.exit`: commands own parsing, rendering, and exit codes
|
|
8
|
-
* scripts→Pastel spec).
|
|
7
|
+
* no `process.exit`: commands own parsing, rendering, and exit codes.
|
|
9
8
|
*/
|
|
10
9
|
|
|
11
10
|
export * from "./align-shard.ts"
|
|
@@ -23,6 +22,7 @@ export * from "./lint-shard.ts"
|
|
|
23
22
|
export * from "./lint-shard-vocab.ts"
|
|
24
23
|
export * from "./shard-kryptonite.ts"
|
|
25
24
|
export * from "./overture-subvenue.ts"
|
|
25
|
+
export * from "./postcode-triples.ts"
|
|
26
26
|
export * from "./sub-venue-lexicon.ts"
|
|
27
27
|
export * from "./sub-venue-promotions.ts"
|
|
28
28
|
export * from "./shard-translit.ts"
|
package/src/tools/ingest-csv.ts
CHANGED
|
@@ -241,7 +241,6 @@ async function runIngest(opts: IngestOptions): Promise<void> {
|
|
|
241
241
|
const createTableSQL = `CREATE TABLE IF NOT EXISTS "${opts.tableName}" (\n ${colDefs}\n);`
|
|
242
242
|
|
|
243
243
|
const tempCols = columns.map((c) => `"${c.name}"`).join(", ")
|
|
244
|
-
const insertSQL = `INSERT INTO "${opts.tableName}" (${tempCols})\nSELECT ${tempCols} FROM temp."${opts.tableName}_source";`
|
|
245
244
|
|
|
246
245
|
process.stderr.write(`\nSchema inferred from ${sampleRows.length} sample rows:\n`)
|
|
247
246
|
process.stderr.write(`${createTableSQL}\n\n`)
|
|
@@ -264,17 +263,6 @@ async function runIngest(opts: IngestOptions): Promise<void> {
|
|
|
264
263
|
|
|
265
264
|
// Use the .import approach via a temp table, then INSERT INTO ... SELECT to handle
|
|
266
265
|
// NULL normalization and type coercion.
|
|
267
|
-
const csvBasename = basename(opts.inputPath)
|
|
268
|
-
|
|
269
|
-
const importSQL = [
|
|
270
|
-
`CREATE TEMP TABLE "${opts.tableName}_source" (${colDefs});`,
|
|
271
|
-
`.mode csv`,
|
|
272
|
-
`.separator "${opts.separator}"`,
|
|
273
|
-
`.import "${csvBasename}" --skip ${opts.skipLines + (opts.hasHeader ? 1 : 0)} --schema temp ${opts.tableName}_source`,
|
|
274
|
-
insertSQL,
|
|
275
|
-
`DROP TABLE temp."${opts.tableName}_source";`,
|
|
276
|
-
]
|
|
277
|
-
|
|
278
266
|
// better-sqlite3 doesn't support .import natively, so we use a different approach:
|
|
279
267
|
// Read the CSV line-by-line and INSERT in a transaction.
|
|
280
268
|
process.stderr.write(`Importing rows...\n`)
|
|
@@ -373,7 +361,6 @@ async function runIngest(opts: IngestOptions): Promise<void> {
|
|
|
373
361
|
db.close()
|
|
374
362
|
|
|
375
363
|
// Write MANIFEST
|
|
376
|
-
const fileSize = (await import("node:fs/promises")).stat
|
|
377
364
|
const stat = await (await import("node:fs/promises")).stat(opts.outputPath)
|
|
378
365
|
|
|
379
366
|
const manifest = {
|