forked from IMI-Tool-Project/imi-enrichment-hojin
-
Notifications
You must be signed in to change notification settings - Fork 0
/
IMIEnrichmentHojin.mjs
128 lines (118 loc) · 3.46 KB
/
IMIEnrichmentHojin.mjs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import csvutil from "https://taisukef.github.io/util/util.mjs";
import util from "./lib/util.mjs";
import format from "./lib/format.mjs";
const DIV = 4; // 6
const corporatenumbercache = {};
const getCorporateNumber = async (code) => {
const upper = code.substring(1, code.length - DIV); // ommit the first check digit char
let cache = corporatenumbercache[upper];
if (!cache) {
const fn = `data/${upper}.csv`;
let data = null;
if (
import.meta && import.meta.url && import.meta.url.startsWith("file://") &&
window.Deno
) {
const url = import.meta.url;
const path = url.substring("file://".length, url.lastIndexOf("/") + 1);
data = await Deno.readTextFile(path + fn);
} else {
data =
await (await fetch(
"https://code4sabae.github.io/imi-enrichment-hojin-es/" + fn,
)).text();
}
const json = {};
const csv = csvutil.decodeCSV(data);
for (const d of csv) {
json[parseInt(d[1])] = d;
}
cache = corporatenumbercache[upper] = json;
}
return cache[code];
};
const checkDigit = (id) => {
if (typeof id === "string") {
id = id.replace(/-/g, "");
}
let s = id.toString();
if (s.length < 12) {
s = "0000000000000" + s;
}
s = s.substring(s.length - 12);
let sum = 0;
s.split("").map((a) => parseInt(a)).forEach((v, i) => {
sum += (i % 2 === 0 ? v * 2 : v);
});
const b = 9 - (sum % 9);
return b + s;
};
const get = async (id) => {
const data = await getCorporateNumber(id);
if (!data) return null;
return format(data);
};
const enrich = async function (src) {
const dst = typeof src === "string" || typeof src === "number"
? {
"@context": "https://imi.go.jp/ns/core/context.jsonld",
"@type": "法人型",
"ID": {
"@type": "ID型",
"体系": {
"@type": "ID体系型",
"表記": "法人番号",
},
"識別値": checkDigit(src),
},
}
: JSON.parse(JSON.stringify(src));
const targets = [];
const dig = function (focus) {
if (Array.isArray(focus)) {
focus.forEach((a) => dig(a));
} else if (typeof focus === "object") {
if (focus["@type"] === "法人型" && focus["ID"] && focus["ID"]["識別値"]) {
const key = checkDigit(focus["ID"]["識別値"]);
if (!util.isValidHoujinBangou(key)) {
util.put(focus, "メタデータ", {
"@type": "文書型",
"説明": "法人番号は1~9ではじまる13桁の数字でなければなりません",
});
} else if (!util.isValidCheckDigit(key)) {
util.put(focus, "メタデータ", {
"@type": "文書型",
"説明": "法人番号のチェックデジットが不正です",
});
} else {
targets.push(focus);
}
}
Object.keys(focus).forEach((key) => {
dig(focus[key]);
});
}
};
dig(dst);
if (targets.length === 0) {
return dst;
}
const promises = targets.map(async (target) => {
try {
const json = await get(target["ID"]["識別値"]);
delete json["@context"];
delete target["ID"];
Object.keys(json).forEach((key) => {
util.put(target, key, json[key]);
});
} catch (e) {
util.put(target, "メタデータ", {
"@type": "文書型",
"説明": "該当する法人番号がありません",
});
}
});
await Promise.all(promises);
return dst;
};
export default enrich;