japanese_address_parser 3.0.5 → 3.1.1

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 (54) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +22 -2
  3. data/Gemfile.lock +6 -6
  4. data/js/node_modules/.package-lock.json +86 -1
  5. data/js/node_modules/@geolonia/normalize-japanese-addresses/dist/lib/cacheRegexes.d.ts +9 -2
  6. data/js/node_modules/@geolonia/normalize-japanese-addresses/dist/main-browser.js +141 -25
  7. data/js/node_modules/@geolonia/normalize-japanese-addresses/dist/main-es.d.ts +3 -0
  8. data/js/node_modules/@geolonia/normalize-japanese-addresses/dist/main-es.js +1922 -0
  9. data/js/node_modules/@geolonia/normalize-japanese-addresses/dist/main-node.d.ts +6 -0
  10. data/js/node_modules/@geolonia/normalize-japanese-addresses/dist/main-node.js +203 -54
  11. data/js/node_modules/@geolonia/normalize-japanese-addresses/dist/normalize.d.ts +47 -3
  12. data/js/node_modules/@geolonia/normalize-japanese-addresses/package.json +9 -5
  13. data/js/node_modules/@geolonia/normalize-japanese-addresses/rollup.config.ts +9 -0
  14. data/js/node_modules/@geolonia/normalize-japanese-addresses/src/config.ts +1 -0
  15. data/js/node_modules/@geolonia/normalize-japanese-addresses/src/lib/cacheRegexes.ts +71 -11
  16. data/js/node_modules/@geolonia/normalize-japanese-addresses/src/lib/dict.ts +3 -2
  17. data/js/node_modules/@geolonia/normalize-japanese-addresses/src/lib/kan2num.ts +6 -2
  18. data/js/node_modules/@geolonia/normalize-japanese-addresses/src/main-es.ts +4 -0
  19. data/js/node_modules/@geolonia/normalize-japanese-addresses/src/main-node.ts +41 -12
  20. data/js/node_modules/@geolonia/normalize-japanese-addresses/src/normalize.ts +165 -37
  21. data/js/package-lock.json +7 -7
  22. data/js/package.json +1 -1
  23. data/lib/japanese_address_parser/data/03-03206.csv +1 -0
  24. data/lib/japanese_address_parser/data/04-04421.csv +8 -8
  25. data/lib/japanese_address_parser/data/05-05203.csv +5 -0
  26. data/lib/japanese_address_parser/data/08-08222.csv +4 -0
  27. data/lib/japanese_address_parser/data/11-11442.csv +2 -0
  28. data/lib/japanese_address_parser/data/13-13225.csv +3 -0
  29. data/lib/japanese_address_parser/data/14-14134.csv +3 -0
  30. data/lib/japanese_address_parser/data/15-15104.csv +1 -1
  31. data/lib/japanese_address_parser/data/15-15222.csv +1 -1
  32. data/lib/japanese_address_parser/data/15-15225.csv +1 -1
  33. data/lib/japanese_address_parser/data/18-18202.csv +1 -1
  34. data/lib/japanese_address_parser/data/22-22102.csv +6 -0
  35. data/lib/japanese_address_parser/data/23-23202.csv +1 -0
  36. data/lib/japanese_address_parser/data/23-23207.csv +5 -0
  37. data/lib/japanese_address_parser/data/23-23213.csv +1 -0
  38. data/lib/japanese_address_parser/data/23-23236.csv +1 -0
  39. data/lib/japanese_address_parser/data/25-25206.csv +4 -0
  40. data/lib/japanese_address_parser/data/27-27212.csv +4 -0
  41. data/lib/japanese_address_parser/data/28-28108.csv +1 -0
  42. data/lib/japanese_address_parser/data/28-28204.csv +1 -1
  43. data/lib/japanese_address_parser/data/28-28226.csv +1 -0
  44. data/lib/japanese_address_parser/data/29-29201.csv +1 -1
  45. data/lib/japanese_address_parser/data/34-34207.csv +3 -0
  46. data/lib/japanese_address_parser/data/35-35215.csv +3 -0
  47. data/lib/japanese_address_parser/data/38-38204.csv +17 -0
  48. data/lib/japanese_address_parser/data/40-40131.csv +1 -0
  49. data/lib/japanese_address_parser/data/40-40342.csv +4 -0
  50. data/lib/japanese_address_parser/data/44-44201.csv +27 -0
  51. data/lib/japanese_address_parser/data/46-46201.csv +4 -0
  52. data/lib/japanese_address_parser/data/47-47205.csv +4 -0
  53. data/lib/japanese_address_parser/version.rb +1 -1
  54. metadata +6 -3
@@ -1,3 +1,9 @@
1
1
  import * as Normalize from './normalize';
2
+ export declare const requestHandlers: {
3
+ file: (fileURL: URL) => {
4
+ json: () => Promise<any>;
5
+ };
6
+ http: (fileURL: URL) => Promise<Response>;
7
+ };
2
8
  export declare const config: Normalize.Config;
3
9
  export declare const normalize: Normalize.Normalizer;
