@uns-kit/core 2.0.38 → 2.0.40

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 (42) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +147 -148
  3. package/dist/app-config.d.ts.map +1 -0
  4. package/dist/app-config.js.map +1 -0
  5. package/dist/index.d.ts +8 -8
  6. package/dist/index.js +7 -7
  7. package/dist/tools/datahub/datahub-client.js +1 -1
  8. package/dist/tools/datahub/datahub-client.js.map +1 -1
  9. package/dist/tools/file-utils.d.ts +2 -2
  10. package/dist/tools/file-utils.js +24 -24
  11. package/dist/tools/generate-uns-dictionary.d.ts +23 -23
  12. package/dist/tools/generate-uns-dictionary.js +154 -154
  13. package/dist/tools/generate-uns-measurements.d.ts +21 -21
  14. package/dist/tools/generate-uns-measurements.js +126 -126
  15. package/dist/tools/generate-uns-reference.d.ts +2 -2
  16. package/dist/tools/generate-uns-reference.js +85 -85
  17. package/dist/tools/refresh-uns.js +50 -50
  18. package/dist/tools/sync-uns-schema.d.ts +2 -2
  19. package/dist/tools/sync-uns-schema.js +489 -489
  20. package/dist/uns/uns-asset.d.ts +1 -1
  21. package/dist/uns/uns-asset.js +1 -1
  22. package/dist/uns/uns-attributes.d.ts +6 -6
  23. package/dist/uns/uns-attributes.js +9 -9
  24. package/dist/uns/uns-dictionary-registry.d.ts +4 -4
  25. package/dist/uns/uns-dictionary-registry.js +20 -20
  26. package/dist/uns/uns-dictionary.generated.d.ts +663 -663
  27. package/dist/uns/uns-dictionary.generated.js +745 -745
  28. package/dist/uns/uns-interfaces.d.ts +365 -365
  29. package/dist/uns/uns-measurements.generated.d.ts +362 -362
  30. package/dist/uns/uns-measurements.generated.js +359 -359
  31. package/dist/uns/uns-object.d.ts +20 -20
  32. package/dist/uns/uns-object.js +9 -9
  33. package/dist/uns/uns-packet.js +263 -263
  34. package/dist/uns/uns-path.d.ts +2 -2
  35. package/dist/uns/uns-path.js +10 -10
  36. package/dist/uns/uns-proxy-process.js +203 -203
  37. package/dist/uns/uns-proxy.d.ts +51 -51
  38. package/dist/uns/uns-proxy.js +190 -190
  39. package/dist/uns-config/uns-core-schema.d.ts +3276 -3276
  40. package/dist/uns-grpc/uns-gateway.proto +104 -104
  41. package/dist/uns-mqtt/uns-mqtt-proxy.js +477 -477
  42. package/package.json +1 -1
