cry-vetzdravila 1.0.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/.claude/settings.local.json +17 -0
- package/CLAUDE.md +82 -0
- package/LICENSE.md +16 -0
- package/README.md +376 -0
- package/a.txt +1643 -0
- package/bun.lock +197 -0
- package/dist/atcvet/opisATCvetKode.d.ts +23 -0
- package/dist/atcvet/podatkiATCvetKode.d.ts +20 -0
- package/dist/atcvet/pomeniNivojevATCvet.d.ts +1 -0
- package/dist/atcvet/types/AtcvetFile.d.ts +19 -0
- package/dist/generated/AtcVet.d.ts +9 -0
- package/dist/generated/RegisterZdravil.d.ts +8 -0
- package/dist/generated/seznamZdravil.d.ts +8 -0
- package/dist/index.d.ts +244 -0
- package/dist/index.js +141786 -0
- package/dist/register/MIN_OCENA_PODOBNOSTI.d.ts +2 -0
- package/dist/register/helper/normalizirajNaziv.d.ts +176 -0
- package/dist/register/helper/oblikujRezultatIskanja.d.ts +8 -0
- package/dist/register/helper/oceniPodobnost.d.ts +37 -0
- package/dist/register/helper/poisciZivalskoVrsto.d.ts +33 -0
- package/dist/register/helper/razcleniNaziv.d.ts +2 -0
- package/dist/register/podobnaZdravilaPoATC.d.ts +16 -0
- package/dist/register/podobnaZdravilaPoUcinkovinah.d.ts +18 -0
- package/dist/register/registerZdravil.d.ts +9 -0
- package/dist/register/types/KarencaZdravila.d.ts +24 -0
- package/dist/register/types/PotUporabeZdravila.d.ts +21 -0
- package/dist/register/types/RazclembaZdravila.d.ts +9 -0
- package/dist/register/types/RegisterZdravil.d.ts +2 -0
- package/dist/register/types/UcinkovinaZdravila.d.ts +20 -0
- package/dist/register/types/Zdravilo.d.ts +65 -0
- package/dist/register/types/ZdraviloZUtemeljitvijo.d.ts +9 -0
- package/dist/register/types/ZivalskeVrste.d.ts +158 -0
- package/dist/register/uganiZdravilo.d.ts +43 -0
- package/dist/register/zdravilaZaAtcVetKodo.d.ts +8 -0
- package/dist/register/zdraviloJeVakcinaZa.d.ts +18 -0
- package/docs/vakcine.md +195 -0
- package/package.json +39 -0
- package/src/atcvet/CLAUDE.md +18 -0
- package/src/atcvet/downloadLatestAtcvetPdf.ts +107 -0
- package/src/atcvet/opisATCvetKode.ts +116 -0
- package/src/atcvet/parseAtcvetPdf.ts +215 -0
- package/src/atcvet/podatkiATCvetKode.ts +34 -0
- package/src/atcvet/pomeniNivojevATCvet.ts +8 -0
- package/src/atcvet/types/AtcvetFile.ts +22 -0
- package/src/generate.ts +111 -0
- package/src/generated/AtcVet.ts +56704 -0
- package/src/generated/seznamZdravil.ts +44833 -0
- package/src/importParseAndBuildAll.ts +97 -0
- package/src/index.ts +289 -0
- package/src/interactive.ts +428 -0
- package/src/register/CLAUDE.md +230 -0
- package/src/register/MIN_OCENA_PODOBNOSTI.ts +3 -0
- package/src/register/downloadRegister.ts +148 -0
- package/src/register/helper/analizaVakcin.ts +90 -0
- package/src/register/helper/checkVrste.ts +72 -0
- package/src/register/helper/hashString.ts +27 -0
- package/src/register/helper/normalizirajNaziv.ts +493 -0
- package/src/register/helper/oblikujRezultatIskanja.ts +15 -0
- package/src/register/helper/oceniPodobnost.ts +194 -0
- package/src/register/helper/poisciZivalskoVrsto.ts +100 -0
- package/src/register/helper/razcleniNaziv.ts +105 -0
- package/src/register/helper/testNormalizacije.ts +89 -0
- package/src/register/helper/testPodobnosti.ts +238 -0
- package/src/register/helper/testVakcin.ts +103 -0
- package/src/register/parseRegister.ts +464 -0
- package/src/register/podobnaZdravilaPoATC.ts +71 -0
- package/src/register/podobnaZdravilaPoUcinkovinah.ts +136 -0
- package/src/register/registerZdravil.ts +22 -0
- package/src/register/stats.ts +114 -0
- package/src/register/types/KarencaZdravila.ts +26 -0
- package/src/register/types/PotUporabeZdravila.ts +21 -0
- package/src/register/types/RazclembaZdravila.ts +10 -0
- package/src/register/types/RegisterRaw.ts +23 -0
- package/src/register/types/RegisterZdravil.ts +3 -0
- package/src/register/types/UcinkovinaZdravila.ts +21 -0
- package/src/register/types/Zdravilo.ts +84 -0
- package/src/register/types/ZdraviloZUtemeljitvijo.ts +11 -0
- package/src/register/types/ZivalskeVrste.ts +7 -0
- package/src/register/uganiZdravilo.ts +142 -0
- package/src/register/zdravilaZaAtcVetKodo.ts +28 -0
- package/src/register/zdraviloJeVakcinaZa.ts +202 -0
- package/src/test/testPodobnosti.test.ts +126 -0
- package/src/test/zdravila.json +38693 -0
- package/tsconfig.json +18 -0
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parsanje ATCVet PDF dokumenta
|
|
3
|
+
*
|
|
4
|
+
* Bere data/atcvet.pdf in ustvari data/atcvet.json
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import fs from "node:fs";
|
|
8
|
+
import path from "node:path";
|
|
9
|
+
import * as pdfjsLib from "pdfjs-dist/legacy/build/pdf.mjs";
|
|
10
|
+
import type { AtcvetRow, AtcvetFile } from "./types/AtcvetFile";
|
|
11
|
+
|
|
12
|
+
type TextItem = {
|
|
13
|
+
str: string;
|
|
14
|
+
transform: number[]; // [a,b,c,d,e,f] where e=x, f=y
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
function normalizeSpaces(s: string): string {
|
|
18
|
+
return s.replace(/\s+/g, " ").trim();
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function isFooterOrNoise(line: string): boolean {
|
|
22
|
+
const t = normalizeSpaces(line);
|
|
23
|
+
// common noise patterns found in this PDF export
|
|
24
|
+
if (!t) return true;
|
|
25
|
+
if (t === "ATC 2025") return true;
|
|
26
|
+
if (t.startsWith("Stran ")) return true; // e.g. "Stran 2 of 139ATC 2025"
|
|
27
|
+
if (t === "ATCCode ATCDescription ATCDescriptionSI") return true;
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Heuristic: ATCvet codes start with Q and then letters/digits; in this doc examples are like QA, QA01, QA01A, QA01AA, QA01AA01
|
|
32
|
+
// QA01AA01 has 8 chars total, so we need {1,7} after Q
|
|
33
|
+
const CODE_RE = /^Q[A-Z0-9]{1,7}$/;
|
|
34
|
+
|
|
35
|
+
function inferLevel(code: string): 1 | 2 | 3 | 4 | 5 {
|
|
36
|
+
// Typical lengths in this doc:
|
|
37
|
+
// 2: QA (level 1)
|
|
38
|
+
// 4: QA01 (level 2)
|
|
39
|
+
// 5: QA01A (level 3)
|
|
40
|
+
// 6: QA01AA (level 4)
|
|
41
|
+
// 8: QA01AA01 (level 5)
|
|
42
|
+
const len = code.length;
|
|
43
|
+
if (len <= 2) return 1;
|
|
44
|
+
if (len === 4) return 2;
|
|
45
|
+
if (len === 5) return 3;
|
|
46
|
+
if (len === 6) return 4;
|
|
47
|
+
return 5;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function inferParent(code: string): string | undefined {
|
|
51
|
+
const level = inferLevel(code);
|
|
52
|
+
if (level === 1) return undefined;
|
|
53
|
+
if (level === 2) return code.slice(0, 2);
|
|
54
|
+
if (level === 3) return code.slice(0, 4);
|
|
55
|
+
if (level === 4) return code.slice(0, 5);
|
|
56
|
+
return code.slice(0, 6);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function groupByLine(items: TextItem[]): Map<number, TextItem[]> {
|
|
60
|
+
// group by rounded Y coordinate (PDF uses floats)
|
|
61
|
+
const map = new Map<number, TextItem[]>();
|
|
62
|
+
for (const it of items) {
|
|
63
|
+
const x = it.transform[4];
|
|
64
|
+
const y = it.transform[5];
|
|
65
|
+
const yKey = Math.round(y * 2) / 2; // 0.5 precision
|
|
66
|
+
const arr = map.get(yKey) ?? [];
|
|
67
|
+
arr.push({ ...it, transform: [0,0,0,0,x,y] });
|
|
68
|
+
map.set(yKey, arr);
|
|
69
|
+
}
|
|
70
|
+
// sort each line by X
|
|
71
|
+
for (const [k, arr] of map.entries()) {
|
|
72
|
+
arr.sort((a, b) => a.transform[4] - b.transform[4]);
|
|
73
|
+
map.set(k, arr);
|
|
74
|
+
}
|
|
75
|
+
return map;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export async function parseAtcvetPdf(pdfPath: string): Promise<AtcvetRow[]> {
|
|
79
|
+
const data = new Uint8Array(fs.readFileSync(pdfPath));
|
|
80
|
+
const doc = await pdfjsLib.getDocument({ data }).promise;
|
|
81
|
+
|
|
82
|
+
const out: AtcvetRow[] = [];
|
|
83
|
+
let lastRow: AtcvetRow | null = null;
|
|
84
|
+
|
|
85
|
+
for (let p = 1; p <= doc.numPages; p++) {
|
|
86
|
+
const page = await doc.getPage(p);
|
|
87
|
+
const content = await page.getTextContent();
|
|
88
|
+
const rawItems = content.items as unknown as TextItem[];
|
|
89
|
+
|
|
90
|
+
// Find header on this page to detect column X positions.
|
|
91
|
+
// We look for "ATCCode", "ATCDescription", "ATCDescriptionSI"
|
|
92
|
+
const headerItems = rawItems
|
|
93
|
+
.filter(i => ["ATCCode", "ATCDescription", "ATCDescriptionSI"].includes(i.str.trim()));
|
|
94
|
+
|
|
95
|
+
// Fallback column boundaries if header not found (should usually be found)
|
|
96
|
+
// PDF has: ATCCode ~19, ATCDescription ~79, ATCDescriptionSI ~624
|
|
97
|
+
let xCodeMax = 70;
|
|
98
|
+
let xEnMax = 600;
|
|
99
|
+
|
|
100
|
+
if (headerItems.length >= 3) {
|
|
101
|
+
const xs = headerItems
|
|
102
|
+
.map(i => ({ s: i.str.trim(), x: i.transform[4] }))
|
|
103
|
+
.sort((a, b) => a.x - b.x);
|
|
104
|
+
|
|
105
|
+
const xEn = xs.find(v => v.s === "ATCDescription")?.x;
|
|
106
|
+
const xSi = xs.find(v => v.s === "ATCDescriptionSI")?.x;
|
|
107
|
+
|
|
108
|
+
// boundaries are just before the next column starts
|
|
109
|
+
if (typeof xEn === "number") {
|
|
110
|
+
xCodeMax = xEn - 5;
|
|
111
|
+
}
|
|
112
|
+
if (typeof xSi === "number") {
|
|
113
|
+
xEnMax = xSi - 5;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const byLine = groupByLine(rawItems);
|
|
118
|
+
|
|
119
|
+
// Sort lines top-to-bottom by Y (PDF y increases upwards; we want descending)
|
|
120
|
+
const yKeys = Array.from(byLine.keys()).sort((a, b) => b - a);
|
|
121
|
+
|
|
122
|
+
for (const y of yKeys) {
|
|
123
|
+
const lineItems = byLine.get(y)!;
|
|
124
|
+
|
|
125
|
+
// Build 3 column strings based on x boundaries
|
|
126
|
+
let colCode = "";
|
|
127
|
+
let colEn = "";
|
|
128
|
+
let colSi = "";
|
|
129
|
+
|
|
130
|
+
for (const it of lineItems) {
|
|
131
|
+
const s = it.str;
|
|
132
|
+
if (!s || !s.trim()) continue;
|
|
133
|
+
const x = it.transform[4];
|
|
134
|
+
|
|
135
|
+
if (x <= xCodeMax) colCode += s;
|
|
136
|
+
else if (x <= xEnMax) colEn += (colEn ? " " : "") + s;
|
|
137
|
+
else colSi += (colSi ? " " : "") + s;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
colCode = normalizeSpaces(colCode);
|
|
141
|
+
colEn = normalizeSpaces(colEn);
|
|
142
|
+
colSi = normalizeSpaces(colSi);
|
|
143
|
+
|
|
144
|
+
const joinedForNoise = normalizeSpaces([colCode, colEn, colSi].filter(Boolean).join(" "));
|
|
145
|
+
if (isFooterOrNoise(joinedForNoise)) continue;
|
|
146
|
+
|
|
147
|
+
// Some footers can end up in colCode area; filter them
|
|
148
|
+
if (colCode.startsWith("Stran ")) continue;
|
|
149
|
+
|
|
150
|
+
// If we have a code -> new row; else treat as continuation and append
|
|
151
|
+
if (colCode && CODE_RE.test(colCode)) {
|
|
152
|
+
const row: AtcvetRow = {
|
|
153
|
+
code: colCode,
|
|
154
|
+
desc_en: colEn,
|
|
155
|
+
desc_si: colSi,
|
|
156
|
+
level: inferLevel(colCode),
|
|
157
|
+
parent: inferParent(colCode),
|
|
158
|
+
};
|
|
159
|
+
if (!row.parent) delete row.parent;
|
|
160
|
+
|
|
161
|
+
out.push(row);
|
|
162
|
+
lastRow = row;
|
|
163
|
+
} else if (lastRow) {
|
|
164
|
+
// continuation line (rare, but can happen if long descriptions wrap)
|
|
165
|
+
// append whichever columns are populated
|
|
166
|
+
if (colEn) lastRow.desc_en = normalizeSpaces(`${lastRow.desc_en} ${colEn}`);
|
|
167
|
+
if (colSi) lastRow.desc_si = normalizeSpaces(`${lastRow.desc_si} ${colSi}`);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// final cleanup: drop duplicates (if any) by code, keep first
|
|
173
|
+
const seen = new Set<string>();
|
|
174
|
+
const dedup: AtcvetRow[] = [];
|
|
175
|
+
for (const r of out) {
|
|
176
|
+
if (seen.has(r.code)) continue;
|
|
177
|
+
seen.add(r.code);
|
|
178
|
+
// ensure required fields
|
|
179
|
+
r.desc_en = normalizeSpaces(r.desc_en);
|
|
180
|
+
r.desc_si = normalizeSpaces(r.desc_si);
|
|
181
|
+
dedup.push(r);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return dedup;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const DEFAULT_PDF_PATH = "./data/atcvet.pdf";
|
|
188
|
+
const DEFAULT_JSON_PATH = "./data/atcvet.json";
|
|
189
|
+
|
|
190
|
+
async function main() {
|
|
191
|
+
const pdfIn = process.argv[2] || DEFAULT_PDF_PATH;
|
|
192
|
+
const jsonOut = process.argv[3] || DEFAULT_JSON_PATH;
|
|
193
|
+
|
|
194
|
+
console.log(`Parsam: ${pdfIn}`);
|
|
195
|
+
const rows = await parseAtcvetPdf(pdfIn);
|
|
196
|
+
|
|
197
|
+
const payload: AtcvetFile = {
|
|
198
|
+
meta: {
|
|
199
|
+
source: path.basename(pdfIn),
|
|
200
|
+
generatedAt: new Date().toISOString(),
|
|
201
|
+
count: rows.length,
|
|
202
|
+
},
|
|
203
|
+
rows,
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
fs.writeFileSync(jsonOut, JSON.stringify(payload, null, 2), "utf8");
|
|
207
|
+
console.log(`Zapisano ${rows.length} vrstic v ${jsonOut}`);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
if (import.meta.main) {
|
|
211
|
+
main().catch((e) => {
|
|
212
|
+
console.error(e);
|
|
213
|
+
process.exit(1);
|
|
214
|
+
});
|
|
215
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { opisATCvetKode, izracunajNivoje, type RazlagaATCvetKode } from "./opisATCvetKode";
|
|
2
|
+
|
|
3
|
+
export type { RazlagaATCvetKode };
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Funkcija vrne opise vseh nivojev za dano ATCvet kodo, urejene po nivoju
|
|
7
|
+
* @param koda ATCvet koda (npr. "QA01AA01")
|
|
8
|
+
* @returns Seznam razlag za vse nivoje kode
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* const rezultat = podatkiATCvetKode("QA01AC03");
|
|
12
|
+
* // Vrne:
|
|
13
|
+
* // [
|
|
14
|
+
* // { nivo: 0, pomenNivoja: "veterinarska uporaba", opisNivoja: "Veterinarska zdravila" },
|
|
15
|
+
* // { nivo: 1, pomenNivoja: "anatomska glavna skupina", opisNivoja: "ZDRAVILA ZA BOLEZNI PREBAVIL IN PRESNOVE" },
|
|
16
|
+
* // { nivo: 2, pomenNivoja: "terapevtska podskupina", opisNivoja: "ZDRAVILA V ZOBOZDRAVSTVU" },
|
|
17
|
+
* // { nivo: 3, pomenNivoja: "farmakološka podskupina", opisNivoja: "Zdravila v zobozdravstvu" },
|
|
18
|
+
* // { nivo: 5, pomenNivoja: "kemijska učinkovina", opisNivoja: "hidrokortizon" }
|
|
19
|
+
* // ]
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export function podatkiATCvetKode(koda: string): RazlagaATCvetKode[] {
|
|
23
|
+
const nivoji = izracunajNivoje(koda);
|
|
24
|
+
const rezultati: RazlagaATCvetKode[] = [];
|
|
25
|
+
|
|
26
|
+
for (const nivoKoda of nivoji) {
|
|
27
|
+
const opis = opisATCvetKode(nivoKoda);
|
|
28
|
+
if (opis) {
|
|
29
|
+
rezultati.push(opis);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return rezultati;
|
|
34
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export const pomeniNivojevATCvet: Array<[nivo: number, pomen: string]> = [
|
|
2
|
+
[0, "veterinarska uporaba"],
|
|
3
|
+
[1, "anatomska glavna skupina"],
|
|
4
|
+
[2, "terapevtska podskupina"],
|
|
5
|
+
[3, "farmakološka podskupina"],
|
|
6
|
+
[4, "kemijska podskupina"],
|
|
7
|
+
[5, "kemijska učinkovina"]
|
|
8
|
+
];
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tipizacija za ATCVet JSON datoteko
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export interface AtcvetRow {
|
|
6
|
+
code: string;
|
|
7
|
+
desc_en: string;
|
|
8
|
+
desc_si: string;
|
|
9
|
+
level: 1 | 2 | 3 | 4 | 5;
|
|
10
|
+
parent?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface AtcvetMeta {
|
|
14
|
+
source: string;
|
|
15
|
+
generatedAt: string;
|
|
16
|
+
count: number;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface AtcvetFile {
|
|
20
|
+
meta: AtcvetMeta;
|
|
21
|
+
rows: AtcvetRow[];
|
|
22
|
+
}
|
package/src/generate.ts
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generiranje TypeScript datotek iz JSON podatkov
|
|
3
|
+
*
|
|
4
|
+
* Generira:
|
|
5
|
+
* - generated/seznamZdravil.ts - seznam zdravil
|
|
6
|
+
* - generated/AtcVet.ts - ATCVet klasifikacija
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import fs from "node:fs";
|
|
10
|
+
import type { RegisterRaw } from "./register/types/RegisterRaw";
|
|
11
|
+
import type { AtcvetFile } from "./atcvet/types/AtcvetFile";
|
|
12
|
+
import { Zdravilo } from "./register/types/Zdravilo";
|
|
13
|
+
|
|
14
|
+
const GENERATED_DIR = "./src/generated";
|
|
15
|
+
const REGISTER_JSON = "./data/register.json";
|
|
16
|
+
const ATCVET_JSON = "./data/atcvet.json";
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Ustvari direktorij če ne obstaja
|
|
20
|
+
*/
|
|
21
|
+
export function ensureGeneratedDir(): void {
|
|
22
|
+
if (!fs.existsSync(GENERATED_DIR)) {
|
|
23
|
+
fs.mkdirSync(GENERATED_DIR, { recursive: true });
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Generiraj RegisterZdravil.ts
|
|
29
|
+
*/
|
|
30
|
+
export function generateRegisterZdravil(): void {
|
|
31
|
+
console.log("Generiram RegisterZdravil.ts...");
|
|
32
|
+
|
|
33
|
+
const registerData = JSON.parse(fs.readFileSync(REGISTER_JSON, "utf8")) as RegisterRaw;
|
|
34
|
+
const registerZdravil = new Map<number, Zdravilo>();
|
|
35
|
+
|
|
36
|
+
for (let zdravilo of registerData.zdravila) {
|
|
37
|
+
registerZdravil.set(zdravilo.id,zdravilo)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const content = `/**
|
|
41
|
+
* Seznam veterinarskih zdravil registriranih v Sloveniji
|
|
42
|
+
*
|
|
43
|
+
* Generirano: ${new Date().toISOString()}
|
|
44
|
+
* Število zdravil: ${registerData.steviloZdravil}
|
|
45
|
+
*/
|
|
46
|
+
|
|
47
|
+
import type { Zdravilo } from "../register/types/Zdravilo";
|
|
48
|
+
|
|
49
|
+
export const seznamZdravil: Zdravilo[] = ${JSON.stringify(registerData.zdravila, null, 2)};
|
|
50
|
+
`;
|
|
51
|
+
|
|
52
|
+
fs.writeFileSync(`${GENERATED_DIR}/seznamZdravil.ts`, content, "utf8");
|
|
53
|
+
console.log(` Zapisano: ${GENERATED_DIR}/seznamZdravil.ts (${registerData.steviloZdravil} zdravil)`);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Generiraj AtcVet.ts
|
|
58
|
+
*/
|
|
59
|
+
export function generateAtcVet(): void {
|
|
60
|
+
console.log("Generiram AtcVet.ts...");
|
|
61
|
+
|
|
62
|
+
const atcvetData = JSON.parse(fs.readFileSync(ATCVET_JSON, "utf8")) as AtcvetFile;
|
|
63
|
+
|
|
64
|
+
const content = `/**
|
|
65
|
+
* ATCVet klasifikacija
|
|
66
|
+
*
|
|
67
|
+
* Generirano: ${new Date().toISOString()}
|
|
68
|
+
* Število kod: ${atcvetData.meta.count}
|
|
69
|
+
* Vir: ${atcvetData.meta.source}
|
|
70
|
+
*/
|
|
71
|
+
|
|
72
|
+
import type { AtcvetRow } from "../atcvet/types/AtcvetFile";
|
|
73
|
+
|
|
74
|
+
export const AtcVet: AtcvetRow[] = ${JSON.stringify(atcvetData.rows, null, 2)};
|
|
75
|
+
`;
|
|
76
|
+
|
|
77
|
+
fs.writeFileSync(`${GENERATED_DIR}/AtcVet.ts`, content, "utf8");
|
|
78
|
+
console.log(` Zapisano: ${GENERATED_DIR}/AtcVet.ts (${atcvetData.meta.count} kod)`);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
async function main() {
|
|
82
|
+
console.log("═══════════════════════════════════════════════════════════════");
|
|
83
|
+
console.log(" GENERIRANJE TYPESCRIPT DATOTEK");
|
|
84
|
+
console.log("═══════════════════════════════════════════════════════════════\n");
|
|
85
|
+
|
|
86
|
+
// Preveri, da JSON datoteke obstajajo
|
|
87
|
+
if (!fs.existsSync(REGISTER_JSON)) {
|
|
88
|
+
console.error(`Napaka: ${REGISTER_JSON} ne obstaja. Najprej izvedi 'bun run import:all'.`);
|
|
89
|
+
process.exit(1);
|
|
90
|
+
}
|
|
91
|
+
if (!fs.existsSync(ATCVET_JSON)) {
|
|
92
|
+
console.error(`Napaka: ${ATCVET_JSON} ne obstaja. Najprej izvedi 'bun run import:all'.`);
|
|
93
|
+
process.exit(1);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
ensureGeneratedDir();
|
|
97
|
+
|
|
98
|
+
generateRegisterZdravil();
|
|
99
|
+
generateAtcVet();
|
|
100
|
+
|
|
101
|
+
console.log("\n═══════════════════════════════════════════════════════════════");
|
|
102
|
+
console.log(" KONČANO");
|
|
103
|
+
console.log("═══════════════════════════════════════════════════════════════\n");
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (import.meta.main) {
|
|
107
|
+
main().catch((e) => {
|
|
108
|
+
console.error("Napaka:", e);
|
|
109
|
+
process.exit(1);
|
|
110
|
+
});
|
|
111
|
+
}
|