@@ -78,6 +78,7 @@ function __generator(thisArg, body) {
78
78
 
79
79
  var gh_pages_endpoint = 'https://geolonia.github.io/japanese-addresses/api/ja';
80
80
  var currentConfig = {
81
+ interfaceVersion: 1,
81
82
  japaneseAddressesApi: gh_pages_endpoint,
82
83
  townCacheSize: 1000,
83
84
  };
@@ -85,8 +86,13 @@ var currentConfig = {
85
86
  var kan2num = function (string) {
86
87
  var kanjiNumbers = japaneseNumeral.findKanjiNumbers(string);
87
88
  for (var i = 0; i < kanjiNumbers.length; i++) {
88
- // @ts-ignore
89
- string = string.replace(kanjiNumbers[i], japaneseNumeral.kanji2number(kanjiNumbers[i]));
89
+ try {
90
+ // @ts-ignore
91
+ string = string.replace(kanjiNumbers[i], japaneseNumeral.kanji2number(kanjiNumbers[i]));
92
+ }
93
+ catch (error) {
94
+ // ignore
95
+ }
90
96
  }
91
97
  return string;
92
98
  };
@@ -132,8 +138,8 @@ var patchAddr = function (pref, city, town, addr) {
132
138
  };
133
139
 
134
140
  // JIS 第2水準 => 第1水準 及び 旧字体 => 新字体
135
- var JIS_OLD_KANJI = '亞,圍,壹,榮,驛,應,櫻,假,會,懷,覺,樂,陷,歡,氣,戲,據,挾,區,徑,溪,輕,藝,儉,圈,權,嚴,恆,國,齋,雜,蠶,殘,兒,實,釋,從,縱,敍,燒,條,剩,壤,釀,眞,盡,醉,髓,聲,竊,淺,錢,禪,爭,插,騷,屬,對,滯,擇,單,斷,癡,鑄,敕,鐵,傳,黨,鬪,屆,腦,廢,發,蠻,拂,邊,瓣,寶,沒,滿,藥,餘,樣,亂,兩,禮,靈,爐,灣,惡,醫,飮,營,圓,歐,奧,價,繪,擴,學,罐,勸,觀,歸,犧,擧,狹,驅,莖,經,繼,缺,劍,檢,顯,廣,鑛,碎,劑,參,慘,絲,辭,舍,壽,澁,肅,將,證,乘,疊,孃,觸,寢,圖,穗,樞,齊,攝,戰,潛,雙,莊,裝,藏,續,體,臺,澤,膽,彈,蟲,廳,鎭,點,燈,盜,獨,貳,霸,賣,髮,祕,佛,變,辯,豐,飜,默,與,譽,謠,覽,獵,勵,齡,勞,壓,爲,隱,衞,鹽,毆,穩,畫,壞,殼,嶽,卷,關,顏,僞,舊,峽,曉,勳,惠,螢,鷄,縣,險,獻,驗,效,號,濟,册,棧,贊,齒,濕,寫,收,獸,處,稱,奬,淨,繩,讓,囑,愼,粹,隨,數,靜,專,踐,纖,壯,搜,總,臟,墮,帶,瀧,擔,團,遲,晝,聽,遞,轉,當,稻,讀,惱,拜,麥,拔,濱,竝,辨,舖,襃,萬,譯,豫,搖,來,龍,壘,隸,戀,樓,鰺,鶯,蠣,攪,竈,灌,諫,頸,礦,蘂,靱,賤,壺,礪,檮,濤,邇,蠅,檜,儘,藪,籠,彌'.split(/,/);
136
- var JIS_NEW_KANJI = '亜,囲,壱,栄,駅,応,桜,仮,会,懐,覚,楽,陥,歓,気,戯,拠,挟,区,径,渓,軽,芸,倹,圏,権,厳,恒,国,斎,雑,蚕,残,児,実,釈,従,縦,叙,焼,条,剰,壌,醸,真,尽,酔,髄,声,窃,浅,銭,禅,争,挿,騒,属,対,滞,択,単,断,痴,鋳,勅,鉄,伝,党,闘,届,脳,廃,発,蛮,払,辺,弁,宝,没,満,薬,余,様,乱,両,礼,霊,炉,湾,悪,医,飲,営,円,欧,奥,価,絵,拡,学,缶,勧,観,帰,犠,挙,狭,駆,茎,経,継,欠,剣,検,顕,広,鉱,砕,剤,参,惨,糸,辞,舎,寿,渋,粛,将,証,乗,畳,嬢,触,寝,図,穂,枢,斉,摂,戦,潜,双,荘,装,蔵,続,体,台,沢,胆,弾,虫,庁,鎮,点,灯,盗,独,弐,覇,売,髪,秘,仏,変,弁,豊,翻,黙,与,誉,謡,覧,猟,励,齢,労,圧,為,隠,衛,塩,殴,穏,画,壊,殻,岳,巻,関,顔,偽,旧,峡,暁,勲,恵,蛍,鶏,県,険,献,験,効,号,済,冊,桟,賛,歯,湿,写,収,獣,処,称,奨,浄,縄,譲,嘱,慎,粋,随,数,静,専,践,繊,壮,捜,総,臓,堕,帯,滝,担,団,遅,昼,聴,逓,転,当,稲,読,悩,拝,麦,抜,浜,並,弁,舗,褒,万,訳,予,揺,来,竜,塁,隷,恋,楼,鯵,鴬,蛎,撹,竃,潅,諌,頚,砿,蕊,靭,賎,壷,砺,梼,涛,迩,蝿,桧,侭,薮,篭,弥'.split(/,/);
141
+ var JIS_OLD_KANJI = '亞,圍,壹,榮,驛,應,櫻,假,會,懷,覺,樂,陷,歡,氣,戲,據,挾,區,徑,溪,輕,藝,儉,圈,權,嚴,恆,國,齋,雜,蠶,殘,兒,實,釋,從,縱,敍,燒,條,剩,壤,釀,眞,盡,醉,髓,聲,竊,淺,錢,禪,爭,插,騷,屬,對,滯,擇,單,斷,癡,鑄,敕,鐵,傳,黨,鬪,屆,腦,廢,發,蠻,拂,邊,瓣,寶,沒,滿,藥,餘,樣,亂,兩,禮,靈,爐,灣,惡,醫,飮,營,圓,歐,奧,價,繪,擴,學,罐,勸,觀,歸,犧,擧,狹,驅,莖,經,繼,缺,劍,檢,顯,廣,鑛,碎,劑,參,慘,絲,辭,舍,壽,澁,肅,將,證,乘,疊,孃,觸,寢,圖,穗,樞,齊,攝,戰,潛,雙,莊,裝,藏,續,體,臺,澤,膽,彈,蟲,廳,鎭,點,燈,盜,獨,貳,霸,賣,髮,祕,佛,變,辯,豐,飜,默,與,譽,謠,覽,獵,勵,齡,勞,壓,爲,隱,衞,鹽,毆,穩,畫,壞,殼,嶽,卷,關,顏,僞,舊,峽,曉,勳,惠,螢,鷄,縣,險,獻,驗,效,號,濟,册,棧,贊,齒,濕,寫,收,獸,處,稱,奬,淨,繩,讓,囑,愼,粹,隨,數,靜,專,踐,纖,壯,搜,總,臟,墮,帶,瀧,擔,團,遲,晝,聽,遞,轉,當,稻,讀,惱,拜,麥,拔,濱,竝,辨,舖,襃,萬,譯,豫,搖,來,龍,壘,隸,戀,樓,鰺,鶯,蠣,攪,竈,灌,諫,頸,礦,蘂,靱,賤,壺,礪,檮,濤,邇,蠅,檜,儘,藪,籠,彌,麩'.split(/,/);
142
+ var JIS_NEW_KANJI = '亜,囲,壱,栄,駅,応,桜,仮,会,懐,覚,楽,陥,歓,気,戯,拠,挟,区,径,渓,軽,芸,倹,圏,権,厳,恒,国,斎,雑,蚕,残,児,実,釈,従,縦,叙,焼,条,剰,壌,醸,真,尽,酔,髄,声,窃,浅,銭,禅,争,挿,騒,属,対,滞,択,単,断,痴,鋳,勅,鉄,伝,党,闘,届,脳,廃,発,蛮,払,辺,弁,宝,没,満,薬,余,様,乱,両,礼,霊,炉,湾,悪,医,飲,営,円,欧,奥,価,絵,拡,学,缶,勧,観,帰,犠,挙,狭,駆,茎,経,継,欠,剣,検,顕,広,鉱,砕,剤,参,惨,糸,辞,舎,寿,渋,粛,将,証,乗,畳,嬢,触,寝,図,穂,枢,斉,摂,戦,潜,双,荘,装,蔵,続,体,台,沢,胆,弾,虫,庁,鎮,点,灯,盗,独,弐,覇,売,髪,秘,仏,変,弁,豊,翻,黙,与,誉,謡,覧,猟,励,齢,労,圧,為,隠,衛,塩,殴,穏,画,壊,殻,岳,巻,関,顔,偽,旧,峡,暁,勲,恵,蛍,鶏,県,険,献,験,効,号,済,冊,桟,賛,歯,湿,写,収,獣,処,称,奨,浄,縄,譲,嘱,慎,粋,随,数,静,専,践,繊,壮,捜,総,臓,堕,帯,滝,担,団,遅,昼,聴,逓,転,当,稲,読,悩,拝,麦,抜,浜,並,弁,舗,褒,万,訳,予,揺,来,竜,塁,隷,恋,楼,鯵,鴬,蛎,撹,竃,潅,諌,頚,砿,蕊,靭,賎,壷,砺,梼,涛,迩,蝿,桧,侭,薮,篭,弥,麸'.split(/,/);
137
143
  var JIS_KANJI_REGEX_PATTERNS = JIS_OLD_KANJI.map(function (old, i) {
138
144
  var pattern = old + "|" + JIS_NEW_KANJI[i];
139
145
  return [pattern, old, JIS_NEW_KANJI[i]];
@@ -152,6 +158,7 @@ var toRegexPattern = function (string) {
152
158
  _str = _str
153
159
  .replace(/三栄町|四谷三栄町/g, '(三栄町|四谷三栄町)')
154
160
  .replace(/鬮野川|くじ野川|くじの川/g, '(鬮野川|くじ野川|くじの川)')
161
+ .replace(/柿碕町|柿さき町/g, '(柿碕町|柿さき町)')
155
162
  .replace(/通り|とおり/g, '(通り|とおり)')
156
163
  .replace(/埠頭|ふ頭/g, '(埠頭|ふ頭)')
157
164
  .replace(/番町|番丁/g, '(番町|番丁)')
@@ -190,6 +197,7 @@ var cachedPrefectures = undefined;
190
197
  var cachedTowns = {};
191
198
  var cachedGaikuListItem = {};
192
199
  var cachedResidentials = {};
200
+ var cachedAddrs = {}; // TODO: use LRU
193
201
  var cachedSameNamedPrefectureCityRegexPatterns = undefined;
194
202
  var getPrefectures = function () { return __awaiter(void 0, void 0, void 0, function () {
195
203
  var prefsResp, data;
@@ -199,7 +207,7 @@ var getPrefectures = function () { return __awaiter(void 0, void 0, void 0, func
199
207
  if (typeof cachedPrefectures !== 'undefined') {
200
208
  return [2 /*return*/, cachedPrefectures];
201
209
  }
202
- return [4 /*yield*/, __internals.fetch('.json')]; // ja.json
210
+ return [4 /*yield*/, __internals.fetch('.json', { level: 1 })]; // ja.json
203
211
  case 1:
204
212
  prefsResp = _a.sent() // ja.json
205
213
  ;
@@ -253,7 +261,7 @@ var getTowns = function (pref, city) { return __awaiter(void 0, void 0, void 0,
253
261
  if (typeof cachedTown !== 'undefined') {
254
262
  return [2 /*return*/, cachedTown];
255
263
  }
256
- return [4 /*yield*/, __internals.fetch(['', encodeURI(pref), encodeURI(city) + '.json'].join('/'))];
264
+ return [4 /*yield*/, __internals.fetch(['', encodeURI(pref), encodeURI(city) + '.json'].join('/'), { level: 3, pref: pref, city: city })];
257
265
  case 1:
258
266
  townsResp = _a.sent();
259
267
  return [4 /*yield*/, townsResp.json()];
@@ -268,7 +276,10 @@ var getGaikuList = function (pref, city, town) { return __awaiter(void 0, void 0
268
276
  return __generator(this, function (_b) {
269
277
  switch (_b.label) {
270
278
  case 0:
271
- cacheKey = pref + "-" + city + "-" + town;
279
+ if (currentConfig.interfaceVersion > 1) {
280
+ throw new Error("Invalid config.interfaceVersion: " + currentConfig.interfaceVersion + "'}. Please set config.interfaceVersion to 1.");
281
+ }
282
+ cacheKey = pref + "-" + city + "-" + town + "-v" + currentConfig.interfaceVersion;
272
283
  cache = cachedGaikuListItem[cacheKey];
273
284
  if (typeof cache !== 'undefined') {
274
285
  return [2 /*return*/, cache];
@@ -296,7 +307,10 @@ var getResidentials = function (pref, city, town) { return __awaiter(void 0, voi
296
307
  return __generator(this, function (_b) {
297
308
  switch (_b.label) {
298
309
  case 0:
299
- cacheKey = pref + "-" + city + "-" + town;
310
+ if (currentConfig.interfaceVersion > 1) {
311
+ throw new Error("Invalid config.interfaceVersion: " + currentConfig.interfaceVersion + "'}. Please set config.interfaceVersion to 1.");
312
+ }
313
+ cacheKey = pref + "-" + city + "-" + town + "-v" + currentConfig.interfaceVersion;
300
314
  cache = cachedResidentials[cacheKey];
301
315
  if (typeof cache !== 'undefined') {
302
316
  return [2 /*return*/, cache];
@@ -330,6 +344,39 @@ var getResidentials = function (pref, city, town) { return __awaiter(void 0, voi
330
344
  }
331
345
  });
332
346
  }); };
347
+ var getAddrs = function (pref, city, town) { return __awaiter(void 0, void 0, void 0, function () {
348
+ var cacheKey, cache, addrsResp, addrs;
349
+ return __generator(this, function (_b) {
350
+ switch (_b.label) {
351
+ case 0:
352
+ if (currentConfig.interfaceVersion < 2) {
353
+ throw new Error("Invalid config.interfaceVersion: " + currentConfig.interfaceVersion + "'}. Please set config.interfaceVersion to 2 or higher");
354
+ }
355
+ cacheKey = pref + "-" + city + "-" + town + "-v" + currentConfig.interfaceVersion;
356
+ cache = cachedAddrs[cacheKey];
357
+ if (typeof cache !== 'undefined') {
358
+ return [2 /*return*/, cache];
359
+ }
360
+ return [4 /*yield*/, __internals.fetch(['', encodeURI(pref), encodeURI(city), encodeURI(town) + '.json'].join('/'), { level: 8, pref: pref, city: city, town: town })];
361
+ case 1:
362
+ addrsResp = _b.sent();
363
+ _b.label = 2;
364
+ case 2:
365
+ _b.trys.push([2, 4, , 5]);
366
+ return [4 /*yield*/, addrsResp.json()];
367
+ case 3:
368
+ addrs = (_b.sent());
369
+ return [3 /*break*/, 5];
370
+ case 4:
371
+ _b.sent();
372
+ addrs = [];
373
+ return [3 /*break*/, 5];
374
+ case 5:
375
+ addrs.sort(function (res1, res2) { return res1.addr.length - res2.addr.length; });
376
+ return [2 /*return*/, (cachedAddrs[cacheKey] = addrs)];
377
+ }
378
+ });
379
+ }); };
333
380
  // 十六町 のように漢数字と町が連結しているか
334
381
  var isKanjiNumberFollewedByCho = function (targetTownName) {
335
382
  var xCho = targetTownName.match(/.町/g);
@@ -339,9 +386,9 @@ var isKanjiNumberFollewedByCho = function (targetTownName) {
339
386
  return kanjiNumbers.length > 0;
340
387
  };
341
388
  var getTownRegexPatterns = function (pref, city) { return __awaiter(void 0, void 0, void 0, function () {
342
- var cachedResult, pre_towns, townSet, towns, isKyoto, _i, pre_towns_1, town, originalTown, townAbbr, patterns;
343
- return __generator(this, function (_a) {
344
- switch (_a.label) {
389
+ var cachedResult, pre_towns, townSet, towns, isKyoto, _i, pre_towns_1, town, originalTown, townAbbr, patterns, _a, towns_1, town, chomeMatch, chomeNamePart, chomeNum, pattern;
390
+ return __generator(this, function (_b) {
391
+ switch (_b.label) {
345
392
  case 0:
346
393
  cachedResult = cachedTownRegexes.get(pref + "-" + city);
347
394
  if (typeof cachedResult !== 'undefined') {
@@ -349,7 +396,7 @@ var getTownRegexPatterns = function (pref, city) { return __awaiter(void 0, void
349
396
  }
350
397
  return [4 /*yield*/, getTowns(pref, city)];
351
398
  case 1:
352
- pre_towns = _a.sent();
399
+ pre_towns = _b.sent();
353
400
  townSet = new Set(pre_towns.map(function (town) { return town.town; }));
354
401
  towns = [];
355
402
  isKyoto = city.match(/^京都市/);
@@ -415,6 +462,18 @@ var getTownRegexPatterns = function (pref, city) { return __awaiter(void 0, void
415
462
  }));
416
463
  return [town, pattern];
417
464
  });
465
+ // X丁目の丁目なしの数字だけ許容するため、最後に数字だけ追加していく
466
+ for (_a = 0, towns_1 = towns; _a < towns_1.length; _a++) {
467
+ town = towns_1[_a];
468
+ chomeMatch = town.town.match(/([^一二三四五六七八九十]+)([一二三四五六七八九十]+)(丁目?)/);
469
+ if (!chomeMatch) {
470
+ continue;
471
+ }
472
+ chomeNamePart = chomeMatch[1];
473
+ chomeNum = chomeMatch[2];
474
+ pattern = toRegexPattern("^" + chomeNamePart + "(" + chomeNum + "|" + kan2num(chomeNum) + ")");
475
+ patterns.push([town, pattern]);
476
+ }
418
477
  cachedTownRegexes.set(pref + "-" + city, patterns);
419
478
  return [2 /*return*/, patterns];
420
479
  }
@@ -538,10 +597,32 @@ var normalizeResidentialPart = function (addr, pref, city, town) { return __awai
538
597
  }
539
598
  });
540
599
  }); };
600
+ var normalizeAddrPart = function (addr, pref, city, town) { return __awaiter(void 0, void 0, void 0, function () {
601
+ var addrListItem, addrItem, other;
602
+ return __generator(this, function (_a) {
603
+ switch (_a.label) {
604
+ case 0: return [4 /*yield*/, getAddrs(pref, city, town)
605
+ // 住居表示住所、および地番住所が見つからなかった
606
+ ];
607
+ case 1:
608
+ addrListItem = _a.sent();
609
+ // 住居表示住所、および地番住所が見つからなかった
610
+ if (addrListItem.length === 0) {
611
+ return [2 /*return*/, null];
612
+ }
613
+ addrItem = addrListItem.find(function (item) { return addr.startsWith(item.addr); });
614
+ if (addrItem) {
615
+ other = addr.replace(addrItem.addr, '').trim();
616
+ return [2 /*return*/, { addr: addrItem.addr, other: other, lat: addrItem.lat, lng: addrItem.lng }];
617
+ }
618
+ return [2 /*return*/, null];
619
+ }
620
+ });
621
+ }); };
541
622
  var normalize$1 = function (address, _option) {
542
623
  if (_option === void 0) { _option = defaultOption; }
543
624
  return __awaiter(void 0, void 0, void 0, function () {
544
- var option, addr, pref, city, town, lat, lng, level, normalized, prefectures, prefs, prefPatterns, sameNamedPrefectureCityRegexPatterns, i, _a, prefectureCity, reg, match, i, _b, _pref, pattern, match, matched, _pref, cities, cityPatterns, i, _c, _city, pattern, match, i, normalized_1, cities, cityPatterns, i, _d, _city, pattern, match, result;
625
+ var option, addr, pref, city, town, lat, lng, level, normalized, prefectures, prefs, prefPatterns, sameNamedPrefectureCityRegexPatterns, i, _a, prefectureCity, reg, match, i, _b, _pref, pattern, match, matched, _pref, cities, cityPatterns, i, _c, _city, pattern, match, i, normalized_1, cities, cityPatterns, i, _d, _city, pattern, match, normalizedAddrPart, other, result, result;
545
626
  return __generator(this, function (_e) {
546
627
  switch (_e.label) {
547
628
  case 0:
@@ -684,7 +765,7 @@ var normalize$1 = function (address, _option) {
684
765
  });
685
766
  })
686
767
  .replace(/(([0-9〇一二三四五六七八九十百千]+)(番地?)([0-9〇一二三四五六七八九十百千]+)号)\s*(.+)/, '$1 $5')
687
- .replace(/([0-9〇一二三四五六七八九十百千]+)(番地?)([0-9〇一二三四五六七八九十百千]+)号?/, '$1-$3')
768
+ .replace(/([0-9〇一二三四五六七八九十百千]+)\s*(番地?)\s*([0-9〇一二三四五六七八九十百千]+)\s*号?/, '$1-$3')
688
769
  .replace(/([0-9〇一二三四五六七八九十百千]+)番地?/, '$1')
689
770
  .replace(/([0-9〇一二三四五六七八九十百千]+)の/g, '$1-')
690
771
  .replace(/([0-9〇一二三四五六七八九十百千]+)[--﹣−‐⁃‑‒–—﹘―⎯⏤ーー─━]/g, function (match) {
@@ -701,7 +782,7 @@ var normalize$1 = function (address, _option) {
701
782
  // `-1` のようなケース
702
783
  return kan2num(s);
703
784
  })
704
- .replace(/-[^0-9]+([0-9〇一二三四五六七八九十百千]+)/, function (s) {
785
+ .replace(/-[^0-9]([0-9〇一二三四五六七八九十百千]+)/, function (s) {
705
786
  // `-あ1` のようなケース
706
787
  return kan2num(zen2han(s));
707
788
  })
@@ -714,12 +795,52 @@ var normalize$1 = function (address, _option) {
714
795
  _e.label = 8;
715
796
  case 8:
716
797
  addr = patchAddr(pref, city, town, addr);
717
- if (!(option.level > 3 && normalized && town)) return [3 /*break*/, 10];
718
- return [4 /*yield*/, normalizeResidentialPart(addr, pref, city, town)];
798
+ if (pref)
799
+ level = level + 1;
800
+ if (city)
801
+ level = level + 1;
802
+ if (town)
803
+ level = level + 1;
804
+ if (option.level <= 3 || level < 3) {
805
+ return [2 /*return*/, { pref: pref, city: city, town: town, addr: addr, level: level, lat: lat, lng: lng }];
806
+ }
807
+ if (!(currentConfig.interfaceVersion === 2)) return [3 /*break*/, 10];
808
+ return [4 /*yield*/, normalizeAddrPart(addr, pref, city, town)];
719
809
  case 9:
720
- normalized = _e.sent();
721
- _e.label = 10;
810
+ normalizedAddrPart = _e.sent();
811
+ other = undefined;
812
+ if (normalizedAddrPart) {
813
+ addr = normalizedAddrPart.addr;
814
+ if (normalizedAddrPart.other) {
815
+ other = normalizedAddrPart.other;
816
+ }
817
+ if (normalizedAddrPart.lat !== null)
818
+ lat = parseFloat(normalizedAddrPart.lat);
819
+ if (normalizedAddrPart.lng !== null)
820
+ lng = parseFloat(normalizedAddrPart.lng);
821
+ level = 8;
822
+ }
823
+ result = {
824
+ pref: pref,
825
+ city: city,
826
+ town: town,
827
+ addr: addr,
828
+ level: level,
829
+ lat: lat,
830
+ lng: lng,
831
+ };
832
+ if (other) {
833
+ result.other = other;
834
+ }
835
+ return [2 /*return*/, result];
722
836
  case 10:
837
+ if (!(currentConfig.interfaceVersion === 1)) return [3 /*break*/, 13];
838
+ if (!(option.level > 3 && normalized && town)) return [3 /*break*/, 12];
839
+ return [4 /*yield*/, normalizeResidentialPart(addr, pref, city, town)];
840
+ case 11:
841
+ normalized = _e.sent();
842
+ _e.label = 12;
843
+ case 12:
723
844
  if (normalized) {
724
845
  lat = parseFloat(normalized.lat);
725
846
  lng = parseFloat(normalized.lng);
@@ -728,12 +849,6 @@ var normalize$1 = function (address, _option) {
728
849
  lat = null;
729
850
  lng = null;
730
851
  }
731
- if (pref)
732
- level = level + 1;
733
- if (city)
734
- level = level + 1;
735
- if (town)
736
- level = level + 1;
737
852
  result = {
738
853
  pref: pref,
739
854
  city: city,
@@ -753,45 +868,79 @@ var normalize$1 = function (address, _option) {
753
868
  result.level = 8;
754
869
  }
755
870
  return [2 /*return*/, result];
871
+ case 13: throw new Error('invalid interfaceVersion');
756
872
  }
757
873
  });
758
874
  });
759
875
  };
760
876
 
761
- var fetchOrReadFile = function (input) { return __awaiter(void 0, void 0, void 0, function () {
762
- var fileURL, filePath_1;
763
- return __generator(this, function (_a) {
764
- fileURL = new URL("" + config$1.japaneseAddressesApi + input);
765
- if (fileURL.protocol === 'http:' || fileURL.protocol === 'https:') {
766
- if (config$1.geoloniaApiKey) {
767
- fileURL.search = "?geolonia-api-key=" + config$1.geoloniaApiKey;
768
- }
769
- return [2 /*return*/, unfetch__default['default'](fileURL.toString())];
770
- }
771
- else if (fileURL.protocol === 'file:') {
772
- filePath_1 = decodeURI(fileURL.pathname);
773
- return [2 /*return*/, {
774
- json: function () { return __awaiter(void 0, void 0, void 0, function () {
775
- var contents;
776
- return __generator(this, function (_a) {
777
- switch (_a.label) {
778
- case 0: return [4 /*yield*/, fs.promises.readFile(filePath_1)];
779
- case 1:
780
- contents = _a.sent();
781
- return [2 /*return*/, JSON.parse(contents.toString('utf-8'))];
782
- }
783
- });
784
- }); },
785
- }];
786
- }
787
- else {
788
- throw new Error("Unknown URL schema: " + fileURL.protocol);
877
+ var requestHandlers = {
878
+ file: function (fileURL) {
879
+ var filePath = process.platform === 'win32'
880
+ ? decodeURI(fileURL.pathname).substr(1)
881
+ : decodeURI(fileURL.pathname);
882
+ return {
883
+ json: function () { return __awaiter(void 0, void 0, void 0, function () {
884
+ var contents;
885
+ return __generator(this, function (_a) {
886
+ switch (_a.label) {
887
+ case 0: return [4 /*yield*/, fs.promises.readFile(filePath)];
888
+ case 1:
889
+ contents = _a.sent();
890
+ return [2 /*return*/, JSON.parse(contents.toString('utf-8'))];
891
+ }
892
+ });
893
+ }); },
894
+ };
895
+ },
896
+ http: function (fileURL) {
897
+ if (config$1.geoloniaApiKey) {
898
+ fileURL.search = "?geolonia-api-key=" + config$1.geoloniaApiKey;
789
899
  }
900
+ return unfetch__default['default'](fileURL.toString());
901
+ },
902
+ };
903
+ /**
904
+ * 正規化のためのデータを取得する
905
+ * @param input - Path part like '東京都/文京区.json'
906
+ * @param requestOptions - input を構造化したデータ
907
+ */
908
+ var fetchOrReadFile = function (input, requestOptions) {
909
+ if (requestOptions === void 0) { requestOptions = { level: -1 }; }
910
+ return __awaiter(void 0, void 0, void 0, function () {
911
+ var fileURL, result_1;
912
+ return __generator(this, function (_a) {
913
+ switch (_a.label) {
914
+ case 0:
915
+ fileURL = new URL("" + config$1.japaneseAddressesApi + input);
916
+ if (!(config$1.transformRequest && requestOptions.level !== -1)) return [3 /*break*/, 2];
917
+ return [4 /*yield*/, config$1.transformRequest(fileURL, requestOptions)];
918
+ case 1:
919
+ result_1 = _a.sent();
920
+ return [2 /*return*/, {
921
+ json: function () { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) {
922
+ return [2 /*return*/, Promise.resolve(result_1)];
923
+ }); }); },
924
+ }];
925
+ case 2:
926
+ if (fileURL.protocol === 'http:' || fileURL.protocol === 'https:') {
927
+ return [2 /*return*/, requestHandlers.http(fileURL)];
928
+ }
929
+ else if (fileURL.protocol === 'file:') {
930
+ return [2 /*return*/, requestHandlers.file(fileURL)];
931
+ }
932
+ else {
933
+ throw new Error("Unknown URL schema: " + fileURL.protocol);
934
+ }
935
+ case 3: return [2 /*return*/];
936
+ }
937
+ });
790
938
  });
791
- }); };
939
+ };
792
940
  __internals.fetch = fetchOrReadFile;
793
941
  var config = config$1;
794
942
  var normalize = normalize$1;
795
943
 
796
944
  exports.config = config;
797
945
  exports.normalize = normalize;
946
+ exports.requestHandlers = requestHandlers;
@@ -1,18 +1,35 @@
1
+ import { PrefectureList, TownList, AddrList } from './lib/cacheRegexes';
2
+ declare type TransformRequestResponse = null | PrefectureList | TownList | AddrList;
3
+ export declare type TransformRequestQuery = {
4
+ level: number;
5
+ pref?: string;
6
+ city?: string;
7
+ town?: string;
8
+ };
9
+ export declare type TransformRequestFunction = (url: URL, query: TransformRequestQuery) => TransformRequestResponse | Promise<TransformRequestResponse>;
1
10
  /**
2
11
  * normalize {@link Normalizer} の動作オプション。
3
12
  */
4
13
  export interface Config {
14
+ /**
15
+ * レスポンス型のバージョン。デフォルト 1
16
+ * 1 の場合は jyukyo: string, gaiku: string
17
+ * 2 の場合は addr: string, other: string
18
+ */
19
+ interfaceVersion: number;
5
20
  /** 住所データを URL 形式で指定。 file:// 形式で指定するとローカルファイルを参照できます。 */
6
21
  japaneseAddressesApi: string;
7
22
  /** 町丁目のデータを何件までキャッシュするか。デフォルト 1,000 */
8
23
  townCacheSize: number;
24
+ /** 住所データへのリクエストを変形するオプション。 interfaceVersion === 2 で有効 */
25
+ transformRequest?: TransformRequestFunction;
9
26
  geoloniaApiKey?: string;
10
27
  }
11
28
  export declare const config: Config;
12
29
  /**
13
30
  * 住所の正規化結果として戻されるオブジェクト
14
31
  */
15
- export interface NormalizeResult {
32
+ interface NormalizeResult_v1 {
16
33
  /** 都道府県 */
17
34
  pref: string;
18
35
  /** 市区町村 */
@@ -27,7 +44,7 @@ export interface NormalizeResult {
27
44
  addr: string;
28
45
  /** 緯度。データが存在しない場合は null */
29
46
  lat: number | null;
30
- /** 軽度。データが存在しない場合は null */
47
+ /** 経度。データが存在しない場合は null */
31
48
  lng: number | null;
32
49
  /**
33
50
  * 住所文字列をどこまで判別できたかを表す正規化レベル
@@ -40,6 +57,32 @@ export interface NormalizeResult {
40
57
  */
41
58
  level: number;
42
59
  }
60
+ declare type NormalizeResult_v2 = {
61
+ /** 都道府県 */
62
+ pref: string;
63
+ /** 市区町村 */
64
+ city: string;
65
+ /** 町丁目 */
66
+ town: string;
67
+ /** 住居表示または地番 */
68
+ addr: string;
69
+ /** 正規化後の住所文字列 */
70
+ other?: string;
71
+ /** 緯度。データが存在しない場合は null */
72
+ lat: number | null;
73
+ /** 経度。データが存在しない場合は null */
74
+ lng: number | null;
75
+ /**
76
+ * 住所文字列をどこまで判別できたかを表す正規化レベル
77
+ * - 0 - 都道府県も判別できなかった。
78
+ * - 1 - 都道府県まで判別できた。
79
+ * - 2 - 市区町村まで判別できた。
80
+ * - 3 - 町丁目まで判別できた。
81
+ * - 8 - 住居表示住所の街区符号・住居番号までの判別または地番住所の判別ができた。
82
+ */
83
+ level: number;
84
+ };
85
+ export declare type NormalizeResult = NormalizeResult_v1 | NormalizeResult_v2;
43
86
  /**
44
87
  * 正規化関数の {@link normalize} のオプション
45
88
  */
@@ -64,7 +107,7 @@ export interface Option {
64
107
  * @see https://github.com/geolonia/normalize-japanese-addresses#normalizeaddress-string
65
108
  */
66
109
  export declare type Normalizer = (input: string, option?: Option) => Promise<NormalizeResult>;
67
- export declare type FetchLike = (input: string) => Promise<Response | {
110
+ export declare type FetchLike = (input: string, requestQuery?: TransformRequestQuery) => Promise<Response | {
68
111
  json: () => Promise<unknown>;
69
112
  }>;
70
113
  /**
@@ -74,3 +117,4 @@ export declare const __internals: {
74
117
  fetch: FetchLike;
75
118
  };
76
119
  export declare const normalize: Normalizer;
120
+ export {};
@@ -1,19 +1,23 @@
1
1
  {
2
2
  "name": "@geolonia/normalize-japanese-addresses",
3
- "version": "2.7.3",
3
+ "version": "2.9.2",
4
4
  "description": "",
5
5
  "browser": "./dist/main-browser.js",
6
6
  "main": "./dist/main-node.js",
7
7
  "types": "./dist/normalize.d.ts",
8
8
  "scripts": {
9
- "test": "npm run test:main && npm run test:addresses && npm run test:node && npm run test:residential",
9
+ "test": "npm run test:main && npm run test:addresses && npm run test:node:platform && npm run test:advanced",
10
+ "test:node:platform": "npm run test:node-win || npm run test:node",
10
11
  "test:main": "jest test/main.test.ts",
11
12
  "test:addresses": "jest test/addresses.test.ts",
12
- "test:residential": "jest test/residential.test.ts --runInBand",
13
- "test:node": "curl -sL https://github.com/geolonia/japanese-addresses/archive/refs/heads/master.tar.gz | tar xvfz - -C ./test > /dev/null 2>&1 && jest test/fs.test.ts",
13
+ "test:advanced": "jest test/advanced --runInBand",
14
+ "test:util": "jest test/util.test.ts",
15
+ "test:node": "curl -sL https://github.com/geolonia/japanese-addresses/archive/refs/heads/master.tar.gz | tar xvfz - -C ./test > nul 2>&1 && jest test/fs.test.ts",
16
+ "test:node-win": "curl -sL https://github.com/geolonia/japanese-addresses/archive/refs/heads/master.tar.gz -o master.tar.gz && 7z x master.tar.gz -y -o./ && 7z x ./master.tar -y -o./test && del master.tar.gz master.tar && jest test/fs.test.ts",
14
17
  "test:generate-test-data": "npx ts-node -O '{\"module\":\"commonjs\"}' test/build-test-data.ts > test/addresses.csv",
15
18
  "lint": "eslint \"src/**/*.ts\" \"test/**/*.test.ts\" --fix",
16
- "build": "rm -rf ./dist && rollup -c ./rollup.config.ts"
19
+ "build": "npm run clean && rollup -c rollup.config.ts",
20
+ "clean": "node -e \"const fs = require('fs'); try { fs.rmSync('dist', { recursive: true, force: true }) } catch (err) { console.error(err) }\""
17
21
  },
18
22
  "author": "",
19
23
  "license": "MIT",
@@ -25,4 +25,13 @@ export default [
25
25
  output: { file: pkg.main, format: 'cjs' },
26
26
  plugins: [typescript()],
27
27
  },
28
+ {
29
+ input: 'src/main-es.ts',
30
+ output: {
31
+ dir: 'dist',
32
+ name: 'normalize',
33
+ format: 'esm',
34
+ },
35
+ plugins: [typescript(), resolve({ browser: true }), commonjs()],
36
+ },
28
37
  ]
@@ -4,6 +4,7 @@ export const gh_pages_endpoint =
4
4
  'https://geolonia.github.io/japanese-addresses/api/ja'
5
5
 
6
6
  export const currentConfig: Config = {
7
+ interfaceVersion: 1,
7
8
  japaneseAddressesApi: gh_pages_endpoint,
8
9
  townCacheSize: 1_000,
9
10
  }