@@ -1,155 +1,155 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Generate a TypeScript dictionary of object types and attributes (with descriptions)
4
- * from a JSON file. The output is meant for IntelliSense and metadata enrichment
5
- * (e.g., emitting descriptions alongside topics). No GraphQL calls are performed.
6
- *
7
- * JSON shape (example):
8
- * {
9
- * "objectTypes": {
10
- * "energy-resource": { "description": "Energy carriers (electricity/steam/gas)" },
11
- * "custom-type": { "description": "Tenant-specific thing" }
12
- * },
13
- * "attributes": {
14
- * "cumulative-active-energy-delivered": { "description": "kWh total" },
15
- * "status": { "description": "Generic status" }
16
- * }
17
- * }
18
- */
19
- import { readFile } from "node:fs/promises";
20
- import path from "node:path";
21
- import { pathToFileURL } from "node:url";
22
- import { writeTextFileIfChanged } from "./file-utils.js";
23
- const DEFAULT_INPUT = "uns-dictionary.json";
24
- const DEFAULT_OUTPUT = path.resolve(process.cwd(), "src/uns/uns-dictionary.generated.ts");
25
- async function main() {
26
- const args = parseArgs(process.argv.slice(2));
27
- await generateUnsDictionary(args);
28
- }
29
- function parseArgs(argv) {
30
- let input = DEFAULT_INPUT;
31
- let output = DEFAULT_OUTPUT;
32
- let lang = "sl";
33
- for (let i = 0; i < argv.length; i++) {
34
- const arg = argv[i];
35
- if (arg === "--input" && argv[i + 1]) {
36
- input = argv[++i];
37
- continue;
38
- }
39
- if (arg === "--output" && argv[i + 1]) {
40
- output = argv[++i];
41
- continue;
42
- }
43
- if (arg === "--lang" && argv[i + 1]) {
44
- lang = argv[++i];
45
- continue;
46
- }
47
- if (arg === "--help" || arg === "-h") {
48
- printHelp();
49
- process.exit(0);
50
- }
51
- throw new Error(`Unknown argument: ${arg}`);
52
- }
53
- return { input, output, lang };
54
- }
55
- function printHelp() {
56
- console.log(`Usage: tsx packages/uns-core/src/tools/generate-uns-dictionary.ts [options]
57
-
58
- Options:
59
- --input <file> Path to uns-dictionary.json (default: ${DEFAULT_INPUT})
60
- --output <file> Path to generated TS file (default: src/uns/uns-dictionary.generated.ts)
61
- --lang <code> Preferred description language code (default: "sl")
62
- --help, -h Show this help
63
- `);
64
- }
65
- async function readDictionaryFromJson(filePath) {
66
- const absolute = path.resolve(process.cwd(), filePath);
67
- const raw = await readFile(absolute, "utf8");
68
- return JSON.parse(raw);
69
- }
70
- export async function generateUnsDictionary(args) {
71
- const effective = {
72
- input: args.input ?? DEFAULT_INPUT,
73
- output: args.output ?? DEFAULT_OUTPUT,
74
- lang: args.lang ?? "sl",
75
- };
76
- const dictionary = await readDictionaryFromJson(effective.input);
77
- const changed = await writeDictionaryTs(dictionary, effective.output, effective.lang);
78
- console.log(`Generated dictionary -> ${effective.output}${changed ? "" : " (unchanged)"}`);
79
- }
80
- const resolveDescription = (entry, lang) => {
81
- if (!entry)
82
- return undefined;
83
- const byLang = entry.descriptions?.[lang];
84
- if (byLang && byLang.length > 0)
85
- return byLang;
86
- if (entry.description && entry.description.length > 0)
87
- return entry.description;
88
- return undefined;
89
- };
90
- function renderDoc(description, indent) {
91
- if (!description)
92
- return "";
93
- const normalized = description
94
- .replaceAll("*/", "*\\/")
95
- .split(/\r?\n/)
96
- .map((line) => `${indent} * ${line}`)
97
- .join("\n");
98
- return `${indent}/**\n${normalized}\n${indent} */\n`;
99
- }
100
- export function renderDictionaryTs(dictionary, lang) {
101
- const objectTypeEntries = Object.entries(dictionary.objectTypes ?? {}).sort(([left], [right]) => left.localeCompare(right));
102
- const attributeEntries = Object.entries(dictionary.attributes ?? {}).sort(([left], [right]) => left.localeCompare(right));
103
- const attributesByType = {};
104
- for (const [name, entry] of objectTypeEntries) {
105
- if (Array.isArray(entry.attributes) && entry.attributes.length > 0) {
106
- attributesByType[name] = entry.attributes.filter((attribute) => typeof attribute === "string" && attribute.length > 0);
107
- }
108
- }
109
- const renderRecord = (entries) => entries
110
- .map(([name, entry]) => {
111
- const desc = resolveDescription(entry, lang);
112
- const doc = renderDoc(desc, " ");
113
- return `${doc} "${name}": "${name}",`;
114
- })
115
- .join("\n");
116
- const renderDescriptions = (entries) => entries
117
- .map(([name, value]) => ` "${name}": ${JSON.stringify(resolveDescription(value, lang) ?? "")},`)
118
- .join("\n");
119
- const objectTypeConst = `export const GeneratedObjectTypes = {\n${renderRecord(objectTypeEntries)}\n} as const;`;
120
- const objectTypeDescConst = `export const GeneratedObjectTypeDescriptions: Record<keyof typeof GeneratedObjectTypes, string> = {\n${renderDescriptions(objectTypeEntries)}\n};`;
121
- const attributeConst = `export const GeneratedAttributes = {\n${renderRecord(attributeEntries)}\n} as const;`;
122
- const attributeDescConst = `export const GeneratedAttributeDescriptions: Record<keyof typeof GeneratedAttributes, string> = {\n${renderDescriptions(attributeEntries)}\n};`;
123
- const renderAttributesByType = () => {
124
- const blocks = [];
125
- for (const [objectType, attrs] of Object.entries(attributesByType)) {
126
- if (!attrs.length)
127
- continue;
128
- const lines = attrs
129
- .map((attr) => {
130
- const desc = resolveDescription(dictionary.attributes?.[attr], lang);
131
- const doc = renderDoc(desc, " ");
132
- return `${doc} "${attr}": "${attr}",`;
133
- })
134
- .join("\n");
135
- blocks.push(` "${objectType}": {\n${lines}\n },`);
136
- }
137
- return blocks.join("\n");
138
- };
139
- const attributesByTypeConst = `const GeneratedAttributesByTypeBase = {\n${renderAttributesByType()}\n} as const;\n\nexport const GeneratedAttributesByType = GeneratedAttributesByTypeBase;`;
140
- return `/* Auto-generated by generate-uns-dictionary.ts. Do not edit by hand. */\n${objectTypeConst}\n\n${objectTypeDescConst}\n\nexport type GeneratedObjectTypeName = keyof typeof GeneratedObjectTypes;\n\nexport function getGeneratedObjectTypeDescription(name: string): string | undefined {\n return (GeneratedObjectTypeDescriptions as Record<string, string | undefined>)[name];\n}\n\n${attributeConst}\n\n${attributeDescConst}\n\n${attributesByTypeConst}\n\nexport type GeneratedAttributeName = keyof typeof GeneratedAttributes;\n\nexport type GeneratedAttributesFor<T extends keyof typeof GeneratedAttributesByType> = keyof typeof GeneratedAttributesByType[T];\n\nexport function getGeneratedAttributeDescription(name: string): string | undefined {\n return (GeneratedAttributeDescriptions as Record<string, string | undefined>)[name];\n}\n`;
141
- }
142
- async function writeDictionaryTs(dictionary, filePath, lang) {
143
- const content = renderDictionaryTs(dictionary, lang);
144
- return writeTextFileIfChanged(filePath, content);
145
- }
146
- const isDirectExecution = process.argv[1]
147
- ? import.meta.url === pathToFileURL(path.resolve(process.argv[1])).href
148
- : false;
149
- if (isDirectExecution) {
150
- main().catch((error) => {
151
- console.error("Failed to generate UNS dictionary:", error);
152
- process.exitCode = 1;
153
- });
154
- }
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Generate a TypeScript dictionary of object types and attributes (with descriptions)
4
+ * from a JSON file. The output is meant for IntelliSense and metadata enrichment
5
+ * (e.g., emitting descriptions alongside topics). No GraphQL calls are performed.
6
+ *
7
+ * JSON shape (example):
8
+ * {
9
+ * "objectTypes": {
10
+ * "energy-resource": { "description": "Energy carriers (electricity/steam/gas)" },
11
+ * "custom-type": { "description": "Tenant-specific thing" }
12
+ * },
13
+ * "attributes": {
14
+ * "cumulative-active-energy-delivered": { "description": "kWh total" },
15
+ * "status": { "description": "Generic status" }
16
+ * }
17
+ * }
18
+ */
19
+ import { readFile } from "node:fs/promises";
20
+ import path from "node:path";
21
+ import { pathToFileURL } from "node:url";
22
+ import { writeTextFileIfChanged } from "./file-utils.js";
23
+ const DEFAULT_INPUT = "uns-dictionary.json";
24
+ const DEFAULT_OUTPUT = path.resolve(process.cwd(), "src/uns/uns-dictionary.generated.ts");
25
+ async function main() {
26
+ const args = parseArgs(process.argv.slice(2));
27
+ await generateUnsDictionary(args);
28
+ }
29
+ function parseArgs(argv) {
30
+ let input = DEFAULT_INPUT;
31
+ let output = DEFAULT_OUTPUT;
32
+ let lang = "sl";
33
+ for (let i = 0; i < argv.length; i++) {
34
+ const arg = argv[i];
35
+ if (arg === "--input" && argv[i + 1]) {
36
+ input = argv[++i];
37
+ continue;
38
+ }
39
+ if (arg === "--output" && argv[i + 1]) {
40
+ output = argv[++i];
41
+ continue;
42
+ }
43
+ if (arg === "--lang" && argv[i + 1]) {
44
+ lang = argv[++i];
45
+ continue;
46
+ }
47
+ if (arg === "--help" || arg === "-h") {
48
+ printHelp();
49
+ process.exit(0);
50
+ }
51
+ throw new Error(`Unknown argument: ${arg}`);
52
+ }
53
+ return { input, output, lang };
54
+ }
55
+ function printHelp() {
56
+ console.log(`Usage: tsx packages/uns-core/src/tools/generate-uns-dictionary.ts [options]
57
+
58
+ Options:
59
+ --input <file> Path to uns-dictionary.json (default: ${DEFAULT_INPUT})
60
+ --output <file> Path to generated TS file (default: src/uns/uns-dictionary.generated.ts)
61
+ --lang <code> Preferred description language code (default: "sl")
62
+ --help, -h Show this help
63
+ `);
64
+ }
65
+ async function readDictionaryFromJson(filePath) {
66
+ const absolute = path.resolve(process.cwd(), filePath);
67
+ const raw = await readFile(absolute, "utf8");
68
+ return JSON.parse(raw);
69
+ }
70
+ export async function generateUnsDictionary(args) {
71
+ const effective = {
72
+ input: args.input ?? DEFAULT_INPUT,
73
+ output: args.output ?? DEFAULT_OUTPUT,
74
+ lang: args.lang ?? "sl",
75
+ };
76
+ const dictionary = await readDictionaryFromJson(effective.input);
77
+ const changed = await writeDictionaryTs(dictionary, effective.output, effective.lang);
78
+ console.log(`Generated dictionary -> ${effective.output}${changed ? "" : " (unchanged)"}`);
79
+ }
80
+ const resolveDescription = (entry, lang) => {
81
+ if (!entry)
82
+ return undefined;
83
+ const byLang = entry.descriptions?.[lang];
84
+ if (byLang && byLang.length > 0)
85
+ return byLang;
86
+ if (entry.description && entry.description.length > 0)
87
+ return entry.description;
88
+ return undefined;
89
+ };
90
+ function renderDoc(description, indent) {
91
+ if (!description)
92
+ return "";
93
+ const normalized = description
94
+ .replaceAll("*/", "*\\/")
95
+ .split(/\r?\n/)
96
+ .map((line) => `${indent} * ${line}`)
97
+ .join("\n");
98
+ return `${indent}/**\n${normalized}\n${indent} */\n`;
99
+ }
100
+ export function renderDictionaryTs(dictionary, lang) {
101
+ const objectTypeEntries = Object.entries(dictionary.objectTypes ?? {}).sort(([left], [right]) => left.localeCompare(right));
102
+ const attributeEntries = Object.entries(dictionary.attributes ?? {}).sort(([left], [right]) => left.localeCompare(right));
103
+ const attributesByType = {};
104
+ for (const [name, entry] of objectTypeEntries) {
105
+ if (Array.isArray(entry.attributes) && entry.attributes.length > 0) {
106
+ attributesByType[name] = entry.attributes.filter((attribute) => typeof attribute === "string" && attribute.length > 0);
107
+ }
108
+ }
109
+ const renderRecord = (entries) => entries
110
+ .map(([name, entry]) => {
111
+ const desc = resolveDescription(entry, lang);
112
+ const doc = renderDoc(desc, " ");
113
+ return `${doc} "${name}": "${name}",`;
114
+ })
115
+ .join("\n");
116
+ const renderDescriptions = (entries) => entries
117
+ .map(([name, value]) => ` "${name}": ${JSON.stringify(resolveDescription(value, lang) ?? "")},`)
118
+ .join("\n");
119
+ const objectTypeConst = `export const GeneratedObjectTypes = {\n${renderRecord(objectTypeEntries)}\n} as const;`;
120
+ const objectTypeDescConst = `export const GeneratedObjectTypeDescriptions: Record<keyof typeof GeneratedObjectTypes, string> = {\n${renderDescriptions(objectTypeEntries)}\n};`;
121
+ const attributeConst = `export const GeneratedAttributes = {\n${renderRecord(attributeEntries)}\n} as const;`;
122
+ const attributeDescConst = `export const GeneratedAttributeDescriptions: Record<keyof typeof GeneratedAttributes, string> = {\n${renderDescriptions(attributeEntries)}\n};`;
123
+ const renderAttributesByType = () => {
124
+ const blocks = [];
125
+ for (const [objectType, attrs] of Object.entries(attributesByType)) {
126
+ if (!attrs.length)
127
+ continue;
128
+ const lines = attrs
129
+ .map((attr) => {
130
+ const desc = resolveDescription(dictionary.attributes?.[attr], lang);
131
+ const doc = renderDoc(desc, " ");
132
+ return `${doc} "${attr}": "${attr}",`;
133
+ })
134
+ .join("\n");
135
+ blocks.push(` "${objectType}": {\n${lines}\n },`);
136
+ }
137
+ return blocks.join("\n");
138
+ };
139
+ const attributesByTypeConst = `const GeneratedAttributesByTypeBase = {\n${renderAttributesByType()}\n} as const;\n\nexport const GeneratedAttributesByType = GeneratedAttributesByTypeBase;`;
140
+ return `/* Auto-generated by generate-uns-dictionary.ts. Do not edit by hand. */\n${objectTypeConst}\n\n${objectTypeDescConst}\n\nexport type GeneratedObjectTypeName = keyof typeof GeneratedObjectTypes;\n\nexport function getGeneratedObjectTypeDescription(name: string): string | undefined {\n return (GeneratedObjectTypeDescriptions as Record<string, string | undefined>)[name];\n}\n\n${attributeConst}\n\n${attributeDescConst}\n\n${attributesByTypeConst}\n\nexport type GeneratedAttributeName = keyof typeof GeneratedAttributes;\n\nexport type GeneratedAttributesFor<T extends keyof typeof GeneratedAttributesByType> = keyof typeof GeneratedAttributesByType[T];\n\nexport function getGeneratedAttributeDescription(name: string): string | undefined {\n return (GeneratedAttributeDescriptions as Record<string, string | undefined>)[name];\n}\n`;
141
+ }
142
+ async function writeDictionaryTs(dictionary, filePath, lang) {
143
+ const content = renderDictionaryTs(dictionary, lang);
144
+ return writeTextFileIfChanged(filePath, content);
145
+ }
146
+ const isDirectExecution = process.argv[1]
147
+ ? import.meta.url === pathToFileURL(path.resolve(process.argv[1])).href
148
+ : false;
149
+ if (isDirectExecution) {
150
+ main().catch((error) => {
151
+ console.error("Failed to generate UNS dictionary:", error);
152
+ process.exitCode = 1;
153
+ });
154
+ }
155
155
  //# sourceMappingURL=generate-uns-dictionary.js.map
@@ -1,22 +1,22 @@
1
- #!/usr/bin/env node
2
- type Entry = {
3
- value: string;
4
- description?: string | null;
5
- descriptions?: Record<string, string | null | undefined>;
6
- [key: string]: unknown;
7
- };
8
- type MeasurementsJson = {
9
- schemaVersion?: unknown;
10
- physical?: Record<string, Entry>;
11
- dataSize?: Record<string, Entry>;
12
- counter?: Record<string, Entry>;
13
- [category: string]: unknown;
14
- };
15
- export declare function renderMeasurementsTs(json: MeasurementsJson, lang: string): string;
16
- export declare function generateUnsMeasurements(args: Partial<{
17
- input: string;
18
- output: string;
19
- lang: string;
20
- }>): Promise<void>;
21
- export {};
1
+ #!/usr/bin/env node
2
+ type Entry = {
3
+ value: string;
4
+ description?: string | null;
5
+ descriptions?: Record<string, string | null | undefined>;
6
+ [key: string]: unknown;
7
+ };
8
+ type MeasurementsJson = {
9
+ schemaVersion?: unknown;
10
+ physical?: Record<string, Entry>;
11
+ dataSize?: Record<string, Entry>;
12
+ counter?: Record<string, Entry>;
13
+ [category: string]: unknown;
14
+ };
15
+ export declare function renderMeasurementsTs(json: MeasurementsJson, lang: string): string;
16
+ export declare function generateUnsMeasurements(args: Partial<{
17
+ input: string;
18
+ output: string;
19
+ lang: string;
20
+ }>): Promise<void>;
21
+ export {};
22
22
  //# sourceMappingURL=generate-uns-measurements.d.ts.map
@@ -1,127 +1,127 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Generate a TypeScript helper for measurements from a JSON file.
4
- *
5
- * JSON shape (example):
6
- * {
7
- * "physical": {
8
- * "None": { "value": "", "description": "Brez enote" },
9
- * "Celsius": { "value": "°C", "description": "Stopinje Celzija" }
10
- * },
11
- * "dataSize": {
12
- * "Bit": { "value": "bit", "description": "Bit" }
13
- * },
14
- * "counter": {
15
- * "Kilo": { "value": "k", "description": "Kilo" }
16
- * }
17
- * }
18
- */
19
- import { readFile } from "node:fs/promises";
20
- import path from "node:path";
21
- import { pathToFileURL } from "node:url";
22
- import { writeTextFileIfChanged } from "./file-utils.js";
23
- const DEFAULT_INPUT = "uns-measurements.json";
24
- const DEFAULT_OUTPUT = path.resolve(process.cwd(), "src/uns/uns-measurements.generated.ts");
25
- async function main() {
26
- const { input, output, lang } = parseArgs(process.argv.slice(2));
27
- await generateUnsMeasurements({ input, output, lang });
28
- }
29
- function parseArgs(argv) {
30
- let input = DEFAULT_INPUT;
31
- let output = DEFAULT_OUTPUT;
32
- let lang = "sl";
33
- for (let i = 0; i < argv.length; i++) {
34
- const arg = argv[i];
35
- if (arg === "--input" && argv[i + 1]) {
36
- input = argv[++i];
37
- continue;
38
- }
39
- if (arg === "--output" && argv[i + 1]) {
40
- output = argv[++i];
41
- continue;
42
- }
43
- if (arg === "--lang" && argv[i + 1]) {
44
- lang = argv[++i];
45
- continue;
46
- }
47
- if (arg === "--help" || arg === "-h") {
48
- printHelp();
49
- process.exit(0);
50
- }
51
- throw new Error(`Unknown argument: ${arg}`);
52
- }
53
- return { input, output, lang };
54
- }
55
- function printHelp() {
56
- console.log(`Usage: tsx packages/uns-core/src/tools/generate-uns-measurements.ts [options]
57
-
58
- Options:
59
- --input <file> Path to uns-measurements.json (default: ${DEFAULT_INPUT})
60
- --output <file> Path to generated TS file (default: src/uns/uns-measurements.generated.ts)
61
- --lang <code> Preferred description language (default: "sl")
62
- --help, -h Show this help
63
- `);
64
- }
65
- async function loadJson(filePath) {
66
- const abs = path.resolve(process.cwd(), filePath);
67
- const raw = await readFile(abs, "utf8");
68
- return JSON.parse(raw);
69
- }
70
- const resolveDesc = (entry, lang) => {
71
- if (!entry)
72
- return undefined;
73
- const byLang = entry.descriptions?.[lang];
74
- if (byLang && byLang.length > 0)
75
- return byLang;
76
- if (entry.description && entry.description.length > 0)
77
- return entry.description;
78
- return undefined;
79
- };
80
- function renderSection(name, entries, lang) {
81
- if (!entries)
82
- return `export const ${name} = {} as const;`;
83
- const lines = Object.entries(entries)
84
- .sort(([left], [right]) => left.localeCompare(right))
85
- .map(([key, entry]) => {
86
- const desc = resolveDesc(entry, lang);
87
- const doc = renderDoc(desc, " ");
88
- return `${doc} "${key}": "${entry.value}",`;
89
- })
90
- .join("\n");
91
- return `export const ${name} = {\n${lines}\n} as const;`;
92
- }
93
- function renderDoc(description, indent) {
94
- if (!description)
95
- return "";
96
- const normalized = description
97
- .replaceAll("*/", "*\\/")
98
- .split(/\r?\n/)
99
- .map((line) => `${indent} * ${line}`)
100
- .join("\n");
101
- return `${indent}/**\n${normalized}\n${indent} */\n`;
102
- }
103
- export function renderMeasurementsTs(json, lang) {
104
- const physical = renderSection("GeneratedPhysicalMeasurements", json.physical, lang);
105
- const dataSize = renderSection("GeneratedDataSizeMeasurements", json.dataSize, lang);
106
- const counter = renderSection("GeneratedCounterMeasurements", json.counter, lang);
107
- return `/* Auto-generated by generate-uns-measurements.ts. Do not edit by hand. */\n${physical}\n\n${dataSize}\n\n${counter}\n\nexport type GeneratedPhysicalMeasurement = typeof GeneratedPhysicalMeasurements[keyof typeof GeneratedPhysicalMeasurements];\nexport type GeneratedDataSizeMeasurement = typeof GeneratedDataSizeMeasurements[keyof typeof GeneratedDataSizeMeasurements];\nexport type GeneratedCounterMeasurement = typeof GeneratedCounterMeasurements[keyof typeof GeneratedCounterMeasurements];\nexport type GeneratedMeasurementUnit = GeneratedPhysicalMeasurement | GeneratedDataSizeMeasurement | GeneratedCounterMeasurement | (string & {});\n`;
108
- }
109
- export async function generateUnsMeasurements(args) {
110
- const input = args.input ?? DEFAULT_INPUT;
111
- const output = args.output ?? DEFAULT_OUTPUT;
112
- const lang = args.lang ?? "sl";
113
- const json = await loadJson(input);
114
- const content = renderMeasurementsTs(json, lang);
115
- const changed = await writeTextFileIfChanged(output, content);
116
- console.log(`Generated measurements -> ${output}${changed ? "" : " (unchanged)"}`);
117
- }
118
- const isDirectExecution = process.argv[1]
119
- ? import.meta.url === pathToFileURL(path.resolve(process.argv[1])).href
120
- : false;
121
- if (isDirectExecution) {
122
- main().catch((err) => {
123
- console.error("Failed to generate measurements:", err);
124
- process.exitCode = 1;
125
- });
126
- }
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Generate a TypeScript helper for measurements from a JSON file.
4
+ *
5
+ * JSON shape (example):
6
+ * {
7
+ * "physical": {
8
+ * "None": { "value": "", "description": "Brez enote" },
9
+ * "Celsius": { "value": "°C", "description": "Stopinje Celzija" }
10
+ * },
11
+ * "dataSize": {
12
+ * "Bit": { "value": "bit", "description": "Bit" }
13
+ * },
14
+ * "counter": {
15
+ * "Kilo": { "value": "k", "description": "Kilo" }
16
+ * }
17
+ * }
18
+ */
19
+ import { readFile } from "node:fs/promises";
20
+ import path from "node:path";
21
+ import { pathToFileURL } from "node:url";
22
+ import { writeTextFileIfChanged } from "./file-utils.js";
23
+ const DEFAULT_INPUT = "uns-measurements.json";
24
+ const DEFAULT_OUTPUT = path.resolve(process.cwd(), "src/uns/uns-measurements.generated.ts");
25
+ async function main() {
26
+ const { input, output, lang } = parseArgs(process.argv.slice(2));
27
+ await generateUnsMeasurements({ input, output, lang });
28
+ }
29
+ function parseArgs(argv) {
30
+ let input = DEFAULT_INPUT;
31
+ let output = DEFAULT_OUTPUT;
32
+ let lang = "sl";
33
+ for (let i = 0; i < argv.length; i++) {
34
+ const arg = argv[i];
35
+ if (arg === "--input" && argv[i + 1]) {
36
+ input = argv[++i];
37
+ continue;
38
+ }
39
+ if (arg === "--output" && argv[i + 1]) {
40
+ output = argv[++i];
41
+ continue;
42
+ }
43
+ if (arg === "--lang" && argv[i + 1]) {
44
+ lang = argv[++i];
45
+ continue;
46
+ }
47
+ if (arg === "--help" || arg === "-h") {
48
+ printHelp();
49
+ process.exit(0);
50
+ }
51
+ throw new Error(`Unknown argument: ${arg}`);
52
+ }
53
+ return { input, output, lang };
54
+ }
55
+ function printHelp() {
56
+ console.log(`Usage: tsx packages/uns-core/src/tools/generate-uns-measurements.ts [options]
57
+
58
+ Options:
59
+ --input <file> Path to uns-measurements.json (default: ${DEFAULT_INPUT})
60
+ --output <file> Path to generated TS file (default: src/uns/uns-measurements.generated.ts)
61
+ --lang <code> Preferred description language (default: "sl")
62
+ --help, -h Show this help
63
+ `);
64
+ }
65
+ async function loadJson(filePath) {
66
+ const abs = path.resolve(process.cwd(), filePath);
67
+ const raw = await readFile(abs, "utf8");
68
+ return JSON.parse(raw);
69
+ }
70
+ const resolveDesc = (entry, lang) => {
71
+ if (!entry)
72
+ return undefined;
73
+ const byLang = entry.descriptions?.[lang];
74
+ if (byLang && byLang.length > 0)
75
+ return byLang;
76
+ if (entry.description && entry.description.length > 0)
77
+ return entry.description;
78
+ return undefined;
79
+ };
80
+ function renderSection(name, entries, lang) {
81
+ if (!entries)
82
+ return `export const ${name} = {} as const;`;
83
+ const lines = Object.entries(entries)
84
+ .sort(([left], [right]) => left.localeCompare(right))
85
+ .map(([key, entry]) => {
86
+ const desc = resolveDesc(entry, lang);
87
+ const doc = renderDoc(desc, " ");
88
+ return `${doc} "${key}": "${entry.value}",`;
89
+ })
90
+ .join("\n");
91
+ return `export const ${name} = {\n${lines}\n} as const;`;
92
+ }
93
+ function renderDoc(description, indent) {
94
+ if (!description)
95
+ return "";
96
+ const normalized = description
97
+ .replaceAll("*/", "*\\/")
98
+ .split(/\r?\n/)
99
+ .map((line) => `${indent} * ${line}`)
100
+ .join("\n");
101
+ return `${indent}/**\n${normalized}\n${indent} */\n`;
102
+ }
103
+ export function renderMeasurementsTs(json, lang) {
104
+ const physical = renderSection("GeneratedPhysicalMeasurements", json.physical, lang);
105
+ const dataSize = renderSection("GeneratedDataSizeMeasurements", json.dataSize, lang);
106
+ const counter = renderSection("GeneratedCounterMeasurements", json.counter, lang);
107
+ return `/* Auto-generated by generate-uns-measurements.ts. Do not edit by hand. */\n${physical}\n\n${dataSize}\n\n${counter}\n\nexport type GeneratedPhysicalMeasurement = typeof GeneratedPhysicalMeasurements[keyof typeof GeneratedPhysicalMeasurements];\nexport type GeneratedDataSizeMeasurement = typeof GeneratedDataSizeMeasurements[keyof typeof GeneratedDataSizeMeasurements];\nexport type GeneratedCounterMeasurement = typeof GeneratedCounterMeasurements[keyof typeof GeneratedCounterMeasurements];\nexport type GeneratedMeasurementUnit = GeneratedPhysicalMeasurement | GeneratedDataSizeMeasurement | GeneratedCounterMeasurement | (string & {});\n`;
108
+ }
109
+ export async function generateUnsMeasurements(args) {
110
+ const input = args.input ?? DEFAULT_INPUT;
111
+ const output = args.output ?? DEFAULT_OUTPUT;
112
+ const lang = args.lang ?? "sl";
113
+ const json = await loadJson(input);
114
+ const content = renderMeasurementsTs(json, lang);
115
+ const changed = await writeTextFileIfChanged(output, content);
116
+ console.log(`Generated measurements -> ${output}${changed ? "" : " (unchanged)"}`);
117
+ }
118
+ const isDirectExecution = process.argv[1]
119
+ ? import.meta.url === pathToFileURL(path.resolve(process.argv[1])).href
120
+ : false;
121
+ if (isDirectExecution) {
122
+ main().catch((err) => {
123
+ console.error("Failed to generate measurements:", err);
124
+ process.exitCode = 1;
125
+ });
126
+ }
127
127
  //# sourceMappingURL=generate-uns-measurements.js.map
@@ -1,3 +1,3 @@
1
- #!/usr/bin/env node
2
- export {};
1
+ #!/usr/bin/env node
2
+ export {};
3
3
  //# sourceMappingURL=generate-uns-reference.d.ts.map